From 21b34476339f27078a5b5cf3d77fe79cb7baf600 Mon Sep 17 00:00:00 2001 From: Jersey Date: Thu, 13 Mar 2025 18:22:44 -0400 Subject: [PATCH 1/9] BREAKING CHANGE: remove CJS build, polyfills, dependencies This commit changes revolt.js so that there is no longer a CJS build. CJS users of revolt.js can still import it using versions of Node.js after nodejs/node#51977 was merged. The dependencies on the isomorphic-ws and ws packages were also removed. This does make the minimum supported version the latest LTS, Node.js 22. In browsers and Deno, nothing should change. The dependencies on Solid.js were also removed, making a breaking change for users who used the reactivity from the Solid.js wrappers. Import paths throughout the project were rewritten to import from the original source files everywhere. Prettier, ESLint, and Typescript were all updated to their latest versions as well. Signed-off-by: Jersey --- .eslintrc.json | 49 - .github/workflows/codeql-analysis.yml | 58 +- .prettierrc | 7 +- README.md | 40 +- eslint.config.js | 21 + package-esm.json | 3 - package.json | 46 +- pnpm-lock.yaml | 3031 +++++++------------ src/Client.ts | 150 +- src/classes/BannedUser.ts | 8 +- src/classes/Bot.ts | 2 +- src/classes/Channel.ts | 137 +- src/classes/ChannelUnread.ts | 2 +- src/classes/ChannelWebhook.ts | 12 +- src/classes/Emoji.ts | 4 +- src/classes/File.ts | 6 +- src/classes/Invite.ts | 12 +- src/classes/MFA.ts | 31 +- src/classes/Message.ts | 36 +- src/classes/MessageEmbed.ts | 35 +- src/classes/PublicBot.ts | 16 +- src/classes/PublicInvite.ts | 34 +- src/classes/Server.ts | 171 +- src/classes/ServerBan.ts | 12 +- src/classes/ServerMember.ts | 6 +- src/classes/Session.ts | 4 +- src/classes/SystemMessage.ts | 32 +- src/classes/User.ts | 36 +- src/classes/UserProfile.ts | 8 +- src/collections/AccountCollection.ts | 4 +- src/collections/BotCollection.ts | 19 +- src/collections/ChannelCollection.ts | 13 +- src/collections/ChannelUnreadCollection.ts | 23 +- src/collections/ChannelWebhookCollection.ts | 11 +- src/collections/Collection.ts | 27 +- src/collections/EmojiCollection.ts | 12 +- src/collections/MessageCollection.ts | 14 +- src/collections/ServerCollection.ts | 38 +- src/collections/ServerMemberCollection.ts | 24 +- src/collections/SessionCollection.ts | 13 +- src/collections/UserCollection.ts | 11 +- src/events/EventClient.ts | 67 +- src/events/index.ts | 22 - src/events/v1.ts | 210 +- src/hydration/bot.ts | 4 +- src/hydration/channel.ts | 22 +- src/hydration/channelUnread.ts | 11 +- src/hydration/channelWebhook.ts | 7 +- src/hydration/emoji.ts | 4 +- src/hydration/index.ts | 26 +- src/hydration/message.ts | 30 +- src/hydration/server.ts | 28 +- src/hydration/serverMember.ts | 7 +- src/hydration/session.ts | 4 +- src/hydration/user.ts | 7 +- src/index.ts | 12 +- src/lib/merge.ts | 5 +- src/permissions/calculator.ts | 41 +- src/storage/ObjectStorage.ts | 24 +- test.js | 12 - test.mjs | 6 +- tsconfig.cjs.json | 10 - tsconfig.json | 2 +- 63 files changed, 1837 insertions(+), 2942 deletions(-) delete mode 100644 .eslintrc.json create mode 100644 eslint.config.js delete mode 100644 package-esm.json delete mode 100644 src/events/index.ts delete mode 100644 test.js mode change 100644 => 100755 test.mjs delete mode 100644 tsconfig.cjs.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 589d74e4..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": ["solid", "spellcheck"], - "extends": [ - "eslint:recommended", - "plugin:solid/typescript", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "rules": { - "@typescript-eslint/no-non-null-assertion": "off", - "spellcheck/spell-checker": [ - "warn", - { - "lang": "en_GB", - "strings": false, - "identifiers": false, - "templates": false, - "skipWords": ["uri", "webhook", "webhooks", "unreads"], - "minLength": 3 - } - ], - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "varsIgnorePattern": "^_" - } - ], - "no-unused-vars": [ - "warn", - { - "varsIgnorePattern": "^_" - } - ], - "require-jsdoc": [ - "warn", - { - "require": { - "FunctionDeclaration": true, - "MethodDefinition": true, - "ClassDeclaration": true, - "ArrowFunctionExpression": true, - "FunctionExpression": true - } - } - ] - } -} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dbda93fe..33632a3f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ main ] + branches: [main] pull_request: # The branches below must be a subset of the branches above - branches: [ main ] + branches: [main] schedule: - - cron: '40 21 * * 6' + - cron: "40 21 * * 6" jobs: analyze: @@ -32,40 +32,40 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ["javascript"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed steps: - - name: Checkout repository - uses: actions/checkout@v2 + - name: Checkout repository + uses: actions/checkout@v2 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl + # â„šī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language + # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language - #- run: | - # make bootstrap - # make release + #- run: | + # make bootstrap + # make release - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.prettierrc b/.prettierrc index e9cf7027..fc1b2b28 100644 --- a/.prettierrc +++ b/.prettierrc @@ -2,12 +2,7 @@ "tabWidth": 2, "useTabs": false, "plugins": ["@trivago/prettier-plugin-sort-imports"], - "importOrder": [ - "^solid", - "", - "^\\.\\.", - "^[./]" - ], + "importOrder": ["", "^\\.\\.", "^[./]"], "importOrderSeparation": true, "importOrderSortSpecifiers": true } diff --git a/README.md b/README.md index f261cca4..72863ef1 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # revolt.js -![revolt.js](https://img.shields.io/npm/v/revolt.js) ![revolt-api](https://img.shields.io/npm/v/revolt-api?label=Revolt%20API) +![revolt.js](https://img.shields.io/npm/v/revolt.js) +![revolt-api](https://img.shields.io/npm/v/revolt-api?label=Revolt%20API) -**revolt.js** is a JavaScript library for interacting with the entire Revolt API. +**revolt.js** is a JavaScript library for interacting with the entire Revolt +API. ## Example Usage @@ -14,8 +16,9 @@ const { Client } = require("revolt.js"); let client = new Client(); -client.on("ready", async () => - console.info(`Logged in as ${client.user.username}!`) +client.on( + "ready", + async () => console.info(`Logged in as ${client.user.username}!`), ); client.on("messageCreate", async (message) => { @@ -26,32 +29,3 @@ client.on("messageCreate", async (message) => { client.loginBot(".."); ``` - -## Reactivity with Signals & Solid.js Primitives - -All objects have reactivity built-in and can be dropped straight into any Solid.js project. - -```tsx -const client = new Client(); -// initialise the client - -function MyApp() { - return ( -

Your username is: {client.user?.username ?? "[logging in...]"}

- ); -} -``` - -## Revolt API Types - -> [!WARNING] -> It is advised you do not use this unless necessary. If you find somewhere that isn't covered by the library, please open an issue as this library aims to transform all objects. - -All `revolt-api` types are re-exported from this library under `API`. - -```typescript -import { API } from "revolt.js"; - -// API.Channel; -// API.[..]; -``` diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..f82ab7dc --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,21 @@ +import eslint from "@eslint/js"; +import prettier from "eslint-plugin-prettier/recommended"; +import { defineConfig } from "eslint/config"; +import tseslint from "typescript-eslint"; + +export default defineConfig([ + eslint.configs.recommended, + tseslint.configs.recommended, + { + rules: { + "@typescript-eslint/no-unused-vars": [ + "warn", + { + caughtErrors: "all", + varsIgnorePattern: "^_", + }, + ], + }, + }, + prettier, +]); diff --git a/package-esm.json b/package-esm.json deleted file mode 100644 index 3dbc1ca5..00000000 --- a/package-esm.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "type": "module" -} diff --git a/package.json b/package.json index 1bb75f60..08a3f9cc 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,14 @@ { "name": "revolt.js", "version": "7.0.5", - "main": "lib/cjs/index.js", - "module": "lib/esm/index.js", - "types": "lib/esm/index.d.ts", + "type": "module", + "module": "lib/index.js", + "types": "lib/index.d.ts", "repository": "https://github.com/revoltchat/revolt.js", "author": "Paul Makles ", "license": "MIT", "scripts": { - "build": "pnpm run build:esm && pnpm run build:cjs", - "build:esm": "tsc && cp package-esm.json lib/esm/package.json", - "build:cjs": "tsc -p tsconfig.cjs.json", - "build:watch": "tsc-watch --onSuccess \"node .\"", + "build": "tsc", "lint": "eslint --ext .ts,.tsx src/", "lint:fix": "eslint --fix --ext .ts,.tsx src/", "typecheck": "tsc --noEmit", @@ -26,32 +23,19 @@ "description": "Library for interacting with the Revolt API.", "packageManager": "pnpm@9.4.0", "dependencies": { - "@solid-primitives/map": "^0.4.11", - "@solid-primitives/set": "^0.4.11", "eventemitter3": "^5.0.1", - "isomorphic-ws": "^5.0.0", - "long": "^5.2.3", "revolt-api": "0.8.3", - "solid-js": "^1.8.15", - "ulid": "^2.3.0", - "ws": "^8.16.0" + "ulid": "^2.3.0" }, "devDependencies": { - "@mxssfd/typedoc-theme": "^1.1.3", - "@trivago/prettier-plugin-sort-imports": "^4.3.0", - "@types/node": "^18.19.24", - "@types/ws": "^8.5.10", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", - "dotenv": "^16.4.5", - "eslint": "^8.57.0", - "eslint-config-prettier": "^8.10.0", - "eslint-plugin-solid": "^0.12.1", - "eslint-plugin-spellcheck": "^0.0.20", - "prettier": "^2.8.8", - "tsc-watch": "^6.0.4", - "typed-emitter": "^2.1.0", - "typedoc": "^0.25.1", - "typescript": "^5.4.2" + "@mxssfd/typedoc-theme": "^1.1.7", + "@trivago/prettier-plugin-sort-imports": "^5.2.2", + "@types/node": "^22.13.10", + "eslint-plugin-prettier": "^5.2.3", + "eslint": "^9.22.0", + "prettier": "^3.5.3", + "typedoc": "^0.27.9", + "typescript-eslint": "^8.26.1", + "typescript": "^5.8.2" } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 75d1bd43..058ede26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,735 +1,333 @@ -lockfileVersion: 5.4 - -specifiers: - '@mxssfd/typedoc-theme': ^1.1.3 - '@solid-primitives/map': ^0.4.11 - '@solid-primitives/set': ^0.4.11 - '@trivago/prettier-plugin-sort-imports': ^4.3.0 - '@types/node': ^18.19.24 - '@types/ws': ^8.5.10 - '@typescript-eslint/eslint-plugin': ^5.62.0 - '@typescript-eslint/parser': ^5.62.0 - dotenv: ^16.4.5 - eslint: ^8.57.0 - eslint-config-prettier: ^8.10.0 - eslint-plugin-solid: ^0.12.1 - eslint-plugin-spellcheck: ^0.0.20 - eventemitter3: ^5.0.1 - isomorphic-ws: ^5.0.0 - long: ^5.2.3 - prettier: ^2.8.8 - revolt-api: 0.8.3 - solid-js: ^1.8.15 - tsc-watch: ^6.0.4 - typed-emitter: ^2.1.0 - typedoc: ^0.25.1 - typescript: ^5.4.2 - ulid: ^2.3.0 - ws: ^8.16.0 - -dependencies: - '@solid-primitives/map': 0.4.13_solid-js@1.9.3 - '@solid-primitives/set': 0.4.12_solid-js@1.9.3 - eventemitter3: 5.0.1 - isomorphic-ws: 5.0.0_ws@8.18.0 - long: 5.2.3 - revolt-api: 0.8.3 - solid-js: 1.9.3 - ulid: 2.3.0 - ws: 8.18.0 - -devDependencies: - '@mxssfd/typedoc-theme': 1.1.7_typedoc@0.25.13 - '@trivago/prettier-plugin-sort-imports': 4.3.0_prettier@2.8.8 - '@types/node': 18.19.68 - '@types/ws': 8.5.13 - '@typescript-eslint/eslint-plugin': 5.62.0_kt2ucnmydjm4ow45rl6p5s7bna - '@typescript-eslint/parser': 5.62.0_6txzh3afdjfsavlpa2fczfkiua - dotenv: 16.4.7 - eslint: 8.57.1 - eslint-config-prettier: 8.10.0_eslint@8.57.1 - eslint-plugin-solid: 0.12.1_6txzh3afdjfsavlpa2fczfkiua - eslint-plugin-spellcheck: 0.0.20_eslint@8.57.1 - prettier: 2.8.8 - tsc-watch: 6.2.1_typescript@5.7.2 - typed-emitter: 2.1.0 - typedoc: 0.25.13_typescript@5.7.2 - typescript: 5.7.2 +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + eventemitter3: + specifier: ^5.0.1 + version: 5.0.1 + revolt-api: + specifier: 0.8.3 + version: 0.8.3 + ulid: + specifier: ^2.3.0 + version: 2.3.0 + devDependencies: + '@mxssfd/typedoc-theme': + specifier: ^1.1.7 + version: 1.1.7(typedoc@0.27.9(typescript@5.8.2)) + '@trivago/prettier-plugin-sort-imports': + specifier: ^5.2.2 + version: 5.2.2(prettier@3.5.3) + '@types/node': + specifier: ^22.13.10 + version: 22.13.10 + eslint: + specifier: ^9.22.0 + version: 9.22.0 + eslint-plugin-prettier: + specifier: ^5.2.3 + version: 5.2.3(eslint-config-prettier@8.10.0(eslint@9.22.0))(eslint@9.22.0)(prettier@3.5.3) + prettier: + specifier: ^3.5.3 + version: 3.5.3 + typedoc: + specifier: ^0.27.9 + version: 0.27.9(typescript@5.8.2) + typescript: + specifier: ^5.8.2 + version: 5.8.2 + typescript-eslint: + specifier: ^8.26.1 + version: 8.26.1(eslint@9.22.0)(typescript@5.8.2) packages: - /@babel/code-frame/7.26.2: + '@babel/code-frame@7.26.2': resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.25.9 - js-tokens: 4.0.0 - picocolors: 1.1.1 - dev: true - - /@babel/generator/7.17.7: - resolution: {integrity: sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.17.0 - jsesc: 2.5.2 - source-map: 0.5.7 - dev: true - - /@babel/generator/7.26.3: - resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.1.0 - dev: true - - /@babel/helper-environment-visitor/7.24.7: - resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.26.3 - dev: true - - /@babel/helper-function-name/7.24.7: - resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.25.9 - '@babel/types': 7.26.3 - dev: true - /@babel/helper-hoist-variables/7.24.7: - resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + '@babel/generator@7.26.10': + resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.26.3 - dev: true - - /@babel/helper-split-export-declaration/7.24.7: - resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.26.3 - dev: true - /@babel/helper-string-parser/7.25.9: + '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} - dev: true - /@babel/helper-validator-identifier/7.25.9: + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - dev: true - /@babel/parser/7.26.3: - resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} + '@babel/parser@7.26.10': + resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} engines: {node: '>=6.0.0'} hasBin: true - dependencies: - '@babel/types': 7.26.3 - dev: true - - /@babel/template/7.25.9: - resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 - dev: true - /@babel/traverse/7.23.2: - resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} + '@babel/template@7.26.9': + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.3 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-function-name': 7.24.7 - '@babel/helper-hoist-variables': 7.24.7 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 - debug: 4.4.0 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/types/7.17.0: - resolution: {integrity: sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==} + '@babel/traverse@7.26.10': + resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.25.9 - to-fast-properties: 2.0.0 - dev: true - /@babel/types/7.26.3: - resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} + '@babel/types@7.26.10': + resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - dev: true - /@eslint-community/eslint-utils/4.4.1_eslint@8.57.1: - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + '@eslint-community/eslint-utils@4.5.1': + resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 - dev: true - /@eslint-community/regexpp/4.12.1: + '@eslint-community/regexpp@4.12.1': resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true - /@eslint/eslintrc/2.1.4: - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.4.0 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true + '@eslint/config-array@0.19.2': + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /@eslint/js/8.57.1: - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + '@eslint/config-helpers@0.1.0': + resolution: {integrity: sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /@humanwhocodes/config-array/0.13.0: - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead - dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.0 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true + '@eslint/core@0.12.0': + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.0': + resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.22.0': + resolution: {integrity: sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.7': + resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@gerrit0/mini-shiki@1.27.2': + resolution: {integrity: sha512-GeWyHz8ao2gBiUW4OJnQDxXQnFgZQwwQk05t/CVVgNBN7/rK8XZ7xY6YhLVv9tH3VppWWmr9DCl3MwemB/i+Og==} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} - /@humanwhocodes/module-importer/1.0.1: + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - dev: true - /@humanwhocodes/object-schema/2.0.3: - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead - dev: true + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} - /@jridgewell/gen-mapping/0.3.8: + '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - dev: true - /@jridgewell/resolve-uri/3.1.2: + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - dev: true - /@jridgewell/set-array/1.2.1: + '@jridgewell/set-array@1.2.1': resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - dev: true - /@jridgewell/sourcemap-codec/1.5.0: + '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - dev: true - /@jridgewell/trace-mapping/0.3.25: + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - dev: true - /@mxssfd/typedoc-theme/1.1.7_typedoc@0.25.13: + '@mxssfd/typedoc-theme@1.1.7': resolution: {integrity: sha512-dj4p0TjIoudD8j1u+Kf+KzcEc+je3IB/B1oohWcVJmMRfbw5uZYX6qOGHzfUzAPiU1pYe2u5Vo1IPqgLo58taA==} engines: {node: '>= 14'} peerDependencies: typedoc: ^0.26.7 - dependencies: - typedoc: 0.25.13_typescript@5.7.2 - dev: true - /@nodelib/fs.scandir/2.1.5: + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat/2.0.5: + '@nodelib/fs.stat@2.0.5': resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} - dev: true - /@nodelib/fs.walk/1.2.8: + '@nodelib/fs.walk@1.2.8': resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - dev: true - /@solid-primitives/map/0.4.13_solid-js@1.9.3: - resolution: {integrity: sha512-B1zyFbsiTQvqPr+cuPCXO72sRuczG9Swncqk5P74NCGw1VE8qa/Ry9GlfI1e/VdeQYHjan+XkbE3rO2GW/qKew==} - peerDependencies: - solid-js: ^1.6.12 - dependencies: - '@solid-primitives/trigger': 1.1.0_solid-js@1.9.3 - solid-js: 1.9.3 - dev: false + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - /@solid-primitives/set/0.4.12_solid-js@1.9.3: - resolution: {integrity: sha512-p0CTabELYGK0oHDpET0f0p9CZtOqPocPDlZxL5MFSke0ewUByNVfNssK6aOECwvvYWL/rinFOUneOC/KLAXmwA==} - peerDependencies: - solid-js: ^1.6.12 - dependencies: - '@solid-primitives/trigger': 1.1.0_solid-js@1.9.3 - solid-js: 1.9.3 - dev: false + '@shikijs/engine-oniguruma@1.29.2': + resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} - /@solid-primitives/trigger/1.1.0_solid-js@1.9.3: - resolution: {integrity: sha512-00BbAiXV66WwjHuKZc3wr0+GLb9C24mMUmi3JdTpNFgHBbrQGrIHubmZDg36c5/7wH+E0GQtOOanwQS063PO+A==} - peerDependencies: - solid-js: ^1.6.12 - dependencies: - '@solid-primitives/utils': 6.2.3_solid-js@1.9.3 - solid-js: 1.9.3 - dev: false + '@shikijs/types@1.29.2': + resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} - /@solid-primitives/utils/6.2.3_solid-js@1.9.3: - resolution: {integrity: sha512-CqAwKb2T5Vi72+rhebSsqNZ9o67buYRdEJrIFzRXz3U59QqezuuxPsyzTSVCacwS5Pf109VRsgCJQoxKRoECZQ==} - peerDependencies: - solid-js: ^1.6.12 - dependencies: - solid-js: 1.9.3 - dev: false + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - /@trivago/prettier-plugin-sort-imports/4.3.0_prettier@2.8.8: - resolution: {integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==} + '@trivago/prettier-plugin-sort-imports@5.2.2': + resolution: {integrity: sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==} + engines: {node: '>18.12'} peerDependencies: '@vue/compiler-sfc': 3.x prettier: 2.x - 3.x + prettier-plugin-svelte: 3.x + svelte: 4.x || 5.x peerDependenciesMeta: '@vue/compiler-sfc': optional: true - dependencies: - '@babel/generator': 7.17.7 - '@babel/parser': 7.26.3 - '@babel/traverse': 7.23.2 - '@babel/types': 7.17.0 - javascript-natural-sort: 0.7.1 - lodash: 4.17.21 - prettier: 2.8.8 - transitivePeerDependencies: - - supports-color - dev: true + prettier-plugin-svelte: + optional: true + svelte: + optional: true - /@types/json-schema/7.0.15: - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - dev: true + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - /@types/node/18.19.68: - resolution: {integrity: sha512-QGtpFH1vB99ZmTa63K4/FU8twThj4fuVSBkGddTp7uIL/cuoLWIUSL2RcOaigBhfR+hg5pgGkBnkoOxrTVBMKw==} - dependencies: - undici-types: 5.26.5 - dev: true + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - /@types/semver/7.5.8: - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - dev: true + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - /@types/ws/8.5.13: - resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} - dependencies: - '@types/node': 18.19.68 - dev: true + '@types/node@22.13.10': + resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} - /@typescript-eslint/eslint-plugin/5.62.0_kt2ucnmydjm4ow45rl6p5s7bna: - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@typescript-eslint/eslint-plugin@8.26.1': + resolution: {integrity: sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 5.62.0_6txzh3afdjfsavlpa2fczfkiua - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0_6txzh3afdjfsavlpa2fczfkiua - '@typescript-eslint/utils': 5.62.0_6txzh3afdjfsavlpa2fczfkiua - debug: 4.4.0 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare-lite: 1.4.0 - semver: 7.6.3 - tsutils: 3.21.0_typescript@5.7.2 - typescript: 5.7.2 - transitivePeerDependencies: - - supports-color - dev: true + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' - /@typescript-eslint/parser/5.62.0_6txzh3afdjfsavlpa2fczfkiua: - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/parser@8.26.1': + resolution: {integrity: sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0_typescript@5.7.2 - debug: 4.4.0 - eslint: 8.57.1 - typescript: 5.7.2 - transitivePeerDependencies: - - supports-color - dev: true + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' - /@typescript-eslint/scope-manager/5.62.0: - resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - dev: true + '@typescript-eslint/scope-manager@8.26.1': + resolution: {integrity: sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /@typescript-eslint/type-utils/5.62.0_6txzh3afdjfsavlpa2fczfkiua: - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/type-utils@8.26.1': + resolution: {integrity: sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.62.0_typescript@5.7.2 - '@typescript-eslint/utils': 5.62.0_6txzh3afdjfsavlpa2fczfkiua - debug: 4.4.0 - eslint: 8.57.1 - tsutils: 3.21.0_typescript@5.7.2 - typescript: 5.7.2 - transitivePeerDependencies: - - supports-color - dev: true + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' - /@typescript-eslint/types/5.62.0: - resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + '@typescript-eslint/types@8.26.1': + resolution: {integrity: sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /@typescript-eslint/typescript-estree/5.62.0_typescript@5.7.2: - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/typescript-estree@8.26.1': + resolution: {integrity: sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.0 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.6.3 - tsutils: 3.21.0_typescript@5.7.2 - typescript: 5.7.2 - transitivePeerDependencies: - - supports-color - dev: true + typescript: '>=4.8.4 <5.9.0' - /@typescript-eslint/utils/5.62.0_6txzh3afdjfsavlpa2fczfkiua: - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@typescript-eslint/utils@8.26.1': + resolution: {integrity: sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.1_eslint@8.57.1 - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0_typescript@5.7.2 - eslint: 8.57.1 - eslint-scope: 5.1.1 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys/5.62.0: - resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.62.0 - eslint-visitor-keys: 3.4.3 - dev: true + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' - /@ungap/structured-clone/1.2.1: - resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} - dev: true + '@typescript-eslint/visitor-keys@8.26.1': + resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /acorn-jsx/5.3.2_acorn@8.14.0: + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.14.0 - dev: true - /acorn/8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} hasBin: true - dev: true - /ajv/6.12.6: + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - dev: true - - /ansi-regex/5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - /ansi-sequence-parser/1.1.1: - resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==} - dev: true - /ansi-styles/4.3.0: + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - /argparse/2.0.1: + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - - /array-buffer-byte-length/1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - is-array-buffer: 3.0.5 - dev: true - - /array-includes/3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.7 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.6 - is-string: 1.1.1 - dev: true - - /array-union/2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - /array.prototype.flat/1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.7 - es-shim-unscopables: 1.0.2 - dev: true - - /arraybuffer.prototype.slice/1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.6 - is-array-buffer: 3.0.5 - dev: true - - /available-typed-arrays/1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - dependencies: - possible-typed-array-names: 1.0.0 - dev: true - - /axios/0.26.1: + + axios@0.26.1: resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} - dependencies: - follow-redirects: 1.15.9 - transitivePeerDependencies: - - debug - dev: false - /balanced-match/1.0.2: + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - /brace-expansion/1.1.11: + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - /brace-expansion/2.0.1: + brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - /braces/3.0.3: + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - dependencies: - fill-range: 7.1.1 - dev: true - - /call-bind-apply-helpers/1.0.1: - resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - dev: true - - /call-bind/1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - dependencies: - call-bind-apply-helpers: 1.0.1 - es-define-property: 1.0.1 - get-intrinsic: 1.2.6 - set-function-length: 1.2.2 - dev: true - - /call-bound/1.0.3: - resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind-apply-helpers: 1.0.1 - get-intrinsic: 1.2.6 - dev: true - /callsites/3.1.0: + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - dev: true - /chalk/4.1.2: + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - /color-convert/2.0.1: + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - /color-name/1.1.4: + color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - /concat-map/0.0.1: + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - /cross-spawn/7.0.6: + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - /csstype/3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - dev: false - - /data-view-buffer/1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 - dev: true - - /data-view-byte-length/1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 - dev: true - - /data-view-byte-offset/1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 - dev: true - /debug/4.4.0: + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} peerDependencies: @@ -737,389 +335,122 @@ packages: peerDependenciesMeta: supports-color: optional: true - dependencies: - ms: 2.1.3 - dev: true - /deep-is/0.1.4: + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true - - /define-data-property/1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - dev: true - - /define-properties/1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - dev: true - /dir-glob/3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} - /doctrine/3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /dotenv/16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} - engines: {node: '>=12'} - dev: true - - /dunder-proto/1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - dependencies: - call-bind-apply-helpers: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - dev: true - - /duplexer/0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - dev: true - - /es-abstract/1.23.7: - resolution: {integrity: sha512-OygGC8kIcDhXX+6yAZRGLqwi2CmEXCbLQixeGUgYeR+Qwlppqmo7DIDr8XibtEBZp+fJcoYpoatp5qwLMEdcqQ==} - engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.3 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.0.0 - es-set-tostringtag: 2.0.3 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.2.6 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-regex: 1.2.1 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.0 - math-intrinsics: 1.1.0 - object-inspect: 1.13.3 - object-keys: 1.1.1 - object.assign: 4.1.7 - regexp.prototype.flags: 1.5.3 - safe-array-concat: 1.1.3 - safe-regex-test: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.18 - dev: true - - /es-define-property/1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - dev: true - - /es-errors/1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - dev: true - - /es-object-atoms/1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - dev: true - - /es-set-tostringtag/2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.6 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - dev: true - - /es-shim-unscopables/1.0.2: - resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} - dependencies: - hasown: 2.0.2 - dev: true - - /es-to-primitive/1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - dev: true - - /escape-string-regexp/4.0.0: + escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - dev: true - /eslint-config-prettier/8.10.0_eslint@8.57.1: + eslint-config-prettier@8.10.0: resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} hasBin: true peerDependencies: eslint: '>=7.0.0' - dependencies: - eslint: 8.57.1 - dev: true - - /eslint-plugin-solid/0.12.1_6txzh3afdjfsavlpa2fczfkiua: - resolution: {integrity: sha512-fM0sEg9PcS1mcNbWklwc+W/lOv1/XyEwXf53HmFFy4GOA8E3u41h8JW+hc+Vv1m3kh01umKoTalOTET08zKdAQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@typescript-eslint/utils': 5.62.0_6txzh3afdjfsavlpa2fczfkiua - eslint: 8.57.1 - is-html: 2.0.0 - jsx-ast-utils: 3.3.5 - kebab-case: 1.0.2 - known-css-properties: 0.24.0 - style-to-object: 0.3.0 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - /eslint-plugin-spellcheck/0.0.20_eslint@8.57.1: - resolution: {integrity: sha512-GJa6vgzWAYqe0elKADAsiBRrhvqBnKyt7tpFSqlCZJsK2W9+K80oMyHhKolA7vJ13H5RCGs5/KCN+mKUyKoAiA==} + eslint-plugin-prettier@5.2.3: + resolution: {integrity: sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==} + engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - eslint: '>=0.8.0' - dependencies: - eslint: 8.57.1 - globals: 13.24.0 - hunspell-spellchecker: 1.0.2 - lodash: 4.17.21 - dev: true - - /eslint-scope/5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true - /eslint-scope/7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - dev: true + eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /eslint-visitor-keys/3.4.3: + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - /eslint/8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.22.0: + resolution: {integrity: sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.1_eslint@8.57.1 - '@eslint-community/regexpp': 4.12.1 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.1 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.0 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true - /espree/9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2_acorn@8.14.0 - eslint-visitor-keys: 3.4.3 - dev: true + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - /esquery/1.6.0: + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - dev: true - /esrecurse/4.3.0: + esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - dev: true - - /estraverse/4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - /estraverse/5.3.0: + estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} - dev: true - /esutils/2.0.3: + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - dev: true - - /event-stream/3.3.4: - resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - dependencies: - duplexer: 0.1.2 - from: 0.1.7 - map-stream: 0.1.0 - pause-stream: 0.0.11 - split: 0.3.3 - stream-combiner: 0.0.4 - through: 2.3.8 - dev: true - /eventemitter3/5.0.1: + eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - dev: false - /fast-deep-equal/3.1.3: + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true - /fast-glob/3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - dev: true - /fast-json-stable-stringify/2.1.0: + fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true - /fast-levenshtein/2.0.6: + fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true - /fastq/1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - dependencies: - reusify: 1.0.4 - dev: true + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - /file-entry-cache/6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.2.0 - dev: true + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} - /fill-range/7.1.1: + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - /find-up/5.0.0: + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - dev: true - /flat-cache/3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.3.2 - keyv: 4.5.4 - rimraf: 3.0.2 - dev: true + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} - /flatted/3.3.2: - resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} - dev: true + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - /follow-redirects/1.15.9: + follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} peerDependencies: @@ -1127,620 +458,859 @@ packages: peerDependenciesMeta: debug: optional: true - dev: false - - /for-each/0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - dev: true - - /from/0.1.7: - resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} - dev: true - - /fs.realpath/1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - /function-bind/1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - dev: true - - /function.prototype.name/1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - dev: true - - /functions-have-names/1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true - - /get-intrinsic/1.2.6: - resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind-apply-helpers: 1.0.1 - dunder-proto: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.0.0 - function-bind: 1.1.2 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - dev: true - - /get-symbol-description/1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.6 - dev: true - - /glob-parent/5.1.2: + + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - /glob-parent/6.0.2: + glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + javascript-natural-sort@0.7.1: + resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.defaultsdeep@4.6.1: + resolution: {integrity: sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + revolt-api@0.8.3: + resolution: {integrity: sha512-4dOe6sbiWFGF5PlAuYtH9vWHXdFOge/L6/EKr6oLgslN+QBn2DKfSOIhl6Ni2n0B0cBurhA1KuBy0mWfE68fIQ==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@2.0.1: + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typedoc@0.27.9: + resolution: {integrity: sha512-/z585740YHURLl9DN2jCWe6OW7zKYm6VoQ93H0sxZ1cwHQEQrUn5BJrEnkWhfzUdyO+BLGjnKUZ9iz9hKloFDw==} + engines: {node: '>= 18'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x + + typescript-eslint@8.26.1: + resolution: {integrity: sha512-t/oIs9mYyrwZGRpDv3g+3K6nZ5uhKEMt2oNmAPwaY4/ye0+EH4nXIPYNtkYFS6QHm+1DFg34DbglYBz5P9Xysg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + typescript@5.8.2: + resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + ulid@2.3.0: + resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==} + hasBin: true + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@babel/code-frame@7.26.2': dependencies: - is-glob: 4.0.3 - dev: true + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/generator@7.26.10': + dependencies: + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.26.10': + dependencies: + '@babel/types': 7.26.10 - /glob/7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + '@babel/template@7.26.9': dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.10 + '@babel/types': 7.26.10 + + '@babel/traverse@7.26.10': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.10 + '@babel/parser': 7.26.10 + '@babel/template': 7.26.9 + '@babel/types': 7.26.10 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.26.10': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@eslint-community/eslint-utils@4.5.1(eslint@9.22.0)': + dependencies: + eslint: 9.22.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.2': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true + transitivePeerDependencies: + - supports-color - /globals/11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true + '@eslint/config-helpers@0.1.0': {} - /globals/13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} + '@eslint/core@0.12.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.0': + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.22.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.2.7': dependencies: - type-fest: 0.20.2 - dev: true + '@eslint/core': 0.12.0 + levn: 0.4.1 - /globalthis/1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} + '@gerrit0/mini-shiki@1.27.2': dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - dev: true + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 - /globby/11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.2': {} + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@mxssfd/typedoc-theme@1.1.7(typedoc@0.27.9(typescript@5.8.2))': + dependencies: + typedoc: 0.27.9(typescript@5.8.2) + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@pkgr/core@0.1.1': {} + + '@shikijs/engine-oniguruma@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/types@1.29.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.5.3)': + dependencies: + '@babel/generator': 7.26.10 + '@babel/parser': 7.26.10 + '@babel/traverse': 7.26.10 + '@babel/types': 7.26.10 + javascript-natural-sort: 0.7.1 + lodash: 4.17.21 + prettier: 3.5.3 + transitivePeerDependencies: + - supports-color + + '@types/estree@1.0.6': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/node@22.13.10': + dependencies: + undici-types: 6.20.0 + + '@types/unist@3.0.3': {} + + '@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/scope-manager': 8.26.1 + '@typescript-eslint/type-utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.26.1 + eslint: 9.22.0 + graphemer: 1.4.0 ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - dev: true + natural-compare: 1.4.0 + ts-api-utils: 2.0.1(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color - /gopd/1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - dev: true + '@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.26.1 + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) + '@typescript-eslint/visitor-keys': 8.26.1 + debug: 4.4.0 + eslint: 9.22.0 + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color - /graphemer/1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true + '@typescript-eslint/scope-manager@8.26.1': + dependencies: + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/visitor-keys': 8.26.1 + + '@typescript-eslint/type-utils@8.26.1(eslint@9.22.0)(typescript@5.8.2)': + dependencies: + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + debug: 4.4.0 + eslint: 9.22.0 + ts-api-utils: 2.0.1(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.26.1': {} + + '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.2)': + dependencies: + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/visitor-keys': 8.26.1 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.26.1(eslint@9.22.0)(typescript@5.8.2)': + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@9.22.0) + '@typescript-eslint/scope-manager': 8.26.1 + '@typescript-eslint/types': 8.26.1 + '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) + eslint: 9.22.0 + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.26.1': + dependencies: + '@typescript-eslint/types': 8.26.1 + eslint-visitor-keys: 4.2.0 + + acorn-jsx@5.3.2(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + axios@0.26.1: + dependencies: + follow-redirects: 1.15.9 + transitivePeerDependencies: + - debug - /has-bigints/1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - dev: true + balanced-match@1.0.2: {} - /has-flag/4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 - /has-property-descriptors/1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + brace-expansion@2.0.1: dependencies: - es-define-property: 1.0.1 - dev: true + balanced-match: 1.0.2 - /has-proto/1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} + braces@3.0.3: dependencies: - dunder-proto: 1.0.1 - dev: true + fill-range: 7.1.1 - /has-symbols/1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - dev: true + callsites@3.1.0: {} - /has-tostringtag/1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + chalk@4.1.2: dependencies: - has-symbols: 1.1.0 - dev: true + ansi-styles: 4.3.0 + supports-color: 7.2.0 - /hasown/2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + color-convert@2.0.1: dependencies: - function-bind: 1.1.2 - dev: true - - /html-tags/3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} - engines: {node: '>=8'} - dev: true + color-name: 1.1.4 - /hunspell-spellchecker/1.0.2: - resolution: {integrity: sha512-4DwmFAvlz+ChsqLDsZT2cwBsYNXh+oWboemxXtafwKIyItq52xfR4e4kr017sLAoPaSYVofSOvPUfmOAhXyYvw==} - hasBin: true - dev: true + color-name@1.1.4: {} - /ignore/5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - dev: true + concat-map@0.0.1: {} - /import-fresh/3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} + cross-spawn@7.0.6: dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - dev: true - - /imurmurhash/0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 - /inflight/1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + debug@4.4.0: dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true + ms: 2.1.3 - /inherits/2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true + deep-is@0.1.4: {} - /inline-style-parser/0.1.1: - resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} - dev: true + entities@4.5.0: {} - /internal-slot/1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - dev: true + escape-string-regexp@4.0.0: {} - /is-array-buffer/3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} + eslint-config-prettier@8.10.0(eslint@9.22.0): dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - get-intrinsic: 1.2.6 - dev: true + eslint: 9.22.0 + optional: true - /is-async-function/2.0.0: - resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} - engines: {node: '>= 0.4'} + eslint-plugin-prettier@5.2.3(eslint-config-prettier@8.10.0(eslint@9.22.0))(eslint@9.22.0)(prettier@3.5.3): dependencies: - has-tostringtag: 1.0.2 - dev: true + eslint: 9.22.0 + prettier: 3.5.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.9.2 + optionalDependencies: + eslint-config-prettier: 8.10.0(eslint@9.22.0) - /is-bigint/1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} + eslint-scope@8.3.0: dependencies: - has-bigints: 1.1.0 - dev: true + esrecurse: 4.3.0 + estraverse: 5.3.0 - /is-boolean-object/1.2.1: - resolution: {integrity: sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 - dev: true + eslint-visitor-keys@3.4.3: {} - /is-callable/1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true + eslint-visitor-keys@4.2.0: {} - /is-data-view/1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} + eslint@9.22.0: dependencies: - call-bound: 1.0.3 - get-intrinsic: 1.2.6 - is-typed-array: 1.1.15 - dev: true + '@eslint-community/eslint-utils': 4.5.1(eslint@9.22.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.2 + '@eslint/config-helpers': 0.1.0 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.0 + '@eslint/js': 9.22.0 + '@eslint/plugin-kit': 0.2.7 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color - /is-date-object/1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} + espree@10.3.0: dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 - dev: true - - /is-extglob/2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 4.2.0 - /is-finalizationregistry/1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} + esquery@1.6.0: dependencies: - call-bound: 1.0.3 - dev: true + estraverse: 5.3.0 - /is-generator-function/1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} + esrecurse@4.3.0: dependencies: - has-tostringtag: 1.0.2 - dev: true + estraverse: 5.3.0 - /is-glob/4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true + estraverse@5.3.0: {} - /is-html/2.0.0: - resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==} - engines: {node: '>=8'} - dependencies: - html-tags: 3.3.1 - dev: true + esutils@2.0.3: {} + + eventemitter3@5.0.1: {} - /is-map/2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - dev: true + fast-deep-equal@3.1.3: {} - /is-number-object/1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} + fast-diff@1.3.0: {} + + fast-glob@3.3.3: dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 - dev: true + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 - /is-number/7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true + fast-json-stable-stringify@2.1.0: {} - /is-path-inside/3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true + fast-levenshtein@2.0.6: {} - /is-regex/1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} + fastq@1.19.1: dependencies: - call-bound: 1.0.3 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - dev: true - - /is-set/2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - dev: true + reusify: 1.1.0 - /is-shared-array-buffer/1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} + file-entry-cache@8.0.0: dependencies: - call-bound: 1.0.3 - dev: true + flat-cache: 4.0.1 - /is-string/1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} + fill-range@7.1.1: dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 - dev: true + to-regex-range: 5.0.1 - /is-symbol/1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} + find-up@5.0.0: dependencies: - call-bound: 1.0.3 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - dev: true + locate-path: 6.0.0 + path-exists: 4.0.0 - /is-typed-array/1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} + flat-cache@4.0.1: dependencies: - which-typed-array: 1.1.18 - dev: true + flatted: 3.3.3 + keyv: 4.5.4 - /is-weakmap/2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - dev: true + flatted@3.3.3: {} - /is-weakref/1.1.0: - resolution: {integrity: sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==} - engines: {node: '>= 0.4'} + follow-redirects@1.15.9: {} + + glob-parent@5.1.2: dependencies: - call-bound: 1.0.3 - dev: true + is-glob: 4.0.3 - /is-weakset/2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} + glob-parent@6.0.2: dependencies: - call-bound: 1.0.3 - get-intrinsic: 1.2.6 - dev: true + is-glob: 4.0.3 - /isarray/2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true + globals@11.12.0: {} - /isexe/2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true + globals@14.0.0: {} - /isomorphic-ws/5.0.0_ws@8.18.0: - resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} - peerDependencies: - ws: '*' - dependencies: - ws: 8.18.0 - dev: false + graphemer@1.4.0: {} - /javascript-natural-sort/0.7.1: - resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} - dev: true + has-flag@4.0.0: {} - /js-tokens/4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true + ignore@5.3.2: {} - /js-yaml/4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + import-fresh@3.3.1: dependencies: - argparse: 2.0.1 - dev: true + parent-module: 1.0.1 + resolve-from: 4.0.0 - /jsesc/2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true + imurmurhash@0.1.4: {} - /jsesc/3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - dev: true + is-extglob@2.1.1: {} - /json-buffer/3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - dev: true + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 - /json-schema-traverse/0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true + is-number@7.0.0: {} - /json-stable-stringify-without-jsonify/1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true + isexe@2.0.0: {} - /jsonc-parser/3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - dev: true + javascript-natural-sort@0.7.1: {} - /jsx-ast-utils/3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} + js-tokens@4.0.0: {} + + js-yaml@4.1.0: dependencies: - array-includes: 3.1.8 - array.prototype.flat: 1.3.3 - object.assign: 4.1.7 - object.values: 1.2.1 - dev: true + argparse: 2.0.1 - /kebab-case/1.0.2: - resolution: {integrity: sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q==} - dev: true + jsesc@3.1.0: {} - /keyv/4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: dependencies: json-buffer: 3.0.1 - dev: true - /known-css-properties/0.24.0: - resolution: {integrity: sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==} - dev: true - - /levn/0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - /locate-path/6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + linkify-it@5.0.0: dependencies: - p-locate: 5.0.0 - dev: true + uc.micro: 2.1.0 - /lodash.defaultsdeep/4.6.1: - resolution: {integrity: sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==} - dev: false - - /lodash.merge/4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 - /lodash/4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true + lodash.defaultsdeep@4.6.1: {} - /long/5.2.3: - resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} - dev: false + lodash.merge@4.6.2: {} - /lunr/2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - dev: true + lodash@4.17.21: {} - /map-stream/0.1.0: - resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} - dev: true + lunr@2.3.9: {} - /marked/4.3.0: - resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} - engines: {node: '>= 12'} - hasBin: true - dev: true + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 - /math-intrinsics/1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - dev: true + mdurl@2.0.0: {} - /merge2/1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true + merge2@1.4.1: {} - /micromatch/4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 - dev: true - /minimatch/3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - dev: true - /minimatch/9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 - dev: true - /ms/2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true + ms@2.1.3: {} - /natural-compare-lite/1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true + natural-compare@1.4.0: {} - /natural-compare/1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true - - /node-cleanup/2.1.2: - resolution: {integrity: sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==} - dev: true - - /object-inspect/1.13.3: - resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} - engines: {node: '>= 0.4'} - dev: true - - /object-keys/1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true - - /object.assign/4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - has-symbols: 1.1.0 - object-keys: 1.1.1 - dev: true - - /object.values/1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - dev: true - - /once/1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - - /optionator/0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} + optionator@0.9.4: dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 @@ -1748,629 +1318,126 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 word-wrap: 1.2.5 - dev: true - /p-limit/3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - dev: true - /p-locate/5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - dev: true - /parent-module/1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + parent-module@1.0.1: dependencies: callsites: 3.1.0 - dev: true - - /path-exists/4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-is-absolute/1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - /path-key/3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true + path-exists@4.0.0: {} - /path-type/4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true + path-key@3.1.1: {} - /pause-stream/0.0.11: - resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - dependencies: - through: 2.3.8 - dev: true + picocolors@1.1.1: {} - /picocolors/1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - dev: true + picomatch@2.3.1: {} - /picomatch/2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true + prelude-ls@1.2.1: {} - /possible-typed-array-names/1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} - dev: true + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 - /prelude-ls/1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true + prettier@3.5.3: {} - /prettier/2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true + punycode.js@2.3.1: {} - /ps-tree/1.2.0: - resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} - engines: {node: '>= 0.10'} - hasBin: true - dependencies: - event-stream: 3.3.4 - dev: true + punycode@2.3.1: {} - /punycode/2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - dev: true + queue-microtask@1.2.3: {} - /queue-microtask/1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - /reflect.getprototypeof/1.0.9: - resolution: {integrity: sha512-r0Ay04Snci87djAsI4U+WNRcSw5S4pOH7qFjd/veA5gC7TbqESR3tcj28ia95L/fYUDw11JKP7uqUKUAfVvV5Q==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - dunder-proto: 1.0.1 - es-abstract: 1.23.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.6 - gopd: 1.2.0 - which-builtin-type: 1.2.1 - dev: true - - /regexp.prototype.flags/1.5.3: - resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - set-function-name: 2.0.2 - dev: true - - /resolve-from/4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true + resolve-from@4.0.0: {} - /reusify/1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true + reusify@1.1.0: {} - /revolt-api/0.8.3: - resolution: {integrity: sha512-4dOe6sbiWFGF5PlAuYtH9vWHXdFOge/L6/EKr6oLgslN+QBn2DKfSOIhl6Ni2n0B0cBurhA1KuBy0mWfE68fIQ==} + revolt-api@0.8.3: dependencies: axios: 0.26.1 lodash.defaultsdeep: 4.6.1 transitivePeerDependencies: - debug - dev: false - - /rimraf/3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - /run-parallel/1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - dev: true - - /rxjs/7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - requiresBuild: true - dependencies: - tslib: 2.8.1 - dev: true - optional: true - - /safe-array-concat/1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - get-intrinsic: 1.2.6 - has-symbols: 1.1.0 - isarray: 2.0.5 - dev: true - - /safe-regex-test/1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-regex: 1.2.1 - dev: true - - /semver/7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} - hasBin: true - dev: true - /seroval-plugins/1.1.1_seroval@1.1.1: - resolution: {integrity: sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==} - engines: {node: '>=10'} - peerDependencies: - seroval: ^1.0 - dependencies: - seroval: 1.1.1 - dev: false + semver@7.7.1: {} - /seroval/1.1.1: - resolution: {integrity: sha512-rqEO6FZk8mv7Hyv4UCj3FD3b6Waqft605TLfsCe/BiaylRpyyMC0b+uA5TJKawX3KzMrdi3wsLbCaLplrQmBvQ==} - engines: {node: '>=10'} - dev: false - - /set-function-length/1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.6 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - dev: true - - /set-function-name/2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - dev: true - - /shebang-command/2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - dev: true - - /shebang-regex/3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true - - /shiki/0.14.7: - resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} - dependencies: - ansi-sequence-parser: 1.1.1 - jsonc-parser: 3.3.1 - vscode-oniguruma: 1.7.0 - vscode-textmate: 8.0.0 - dev: true - - /side-channel-list/1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.3 - dev: true - - /side-channel-map/1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.6 - object-inspect: 1.13.3 - dev: true - - /side-channel-weakmap/1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.6 - object-inspect: 1.13.3 - side-channel-map: 1.0.1 - dev: true - - /side-channel/1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.3 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - dev: true - - /slash/3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - /solid-js/1.9.3: - resolution: {integrity: sha512-5ba3taPoZGt9GY3YlsCB24kCg0Lv/rie/HTD4kG6h4daZZz7+yK02xn8Vx8dLYBc9i6Ps5JwAbEiqjmKaLB3Ag==} - dependencies: - csstype: 3.1.3 - seroval: 1.1.1 - seroval-plugins: 1.1.1_seroval@1.1.1 - dev: false - /source-map/0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - dev: true - - /split/0.3.3: - resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} - dependencies: - through: 2.3.8 - dev: true - - /stream-combiner/0.0.4: - resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - dependencies: - duplexer: 0.1.2 - dev: true - - /string-argv/0.3.2: - resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} - engines: {node: '>=0.6.19'} - dev: true - - /string.prototype.trim/1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.23.7 - es-object-atoms: 1.0.0 - has-property-descriptors: 1.0.2 - dev: true - - /string.prototype.trimend/1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - dev: true - - /string.prototype.trimstart/1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - dev: true - - /strip-ansi/6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - - /strip-json-comments/3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true + shebang-regex@3.0.0: {} - /style-to-object/0.3.0: - resolution: {integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==} - dependencies: - inline-style-parser: 0.1.1 - dev: true + strip-json-comments@3.1.1: {} - /supports-color/7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: true - - /text-table/0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - - /to-fast-properties/2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.1 - /to-regex-range/5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - dev: true - /tsc-watch/6.2.1_typescript@5.7.2: - resolution: {integrity: sha512-GLwdz5Dy9K3sVm3RzgkLcyDpl5cvU9HEcE1A3gf5rqEwlUe7gDLxNCgcuNEw3zoKOiegMo3LnbF1t6HLqxhrSA==} - engines: {node: '>=12.12.0'} - hasBin: true - peerDependencies: - typescript: '*' + ts-api-utils@2.0.1(typescript@5.8.2): dependencies: - cross-spawn: 7.0.6 - node-cleanup: 2.1.2 - ps-tree: 1.2.0 - string-argv: 0.3.2 - typescript: 5.7.2 - dev: true - - /tslib/1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true + typescript: 5.8.2 - /tslib/2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - dev: true - optional: true - - /tsutils/3.21.0_typescript@5.7.2: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 5.7.2 - dev: true + tslib@2.8.1: {} - /type-check/0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - dev: true - /type-fest/0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true - - /typed-array-buffer/1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - dev: true - - /typed-array-byte-length/1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - for-each: 0.3.3 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - dev: true - - /typed-array-byte-offset/1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.3 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.9 - dev: true - - /typed-array-length/1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.8 - for-each: 0.3.3 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.0.0 - reflect.getprototypeof: 1.0.9 - dev: true - - /typed-emitter/2.1.0: - resolution: {integrity: sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==} - optionalDependencies: - rxjs: 7.8.1 - dev: true - - /typedoc/0.25.13_typescript@5.7.2: - resolution: {integrity: sha512-pQqiwiJ+Z4pigfOnnysObszLiU3mVLWAExSPf+Mu06G/qsc3wzbuM56SZQvONhHLncLUhYzOVkjFFpFfL5AzhQ==} - engines: {node: '>= 16'} - hasBin: true - peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x + typedoc@0.27.9(typescript@5.8.2): dependencies: + '@gerrit0/mini-shiki': 1.27.2 lunr: 2.3.9 - marked: 4.3.0 + markdown-it: 14.1.0 minimatch: 9.0.5 - shiki: 0.14.7 - typescript: 5.7.2 - dev: true + typescript: 5.8.2 + yaml: 2.7.0 - /typescript/5.7.2: - resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} - engines: {node: '>=14.17'} - hasBin: true - dev: true + typescript-eslint@8.26.1(eslint@9.22.0)(typescript@5.8.2): + dependencies: + '@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) + eslint: 9.22.0 + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color - /ulid/2.3.0: - resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==} - hasBin: true - dev: false + typescript@5.8.2: {} - /unbox-primitive/1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - dev: true + uc.micro@2.1.0: {} - /undici-types/5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - dev: true + ulid@2.3.0: {} - /uri-js/4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + undici-types@6.20.0: {} + + uri-js@4.4.1: dependencies: punycode: 2.3.1 - dev: true - - /vscode-oniguruma/1.7.0: - resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} - dev: true - - /vscode-textmate/8.0.0: - resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} - dev: true - - /which-boxed-primitive/1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.1 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - dev: true - - /which-builtin-type/1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - dependencies: - call-bound: 1.0.3 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.0.0 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.0.10 - is-regex: 1.2.1 - is-weakref: 1.1.0 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.18 - dev: true - - /which-collection/1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - dev: true - - /which-typed-array/1.1.18: - resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.3 - for-each: 0.3.3 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - dev: true - - /which/2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + + which@2.0.2: dependencies: isexe: 2.0.0 - dev: true - - /word-wrap/1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - dev: true - /wrappy/1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true + word-wrap@1.2.5: {} - /ws/8.18.0: - resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false + yaml@2.7.0: {} - /yocto-queue/0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + yocto-queue@0.1.0: {} diff --git a/src/Client.ts b/src/Client.ts index 994bdad1..1f8ebf29 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,44 +1,36 @@ -import { Accessor, Setter, batch, createSignal } from "solid-js"; - import EventEmitter from "eventemitter3"; -import type { DataLogin, Error, RevoltConfig } from "revolt-api"; +import type { DataLogin, RevoltConfig } from "revolt-api"; import { API, Role } from "revolt-api"; -import { - Channel, - Emoji, - Message, - Server, - ServerMember, - User, -} from "./classes/index.js"; +import { Channel } from "./classes/Channel.js"; +import { Emoji } from "./classes/Emoji.js"; +import { Message } from "./classes/Message.js"; +import { Server } from "./classes/Server.js"; +import { ServerMember } from "./classes/ServerMember.js"; +import { User } from "./classes/User.js"; import { AccountCollection } from "./collections/AccountCollection.js"; -import { - BotCollection, - ChannelCollection, - ChannelUnreadCollection, - ChannelWebhookCollection, - EmojiCollection, - MessageCollection, - ServerCollection, - ServerMemberCollection, - SessionCollection, - UserCollection, -} from "./collections/index.js"; +import { BotCollection } from "./collections/BotCollection.js"; +import { ChannelCollection } from "./collections/ChannelCollection.js"; +import { ChannelUnreadCollection } from "./collections/ChannelUnreadCollection.js"; +import { ChannelWebhookCollection } from "./collections/ChannelWebhookCollection.js"; +import { EmojiCollection } from "./collections/EmojiCollection.js"; +import { MessageCollection } from "./collections/MessageCollection.js"; +import { ServerCollection } from "./collections/ServerCollection.js"; +import { ServerMemberCollection } from "./collections/ServerMemberCollection.js"; +import { SessionCollection } from "./collections/SessionCollection.js"; +import { UserCollection } from "./collections/UserCollection.js"; import { ConnectionState, EventClient, EventClientOptions, - handleEventV1, -} from "./events/index.js"; -import { - HydratedChannel, - HydratedEmoji, - HydratedMessage, - HydratedServer, - HydratedServerMember, - HydratedUser, -} from "./hydration/index.js"; +} from "./events/EventClient.js"; +import { handleEvent } from "./events/v1.js"; +import { HydratedChannel } from "./hydration/channel.js"; +import { HydratedEmoji } from "./hydration/emoji.js"; +import { HydratedMessage } from "./hydration/message.js"; +import { HydratedServer } from "./hydration/server.js"; +import { HydratedServerMember } from "./hydration/serverMember.js"; +import { HydratedUser } from "./hydration/user.js"; import { RE_CHANNELS, RE_MENTIONS, RE_SPOILER } from "./lib/regex.js"; export type Session = { _id: string; token: string; user_id: string } | string; @@ -82,7 +74,7 @@ export type Events = { serverMemberUpdate( member: ServerMember, - previousMember: HydratedServerMember + previousMember: HydratedServerMember, ): void; serverMemberJoin(member: ServerMember): void; serverMemberLeave(member: HydratedServerMember): void; @@ -92,7 +84,7 @@ export type Events = { // ^ userPresenceChanged(user: User, previousPresence: boolean): void; userSettingsUpdate( id: string, - update: Record + update: Record, ): void; emojiCreate(emoji: Emoji): void; @@ -160,31 +152,29 @@ export type ClientOptions = Partial & { * Revolt.js Clients */ export class Client extends EventEmitter { - readonly account; - readonly bots; - readonly channels; - readonly channelUnreads; - readonly channelWebhooks; - readonly emojis; - readonly messages; - readonly servers; - readonly serverMembers; - readonly sessions; - readonly users; + readonly account = new AccountCollection(this); + readonly bots = new BotCollection(this); + readonly channels = new ChannelCollection(this); + readonly channelUnreads = new ChannelUnreadCollection(this); + readonly channelWebhooks = new ChannelWebhookCollection(this); + readonly emojis = new EmojiCollection(this); + readonly messages = new MessageCollection(this); + readonly servers = new ServerCollection(this); + readonly serverMembers = new ServerMemberCollection(this); + readonly sessions = new SessionCollection(this); + readonly users = new UserCollection(this); readonly api: API; readonly options: ClientOptions; readonly events: EventClient<1>; - configuration: RevoltConfig | undefined; + public configuration: RevoltConfig | undefined; #session: Session | undefined; user: User | undefined; - readonly ready: Accessor; - #setReady: Setter; + #ready = false; + connectionFailureCount = 0; - readonly connectionFailureCount: Accessor; - #setConnectionFailureCount: Setter; #reconnectTimeout: number | undefined; /** @@ -225,36 +215,14 @@ export class Client extends EventEmitter { baseURL: this.options.baseURL, }); - const [ready, setReady] = createSignal(false); - this.ready = ready; - this.#setReady = setReady; - - const [connectionFailureCount, setConnectionFailureCount] = createSignal(0); - this.connectionFailureCount = connectionFailureCount; - this.#setConnectionFailureCount = setConnectionFailureCount; - - this.account = new AccountCollection(this); - this.bots = new BotCollection(this); - this.channels = new ChannelCollection(this); - this.channelUnreads = new ChannelUnreadCollection(this); - this.channelWebhooks = new ChannelWebhookCollection(this); - this.emojis = new EmojiCollection(this); - this.messages = new MessageCollection(this); - this.servers = new ServerCollection(this); - this.serverMembers = new ServerMemberCollection(this); - this.sessions = new SessionCollection(this); - this.users = new UserCollection(this); - this.events = new EventClient(1, "json", this.options); this.events.on("error", (error) => this.emit("error", error)); this.events.on("state", (state) => { switch (state) { case ConnectionState.Connected: - batch(() => { - this.servers.forEach((server) => server.resetSyncStatus()); - this.#setConnectionFailureCount(0); - this.emit("connected"); - }); + this.servers.forEach((server) => server.resetSyncStatus()); + this.connectionFailureCount = 0; + this.emit("connected"); break; case ConnectionState.Connecting: this.emit("connecting"); @@ -264,21 +232,35 @@ export class Client extends EventEmitter { if (this.options.autoReconnect) { this.#reconnectTimeout = setTimeout( () => this.connect(), - this.options.retryDelayFunction(this.connectionFailureCount()) * - 1e3 + this.options.retryDelayFunction(this.connectionFailureCount) * + 1e3, ) as never; - this.#setConnectionFailureCount((count) => count + 1); + this.connectionFailureCount = this.connectionFailureCount + 1; } break; } }); this.events.on("event", (event) => - handleEventV1(this, event, this.#setReady) + handleEvent(this, event, this.#setReady.bind(this)), ); } + /** + * Whether the client is ready + */ + get ready() { + return this.#ready; + } + + /** + * Set whether the client is ready + */ + #setReady(value: boolean) { + this.#ready = value; + } + /** * Current session id */ @@ -304,7 +286,7 @@ export class Client extends EventEmitter { this.#setReady(false); this.events.connect( this.configuration?.ws ?? "wss://ws.revolt.chat", - typeof this.#session === "string" ? this.#session : this.#session!.token + typeof this.#session === "string" ? this.#session : this.#session!.token, ); } @@ -399,9 +381,9 @@ export class Client extends EventEmitter { */ proxyFile(url: string): string | undefined { if (this.configuration?.features.january.enabled) { - return `${ - this.configuration.features.january.url - }/proxy?url=${encodeURIComponent(url)}`; + return `${this.configuration.features.january.url}/proxy?url=${encodeURIComponent( + url, + )}`; } else { return url; } diff --git a/src/classes/BannedUser.ts b/src/classes/BannedUser.ts index ce96c9d6..4059a7e0 100644 --- a/src/classes/BannedUser.ts +++ b/src/classes/BannedUser.ts @@ -1,6 +1,8 @@ -import { BannedUser as ApiBannedUser } from "revolt-api"; +import { BannedUser as APIBannedUser } from "revolt-api"; -import { Client, File } from "../index.js"; +import { Client } from "../Client.js"; + +import { File } from "./File.js"; /** * Banned User @@ -16,7 +18,7 @@ export class BannedUser { * @param client Client * @param data Data */ - constructor(client: Client, data: ApiBannedUser) { + constructor(client: Client, data: APIBannedUser) { this.id = data._id; this.avatar = data.avatar ? new File(client, data.avatar) : undefined; this.username = data.username; diff --git a/src/classes/Bot.ts b/src/classes/Bot.ts index 4527c773..689fd316 100644 --- a/src/classes/Bot.ts +++ b/src/classes/Bot.ts @@ -1,7 +1,7 @@ import { DataEditBot } from "revolt-api"; import { decodeTime } from "ulid"; -import { BotCollection } from "../collections/index.js"; +import { BotCollection } from "../collections/BotCollection.js"; /** * Bot Class diff --git a/src/classes/Channel.ts b/src/classes/Channel.ts index 02220ccc..d38c16b7 100644 --- a/src/classes/Channel.ts +++ b/src/classes/Channel.ts @@ -1,9 +1,7 @@ -import { batch } from "solid-js"; - import type { - Member as ApiMember, - Message as ApiMessage, - User as ApiUser, + Member as APIMember, + Message as APIMessage, + User as APIUser, DataEditChannel, DataMessageSearch, DataMessageSend, @@ -12,14 +10,15 @@ import type { import { APIRoutes } from "revolt-api/dist/routes"; import { decodeTime, ulid } from "ulid"; -import { ChannelCollection } from "../collections/index.js"; -import { Message } from "../index.js"; +import { ChannelCollection } from "../collections/ChannelCollection.js"; import { bitwiseAndEq, calculatePermission, } from "../permissions/calculator.js"; import { Permission } from "../permissions/definitions.js"; +import { Message } from "./Message.js"; + /** * Channel Class */ @@ -98,8 +97,8 @@ export class Channel { return this.type === "SavedMessages" ? this.user?.username : this.type === "DirectMessage" - ? this.recipient?.username - : this.name; + ? this.recipient?.username + : this.name; } /** @@ -135,7 +134,7 @@ export class Channel { */ get typing() { return [...this.typingIds.values()].map( - (id) => this.#collection.client.users.get(id)! + (id) => this.#collection.client.users.get(id)!, ); } @@ -161,7 +160,7 @@ export class Channel { get recipient() { return this.type === "DirectMessage" ? this.recipients?.find( - (user) => user?.id !== this.#collection.client.user!.id + (user) => user?.id !== this.#collection.client.user!.id, ) : undefined; } @@ -178,7 +177,7 @@ export class Channel { */ get user() { return this.#collection.client.users.get( - this.#collection.getUnderlyingObject(this.id).userId! + this.#collection.getUnderlyingObject(this.id).userId!, ); } @@ -194,7 +193,7 @@ export class Channel { */ get owner() { return this.#collection.client.users.get( - this.#collection.getUnderlyingObject(this.id).ownerId! + this.#collection.getUnderlyingObject(this.id).ownerId!, ); } @@ -210,7 +209,7 @@ export class Channel { */ get server() { return this.#collection.client.servers.get( - this.#collection.getUnderlyingObject(this.id).serverId! + this.#collection.getUnderlyingObject(this.id).serverId!, ); } @@ -281,8 +280,9 @@ export class Channel { this.type === "SavedMessages" || this.type === "VoiceChannel" || this.#collection.client.options.channelIsMuted(this) - ) + ) { return false; + } return ( ( @@ -296,8 +296,9 @@ export class Channel { * Get mentions in this channel for user. */ get mentions() { - if (this.type === "SavedMessages" || this.type === "VoiceChannel") + if (this.type === "SavedMessages" || this.type === "VoiceChannel") { return undefined; + } return this.#collection.client.channelUnreads.get(this.id) ?.messageMentionIds; @@ -329,12 +330,12 @@ export class Channel { (role) => bitwiseAndEq( this.rolePermissions?.[role]?.d ?? 0, - Permission.ViewChannel + Permission.ViewChannel, ) || bitwiseAndEq( this.server?.roles.get(role)?.permissions.d ?? 0, - Permission.ViewChannel - ) + Permission.ViewChannel, + ), ) ); } @@ -354,7 +355,7 @@ export class Channel { havePermission(...permission: (keyof typeof Permission)[]) { return bitwiseAndEq( this.permission, - ...permission.map((x) => Permission[x]) + ...permission.map((x) => Permission[x]), ); } @@ -366,7 +367,7 @@ export class Channel { orPermission(...permission: (keyof typeof Permission)[]) { return ( permission.findIndex((x) => - bitwiseAndEq(this.permission, Permission[x]) + bitwiseAndEq(this.permission, Permission[x]), ) !== -1 ); } @@ -378,13 +379,11 @@ export class Channel { */ async fetchMembers() { const members = await this.#collection.client.api.get( - `/channels/${this.id as ""}/members` + `/channels/${this.id as ""}/members`, ); - return batch(() => - members.map((user) => - this.#collection.client.users.getOrCreate(user._id, user) - ) + return members.map((user) => + this.#collection.client.users.getOrCreate(user._id, user), ); } @@ -395,13 +394,11 @@ export class Channel { */ async fetchWebhooks() { const webhooks = await this.#collection.client.api.get( - `/channels/${this.id as ""}/webhooks` + `/channels/${this.id as ""}/webhooks`, ); - return batch(() => - webhooks.map((webhook) => - this.#collection.client.channelWebhooks.getOrCreate(webhook.id, webhook) - ) + return webhooks.map((webhook) => + this.#collection.client.channelWebhooks.getOrCreate(webhook.id, webhook), ); } @@ -424,7 +421,7 @@ export class Channel { }); if (this.type === "DirectMessage") { - this.#collection.updateUnderlyingObject(this.id, "active", false); + this.#collection.setKeyUnderlyingObject(this.id, "active", false); return; } @@ -438,7 +435,7 @@ export class Channel { */ async addMember(user_id: string) { return await this.#collection.client.api.put( - `/channels/${this.id as ""}/recipients/${user_id as ""}` + `/channels/${this.id as ""}/recipients/${user_id as ""}`, ); } @@ -449,7 +446,7 @@ export class Channel { */ async removeMember(user_id: string) { return await this.#collection.client.api.delete( - `/channels/${this.id as ""}/recipients/${user_id as ""}` + `/channels/${this.id as ""}/recipients/${user_id as ""}`, ); } @@ -461,7 +458,7 @@ export class Channel { */ async sendMessage( data: string | DataMessageSend, - idempotencyKey: string = ulid() + idempotencyKey: string = ulid(), ) { const msg: DataMessageSend = typeof data === "string" ? { content: data } : data; @@ -480,13 +477,13 @@ export class Channel { headers: { "Idempotency-Key": idempotencyKey, }, - } + }, ); return this.#collection.client.messages.getOrCreate( message._id, message, - true + true, ); } @@ -498,7 +495,7 @@ export class Channel { */ async fetchMessage(messageId: string) { const message = await this.#collection.client.api.get( - `/channels/${this.id as ""}/messages/${messageId as ""}` + `/channels/${this.id as ""}/messages/${messageId as ""}`, ); return this.#collection.client.messages.getOrCreate(message._id, message); @@ -517,15 +514,15 @@ export class Channel { path: "/channels/{target}/messages"; })["params"], "include_users" - > + >, ) { const messages = (await this.#collection.client.api.get( `/channels/${this.id as ""}/messages`, - { ...params } - )) as ApiMessage[]; + { ...params }, + )) as APIMessage[]; return messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message) + this.#collection.client.messages.getOrCreate(message._id, message), ); } @@ -542,24 +539,24 @@ export class Channel { path: "/channels/{target}/messages"; })["params"], "include_users" - > + >, ) { const data = (await this.#collection.client.api.get( `/channels/${this.id as ""}/messages`, - { ...params, include_users: true } - )) as { messages: ApiMessage[]; users: ApiUser[]; members?: ApiMember[] }; + { ...params, include_users: true }, + )) as { messages: APIMessage[]; users: APIUser[]; members?: APIMember[] }; - return batch(() => ({ + return { messages: data.messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message) + this.#collection.client.messages.getOrCreate(message._id, message), ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user) + this.#collection.client.users.getOrCreate(user._id, user), ), members: data.members?.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member) + this.#collection.client.serverMembers.getOrCreate(member._id, member), ), - })); + }; } /** @@ -571,13 +568,11 @@ export class Channel { async search(params: Omit) { const messages = (await this.#collection.client.api.post( `/channels/${this.id as ""}/search`, - params - )) as ApiMessage[]; + params, + )) as APIMessage[]; - return batch(() => - messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message) - ) + return messages.map((message) => + this.#collection.client.messages.getOrCreate(message._id, message), ); } @@ -593,20 +588,20 @@ export class Channel { { ...params, include_users: true, - } - )) as { messages: ApiMessage[]; users: ApiUser[]; members?: ApiMember[] }; + }, + )) as { messages: APIMessage[]; users: APIUser[]; members?: APIMember[] }; - return batch(() => ({ + return { messages: data.messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message) + this.#collection.client.messages.getOrCreate(message._id, message), ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user) + this.#collection.client.users.getOrCreate(user._id, user), ), members: data.members?.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member) + this.#collection.client.serverMembers.getOrCreate(member._id, member), ), - })); + }; } /** @@ -619,7 +614,7 @@ export class Channel { `/channels/${this.id as ""}/messages/bulk`, { ids, - } + }, ); } @@ -630,7 +625,7 @@ export class Channel { */ async createInvite() { return await this.#collection.client.api.post( - `/channels/${this.id as ""}/invites` + `/channels/${this.id as ""}/invites`, ); } @@ -650,13 +645,12 @@ export class Channel { message?: Message | string, skipRateLimiter?: boolean, skipRequest?: boolean, - skipNextMarking?: boolean + skipNextMarking?: boolean, ) { if (!message && this.#manuallyMarked) { this.#manuallyMarked = false; return; - } - // Skip the next unread marking + } // Skip the next unread marking else if (skipNextMarking) { this.#manuallyMarked = true; } @@ -670,7 +664,10 @@ export class Channel { const channelUnread = unreads.get(this.id); if (channelUnread) { unreads.updateUnderlyingObject(this.id, { + ...channelUnread, lastMessageId, + messageMentionIds: unreads.getUnderlyingObject(this.id) + .messageMentionIds, }); if (channelUnread.messageMentionIds.size) { @@ -687,7 +684,7 @@ export class Channel { const performAck = () => { this.#ackLimit = undefined; this.#collection.client.api.put( - `/channels/${this.id}/ack/${lastMessageId as ""}` + `/channels/${this.id}/ack/${lastMessageId as ""}`, ); }; @@ -715,7 +712,7 @@ export class Channel { async setPermissions(role_id = "default", permissions: Override) { return await this.#collection.client.api.put( `/channels/${this.id as ""}/permissions/${role_id as ""}`, - { permissions } + { permissions }, ); } diff --git a/src/classes/ChannelUnread.ts b/src/classes/ChannelUnread.ts index 738174be..adfd24e1 100644 --- a/src/classes/ChannelUnread.ts +++ b/src/classes/ChannelUnread.ts @@ -1,4 +1,4 @@ -import { ChannelUnreadCollection } from "../collections/index.js"; +import { ChannelUnreadCollection } from "../collections/ChannelUnreadCollection.js"; /** * Channel Unread Class diff --git a/src/classes/ChannelWebhook.ts b/src/classes/ChannelWebhook.ts index aa73fcf9..14468c14 100644 --- a/src/classes/ChannelWebhook.ts +++ b/src/classes/ChannelWebhook.ts @@ -1,4 +1,4 @@ -import { ChannelWebhookCollection } from "../collections/index.js"; +import { ChannelWebhookCollection } from "../collections/ChannelWebhookCollection.js"; import { hydrate } from "../hydration/index.js"; /** @@ -60,7 +60,7 @@ export class ChannelWebhook { */ get channel() { return this.#collection.client.channels.get( - this.#collection.getUnderlyingObject(this.id).channelId + this.#collection.getUnderlyingObject(this.id).channelId, ); } @@ -75,17 +75,17 @@ export class ChannelWebhook { * Edit this webhook * TODO: not in production */ - async edit(data: any /*: DataEditWebhook*/) { + async edit(data: unknown /*: DataEditWebhook*/) { const webhook = await this.#collection.client.api.patch( // @ts-expect-error not in prod `/webhooks/${this.id as ""}/${this.token as ""}`, - data + data, ); this.#collection.updateUnderlyingObject( this.id, // @ts-expect-error not in prod - hydrate("channelWebhook", webhook, this.#collection.client) + hydrate("channelWebhook", webhook, this.#collection.client), ); } @@ -96,7 +96,7 @@ export class ChannelWebhook { async delete() { await this.#collection.client.api.delete( // @ts-expect-error not in prod - `/webhooks/${this.id}/${this.token}` + `/webhooks/${this.id}/${this.token}`, ); this.#collection.delete(this.id); diff --git a/src/classes/Emoji.ts b/src/classes/Emoji.ts index 2bf03aed..8f578c34 100644 --- a/src/classes/Emoji.ts +++ b/src/classes/Emoji.ts @@ -1,6 +1,6 @@ import { decodeTime } from "ulid"; -import { EmojiCollection } from "../collections/index.js"; +import { EmojiCollection } from "../collections/EmojiCollection.js"; /** * Emoji Class @@ -53,7 +53,7 @@ export class Emoji { */ get creator() { return this.#collection.client.users.get( - this.#collection.getUnderlyingObject(this.id).creatorId + this.#collection.getUnderlyingObject(this.id).creatorId, ); } diff --git a/src/classes/File.ts b/src/classes/File.ts index ce40d07c..b78abbd4 100644 --- a/src/classes/File.ts +++ b/src/classes/File.ts @@ -1,6 +1,6 @@ -import { Metadata } from "revolt-api"; +import { File as APIFile, Metadata } from "revolt-api"; -import { API, Client } from "../index.js"; +import { Client } from "../Client.js"; /** * Uploaded File @@ -45,7 +45,7 @@ export class File { */ constructor( client: Client, - file: Pick & Partial + file: Pick & Partial, ) { this.#client = client; this.id = file._id; diff --git a/src/classes/Invite.ts b/src/classes/Invite.ts index 3b9b3a71..f8f09af0 100644 --- a/src/classes/Invite.ts +++ b/src/classes/Invite.ts @@ -1,18 +1,20 @@ -import { API, Client } from "../index.js"; +import { Invite } from "revolt-api"; + +import { Client } from "../Client.js"; /** * Channel Invite */ export abstract class ChannelInvite { protected client?: Client; - readonly type: API.Invite["type"] | "None"; + readonly type: Invite["type"] | "None"; /** * Construct Channel Invite * @param client Client * @param type Type */ - constructor(client?: Client, type: API.Invite["type"] | "None" = "None") { + constructor(client?: Client, type: Invite["type"] | "None" = "None") { this.client = client; this.type = type; } @@ -23,7 +25,7 @@ export abstract class ChannelInvite { * @param invite Data * @returns Invite */ - static from(client: Client, invite: API.Invite): ChannelInvite { + static from(client: Client, invite: Invite): ChannelInvite { switch (invite.type) { case "Server": return new ServerInvite(client, invite); @@ -52,7 +54,7 @@ export class ServerInvite extends ChannelInvite { * @param client Client * @param invite Invite */ - constructor(client: Client, invite: API.Invite & { type: "Server" }) { + constructor(client: Client, invite: Invite & { type: "Server" }) { super(client, "Server"); this.id = invite._id; diff --git a/src/classes/MFA.ts b/src/classes/MFA.ts index 739c1e86..eb0c5438 100644 --- a/src/classes/MFA.ts +++ b/src/classes/MFA.ts @@ -1,5 +1,3 @@ -import { SetStoreFunction, createStore } from "solid-js/store"; - import { MFAMethod, MFAResponse, @@ -7,14 +5,14 @@ import { MFATicket as TicketType, } from "revolt-api"; -import { Client } from "../index.js"; +import { Client } from "../Client.js"; /** * Multi-Factor Authentication */ export class MFA { #client: Client; - #store: [MultiFactorStatus, SetStoreFunction]; + #store: MultiFactorStatus; /** * Construct MFA helper @@ -23,21 +21,30 @@ export class MFA { */ constructor(client: Client, state: MultiFactorStatus) { this.#client = client; - this.#store = createStore(state); + this.#store = state; + } + + /** + * Set MFA status + * @param key key to set + * @param value boolean + */ + #setStore(key: keyof MultiFactorStatus, value: boolean) { + this.#store[key] = value; } /** * Whether authenticator app is enabled */ get authenticatorEnabled() { - return this.#store[0].totp_mfa; + return this.#store.totp_mfa; } /** * Whether recovery codes are enabled */ get recoveryEnabled() { - return this.#store[0].recovery_active; + return this.#store.recovery_active; } /** @@ -59,7 +66,7 @@ export class MFA { createTicket(params: MFAResponse) { return this.#client.api .put("/auth/mfa/ticket", params) - .then((ticket) => new MFATicket(this.#client, ticket, this.#store[1])); + .then((ticket) => new MFATicket(this.#client, ticket, this.#setStore)); } /** @@ -68,7 +75,7 @@ export class MFA { */ async enableAuthenticator(token: string) { await this.#client.api.put("/auth/mfa/totp", { totp_code: token }); - this.#store[1]("totp_mfa", true); + this.#setStore("totp_mfa", true); } } @@ -78,7 +85,7 @@ export class MFA { export class MFATicket { #client: Client; #ticket: TicketType; - #mutate: SetStoreFunction; + #mutate: (key: keyof MultiFactorStatus, value: boolean) => void; #used = false; /** @@ -90,7 +97,7 @@ export class MFATicket { constructor( client: Client, ticket: TicketType, - mutate: SetStoreFunction + mutate: (key: keyof MultiFactorStatus, value: boolean) => void, ) { this.#client = client; this.#ticket = ticket; @@ -139,7 +146,7 @@ export class MFATicket { headers: { "X-MFA-Ticket": this.token, }, - } + }, ); this.#mutate("recovery_active", true); diff --git a/src/classes/Message.ts b/src/classes/Message.ts index 76a7b38c..dec706af 100644 --- a/src/classes/Message.ts +++ b/src/classes/Message.ts @@ -1,12 +1,14 @@ import { - MessageWebhook as ApiMessageWebhook, + MessageWebhook as APIMessageWebhook, DataEditMessage, DataMessageSend, } from "revolt-api"; import { decodeTime } from "ulid"; -import { MessageCollection } from "../collections/index.js"; -import { Client, File } from "../index.js"; +import { Client } from "../Client.js"; +import { MessageCollection } from "../collections/MessageCollection.js"; + +import { File } from "./File.js"; /** * Message Class @@ -72,7 +74,7 @@ export class Message { */ get channel() { return this.#collection.client.channels.get( - this.#collection.getUnderlyingObject(this.id).channelId + this.#collection.getUnderlyingObject(this.id).channelId, ); } @@ -105,7 +107,7 @@ export class Message { */ get author() { return this.#collection.client.users.get( - this.#collection.getUnderlyingObject(this.id).authorId! + this.#collection.getUnderlyingObject(this.id).authorId!, ); } @@ -208,7 +210,9 @@ export class Message { return ( this.masquerade?.name ?? - (webhook ? webhook.name : this.member?.nickname ?? this.author?.username) + (webhook + ? webhook.name + : (this.member?.nickname ?? this.author?.username)) ); } @@ -229,7 +233,7 @@ export class Message { this.masqueradeAvatarURL ?? (webhook ? webhook.avatarURL - : this.member?.avatarURL ?? this.author?.avatarURL) + : (this.member?.avatarURL ?? this.author?.avatarURL)) ); } @@ -244,8 +248,8 @@ export class Message { (webhook ? webhook.avatarURL : this.member - ? this.member?.animatedAvatarURL - : this.author?.animatedAvatarURL) + ? this.member?.animatedAvatarURL + : this.author?.animatedAvatarURL) ); } @@ -271,7 +275,7 @@ export class Message { async edit(data: DataEditMessage) { return await this.#collection.client.api.patch( `/channels/${this.channelId as ""}/messages/${this.id as ""}`, - data + data, ); } @@ -280,7 +284,7 @@ export class Message { */ async delete() { return await this.#collection.client.api.delete( - `/channels/${this.channelId as ""}/messages/${this.id as ""}` + `/channels/${this.channelId as ""}/messages/${this.id as ""}`, ); } @@ -300,7 +304,7 @@ export class Message { | (Omit & { nonce?: string; }), - mention = true + mention = true, ) { const obj = typeof data === "string" ? { content: data } : data; return this.channel?.sendMessage({ @@ -314,7 +318,7 @@ export class Message { */ async clearReactions() { return await this.#collection.client.api.delete( - `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions` + `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions`, ); } @@ -326,7 +330,7 @@ export class Message { return await this.#collection.client.api.put( `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${ emoji as "" - }` + }`, ); } @@ -338,7 +342,7 @@ export class Message { return await this.#collection.client.api.delete( `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${ emoji as "" - }` + }`, ); } } @@ -358,7 +362,7 @@ export class MessageWebhook { * @param client Client * @param webhook Webhook data */ - constructor(client: Client, webhook: ApiMessageWebhook, id: string) { + constructor(client: Client, webhook: APIMessageWebhook, id: string) { this.#client = client; this.id = id; this.name = webhook.name; diff --git a/src/classes/MessageEmbed.ts b/src/classes/MessageEmbed.ts index f0ae016d..09bb72c6 100644 --- a/src/classes/MessageEmbed.ts +++ b/src/classes/MessageEmbed.ts @@ -1,18 +1,22 @@ -import { API, Client, File } from "../index.js"; +import { Embed, ImageSize, Special } from "revolt-api"; + +import { Client } from "../Client.js"; + +import { File } from "./File.js"; /** * Message Embed */ export abstract class MessageEmbed { protected client?: Client; - readonly type: API.Embed["type"]; + readonly type: Embed["type"]; /** * Construct Embed * @param client Client * @param type Type */ - constructor(client?: Client, type: API.Embed["type"] = "None") { + constructor(client?: Client, type: Embed["type"] = "None") { this.client = client; this.type = type; } @@ -23,7 +27,7 @@ export abstract class MessageEmbed { * @param embed Data * @returns Embed */ - static from(client: Client, embed: API.Embed): MessageEmbed { + static from(client: Client, embed: Embed): MessageEmbed { switch (embed.type) { case "Image": return new ImageEmbed(client, embed); @@ -51,17 +55,14 @@ export class ImageEmbed extends MessageEmbed { readonly url: string; readonly width: number; readonly height: number; - readonly size: API.ImageSize; + readonly size: ImageSize; /** * Construct Image Embed * @param client Client * @param embed Embed */ - constructor( - client: Client, - embed: Omit - ) { + constructor(client: Client, embed: Omit) { super(client, "Image"); this.url = embed.url; @@ -91,10 +92,7 @@ export class VideoEmbed extends MessageEmbed { * @param client Client * @param embed Embed */ - constructor( - client: Client, - embed: Omit - ) { + constructor(client: Client, embed: Omit) { super(client, "Video"); this.url = embed.url; @@ -116,7 +114,7 @@ export class VideoEmbed extends MessageEmbed { export class WebsiteEmbed extends MessageEmbed { readonly url?: string; readonly originalUrl?: string; - readonly specialContent?: API.Special; + readonly specialContent?: Special; readonly title?: string; readonly description?: string; readonly image?: ImageEmbed; @@ -132,7 +130,7 @@ export class WebsiteEmbed extends MessageEmbed { */ constructor( client: Client, - embed: Omit + embed: Omit, ) { super(client, "Website"); @@ -179,7 +177,7 @@ export class WebsiteEmbed extends MessageEmbed { return `https://open.spotify.com/embed/${this.specialContent.content_type}/${this.specialContent.id}`; case "Soundcloud": return `https://w.soundcloud.com/player/?url=${encodeURIComponent( - this.url! + this.url!, )}&color=%23FF7F50&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true`; case "Bandcamp": { return `https://bandcamp.com/EmbeddedPlayer/${this.specialContent.content_type.toLowerCase()}=${ @@ -209,10 +207,7 @@ export class TextEmbed extends MessageEmbed { * @param client Client * @param embed Embed */ - constructor( - client: Client, - embed: Omit - ) { + constructor(client: Client, embed: Omit) { super(client, "Text"); this.iconUrl = embed.icon_url!; diff --git a/src/classes/PublicBot.ts b/src/classes/PublicBot.ts index fa07542b..39f3ecc3 100644 --- a/src/classes/PublicBot.ts +++ b/src/classes/PublicBot.ts @@ -1,4 +1,10 @@ -import { API, Channel, Client, File, Server } from "../index.js"; +import { File as APIFile, PublicBot as APIPublicBot } from "revolt-api"; + +import { Client } from "../Client.js"; + +import { Channel } from "./Channel.js"; +import { File } from "./File.js"; +import { Server } from "./Server.js"; /** * Public Bot Class @@ -16,15 +22,15 @@ export class PublicBot { * @param client Client * @param data Data */ - constructor(client: Client, data: API.PublicBot) { + constructor(client: Client, data: APIPublicBot) { this.#client = client; this.id = data._id; this.username = data.username; this.avatar = data.avatar ? new File(client, { - _id: data.avatar, - tag: "avatars", - } as API.File) + _id: data.avatar, + tag: "avatars", + } as APIFile) : undefined; this.description = data.description!; } diff --git a/src/classes/PublicInvite.ts b/src/classes/PublicInvite.ts index 68444d87..d1f2b972 100644 --- a/src/classes/PublicInvite.ts +++ b/src/classes/PublicInvite.ts @@ -1,21 +1,23 @@ -import { batch } from "solid-js"; +import { Invite, InviteResponse } from "revolt-api"; +import { Client } from "../Client.js"; import { ServerFlags } from "../hydration/server.js"; -import { API, Client, File } from "../index.js"; + +import { File } from "./File.js"; /** * Public Channel Invite */ export abstract class PublicChannelInvite { protected client?: Client; - readonly type: API.Invite["type"] | "None"; + readonly type: Invite["type"] | "None"; /** * Construct Channel Invite * @param client Client * @param type Type */ - constructor(client?: Client, type: API.Invite["type"] | "None" = "None") { + constructor(client?: Client, type: Invite["type"] | "None" = "None") { this.client = client; this.type = type; } @@ -26,7 +28,7 @@ export abstract class PublicChannelInvite { * @param invite Data * @returns Invite */ - static from(client: Client, invite: API.InviteResponse): PublicChannelInvite { + static from(client: Client, invite: InviteResponse): PublicChannelInvite { switch (invite.type) { case "Server": return new ServerPublicInvite(client, invite); @@ -65,7 +67,7 @@ export class ServerPublicInvite extends PublicChannelInvite { * @param client Client * @param invite Invite */ - constructor(client: Client, invite: API.InviteResponse & { type: "Server" }) { + constructor(client: Client, invite: InviteResponse & { type: "Server" }) { super(client, "Server"); this.code = invite.code; @@ -100,17 +102,15 @@ export class ServerPublicInvite extends PublicChannelInvite { const invite = await this.client!.api.post(`/invites/${this.code as ""}`); if (invite.type === "Server") { - return batch(() => { - for (const channel of invite.channels) { - this.client!.channels.getOrCreate(channel._id, channel); - } - - return this.client!.servers.getOrCreate( - invite.server._id, - invite.server, - true - ); - }); + for (const channel of invite.channels) { + this.client!.channels.getOrCreate(channel._id, channel); + } + + return this.client!.servers.getOrCreate( + invite.server._id, + invite.server, + true, + ); } else { throw "unreachable"; } diff --git a/src/classes/Server.ts b/src/classes/Server.ts index 38f58a81..d333d9e7 100644 --- a/src/classes/Server.ts +++ b/src/classes/Server.ts @@ -1,5 +1,3 @@ -import { batch } from "solid-js"; - import type { AllMemberResponse, BannedUser, @@ -13,9 +11,8 @@ import type { } from "revolt-api"; import { decodeTime } from "ulid"; -import { ServerCollection } from "../collections/index.js"; +import { ServerCollection } from "../collections/ServerCollection.js"; import { hydrate } from "../hydration/index.js"; -import { ServerMember, User } from "../index.js"; import { bitwiseAndEq, calculatePermission, @@ -25,6 +22,8 @@ import { Permission } from "../permissions/definitions.js"; import { Channel } from "./Channel.js"; import { ChannelInvite } from "./Invite.js"; import { ServerBan } from "./ServerBan.js"; +import { ServerMember } from "./ServerMember.js"; +import { User } from "./User.js"; /** * Server Class @@ -77,7 +76,7 @@ export class Server { */ get owner() { return this.#collection.client.users.get( - this.#collection.getUnderlyingObject(this.id).ownerId + this.#collection.getUnderlyingObject(this.id).ownerId, ); } @@ -222,7 +221,7 @@ export class Server { if (uncategorised.size > 0) { const channels = [...uncategorised].map( - (key) => this.#collection.client.channels.get(key)! + (key) => this.#collection.client.channels.get(key)!, ); if (defaultCategory) { @@ -275,7 +274,7 @@ export class Server { */ get mentions() { const arr = this.channels.map((channel) => - Array.from(channel.mentions?.values() ?? []) + Array.from(channel.mentions?.values() ?? []), ); return ([] as string[]).concat(...arr); @@ -327,7 +326,7 @@ export class Server { havePermission(...permission: (keyof typeof Permission)[]) { return bitwiseAndEq( this.permission, - ...permission.map((x) => Permission[x]) + ...permission.map((x) => Permission[x]), ); } @@ -339,7 +338,7 @@ export class Server { orPermission(...permission: (keyof typeof Permission)[]) { return ( permission.findIndex((x) => - bitwiseAndEq(this.permission, Permission[x]) + bitwiseAndEq(this.permission, Permission[x]), ) !== -1 ); } @@ -364,7 +363,7 @@ export class Server { async createChannel(data: DataCreateServerChannel) { const channel = await this.#collection.client.api.post( `/servers/${this.id as ""}/channels`, - data + data, ); return this.#collection.client.channels.getOrCreate(channel._id, channel); @@ -381,11 +380,11 @@ export class Server { "server", await this.#collection.client.api.patch( `/servers/${this.id as ""}`, - data + data, ), this.#collection.client, - false - ) + false, + ), ); } @@ -394,26 +393,22 @@ export class Server { * @param leaveEvent Whether we are leaving */ $delete(leaveEvent?: boolean) { - batch(() => { - const server = this.#collection.client.servers.getUnderlyingObject( - this.id - ); + const server = this.#collection.client.servers.getUnderlyingObject(this.id); - // Avoid race conditions - if (server.id) { - this.#collection.client.emit( - leaveEvent ? "serverLeave" : "serverDelete", - server - ); - - for (const channel of this.channelIds) { - this.#collection.client.channels.delete(channel); - } + // Avoid race conditions + if (server.id) { + this.#collection.client.emit( + leaveEvent ? "serverLeave" : "serverDelete", + server, + ); - this.#collection.delete(this.id); + for (const channel of this.channelIds) { + this.#collection.client.channels.delete(channel); } - // TODO: delete members, emoji, etc - }); + + this.#collection.delete(this.id); + } + // TODO: delete members, emoji, etc } /** @@ -432,11 +427,9 @@ export class Server { * Mark a server as read */ async ack() { - batch(() => { - for (const channel of this.channels) { - channel.ack(undefined, false, true); - } - }); + for (const channel of this.channels) { + channel.ack(undefined, false, true); + } await this.#collection.client.api.put(`/servers/${this.id}/ack`); } @@ -448,18 +441,18 @@ export class Server { */ async banUser( user: string | User | ServerMember, - options: DataBanCreate = {} + options: DataBanCreate = {}, ) { const userId = user instanceof User ? user.id : user instanceof ServerMember - ? user.id.user - : user; + ? user.id.user + : user; const ban = await this.#collection.client.api.put( `/servers/${this.id as ""}/bans/${userId as ""}`, - options + options, ); return new ServerBan(this.#collection.client, ban); @@ -475,9 +468,9 @@ export class Server { typeof user === "string" ? user : user instanceof User - ? user.id - : user.id.user - }` + ? user.id + : user.id.user + }`, ); } @@ -488,7 +481,7 @@ export class Server { async unbanUser(user: string | User) { const userId = user instanceof User ? user.id : user; return await this.#collection.client.api.delete( - `/servers/${this.id as ""}/bans/${userId}` + `/servers/${this.id as ""}/bans/${userId}`, ); } @@ -498,11 +491,11 @@ export class Server { */ async fetchInvites() { const invites = await this.#collection.client.api.get( - `/servers/${this.id as ""}/invites` + `/servers/${this.id as ""}/invites`, ); return invites.map((invite) => - ChannelInvite.from(this.#collection.client, invite) + ChannelInvite.from(this.#collection.client, invite), ); } @@ -512,17 +505,17 @@ export class Server { */ async fetchBans() { const { users, bans } = await this.#collection.client.api.get( - `/servers/${this.id as ""}/bans` + `/servers/${this.id as ""}/bans`, ); const userDict = users.reduce( (d, c) => ({ ...d, [c._id]: c }), - {} as Record + {} as Record, ); return bans.map( (ban) => - new ServerBan(this.#collection.client, ban, userDict[ban._id.user]) + new ServerBan(this.#collection.client, ban, userDict[ban._id.user]), ); } @@ -534,7 +527,7 @@ export class Server { async setPermissions(roleId = "default", permissions: Override | number) { return await this.#collection.client.api.put( `/servers/${this.id as ""}/permissions/${roleId as ""}`, - { permissions: permissions as Override } + { permissions: permissions as Override }, ); } @@ -547,7 +540,7 @@ export class Server { `/servers/${this.id as ""}/roles`, { name, - } + }, ); } @@ -559,7 +552,7 @@ export class Server { async editRole(roleId: string, data: DataEditRole) { return await this.#collection.client.api.patch( `/servers/${this.id as ""}/roles/${roleId as ""}`, - data + data, ); } @@ -569,7 +562,7 @@ export class Server { */ async deleteRole(roleId: string) { return await this.#collection.client.api.delete( - `/servers/${this.id as ""}/roles/${roleId as ""}` + `/servers/${this.id as ""}/roles/${roleId as ""}`, ); } @@ -600,34 +593,32 @@ export class Server { const data = await this.#collection.client.api.get( `/servers/${this.id as ""}/members`, - { exclude_offline: excludeOffline } + { exclude_offline: excludeOffline }, ); - batch(() => { - if (excludeOffline) { - for (let i = 0; i < data.users.length; i++) { - const user = data.users[i]; - if (user.online) { - this.#collection.client.users.getOrCreate(user._id, user); - this.#collection.client.serverMembers.getOrCreate( - data.members[i]._id, - data.members[i] - ); - } - } - } else { - for (let i = 0; i < data.users.length; i++) { - this.#collection.client.users.getOrCreate( - data.users[i]._id, - data.users[i] - ); + if (excludeOffline) { + for (let i = 0; i < data.users.length; i++) { + const user = data.users[i]; + if (user.online) { + this.#collection.client.users.getOrCreate(user._id, user); this.#collection.client.serverMembers.getOrCreate( data.members[i]._id, - data.members[i] + data.members[i], ); } } - }); + } else { + for (let i = 0; i < data.users.length; i++) { + this.#collection.client.users.getOrCreate( + data.users[i]._id, + data.users[i], + ); + this.#collection.client.serverMembers.getOrCreate( + data.members[i]._id, + data.members[i], + ); + } + } } /** @@ -644,17 +635,17 @@ export class Server { async fetchMembers() { const data = (await this.#collection.client.api.get( // @ts-expect-error TODO weird typing issue - `/servers/${this.id as ""}/members` + `/servers/${this.id as ""}/members`, )) as AllMemberResponse; - return batch(() => ({ + return { members: data.members.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member) + this.#collection.client.serverMembers.getOrCreate(member._id, member), ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user) + this.#collection.client.users.getOrCreate(user._id, user), ), - })); + }; } /** @@ -667,18 +658,18 @@ export class Server { `/servers/${ this.id as "" }/members_experimental_query?experimental_api=true&query=${encodeURIComponent( - query - )}` as never + query, + )}` as never, )) as AllMemberResponse; - return batch(() => ({ + return { members: data.members.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member) + this.#collection.client.serverMembers.getOrCreate(member._id, member), ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user) + this.#collection.client.users.getOrCreate(user._id, user), ), - })); + }; } /** @@ -688,7 +679,7 @@ export class Server { */ async createEmoji( autumnId: string, - options: Omit + options: Omit, ) { const emoji = await this.#collection.client.api.put( `/custom/emoji/${autumnId as ""}`, @@ -698,7 +689,7 @@ export class Server { id: this.id, }, ...options, - } + }, ); return this.#collection.client.emojis.getOrCreate(emoji._id, emoji, true); @@ -710,13 +701,11 @@ export class Server { */ async fetchEmojis() { const emojis = await this.#collection.client.api.get( - `/servers/${this.id as ""}/emojis` + `/servers/${this.id as ""}/emojis`, ); - return batch(() => - emojis.map((emoji) => - this.#collection.client.emojis.getOrCreate(emoji._id, emoji) - ) + return emojis.map((emoji) => + this.#collection.client.emojis.getOrCreate(emoji._id, emoji), ); } diff --git a/src/classes/ServerBan.ts b/src/classes/ServerBan.ts index 2d20307b..a2909b35 100644 --- a/src/classes/ServerBan.ts +++ b/src/classes/ServerBan.ts @@ -1,10 +1,12 @@ import { - BannedUser as ApiBannedUser, - ServerBan as ApiServerBan, + BannedUser as APIBannedUser, + ServerBan as APIServerBan, MemberCompositeKey, } from "revolt-api"; -import { BannedUser, Client } from "../index.js"; +import { Client } from "../Client.js"; + +import { BannedUser } from "./BannedUser.js"; /** * Server Ban @@ -20,7 +22,7 @@ export class ServerBan { * @param client Client * @param data Data */ - constructor(client: Client, data: ApiServerBan, user?: ApiBannedUser) { + constructor(client: Client, data: APIServerBan, user?: APIBannedUser) { this.client = client; this.id = data._id; this.reason = data.reason!; @@ -39,7 +41,7 @@ export class ServerBan { */ async pardon() { await this.client.api.delete( - `/servers/${this.id.server as ""}/bans/${this.id.user as ""}` + `/servers/${this.id.server as ""}/bans/${this.id.user as ""}`, ); } } diff --git a/src/classes/ServerMember.ts b/src/classes/ServerMember.ts index d408061f..78711838 100644 --- a/src/classes/ServerMember.ts +++ b/src/classes/ServerMember.ts @@ -4,7 +4,7 @@ import type { MemberCompositeKey, } from "revolt-api"; -import { ServerMemberCollection } from "../collections/index.js"; +import { ServerMemberCollection } from "../collections/ServerMemberCollection.js"; import { bitwiseAndEq, calculatePermission, @@ -183,7 +183,7 @@ export class ServerMember { ) { return bitwiseAndEq( this.getPermissions(target), - ...permission.map((x) => Permission[x]) + ...permission.map((x) => Permission[x]), ); } @@ -224,7 +224,7 @@ export class ServerMember { async edit(data: DataMemberEdit) { await this.#collection.client.api.patch( `/servers/${this.id.server as ""}/members/${this.id.user as ""}`, - data + data, ); } diff --git a/src/classes/Session.ts b/src/classes/Session.ts index d0952ba1..305cea3c 100644 --- a/src/classes/Session.ts +++ b/src/classes/Session.ts @@ -1,6 +1,6 @@ import { decodeTime } from "ulid"; -import { SessionCollection } from "../collections/index.js"; +import { SessionCollection } from "../collections/SessionCollection.js"; /** * Session Class @@ -64,7 +64,7 @@ export class Session { friendly_name: name, }); - this.#collection.updateUnderlyingObject(this.id, "name", name); + this.#collection.setKeyUnderlyingObject(this.id, "name", name); } /** diff --git a/src/classes/SystemMessage.ts b/src/classes/SystemMessage.ts index 7e8b04e0..1afc8c5d 100644 --- a/src/classes/SystemMessage.ts +++ b/src/classes/SystemMessage.ts @@ -1,18 +1,20 @@ -import { API, Client } from "../index.js"; +import { SystemMessage as APISystemMessage } from "revolt-api"; + +import { Client } from "../Client.js"; /** * System Message */ export abstract class SystemMessage { protected client?: Client; - readonly type: API.SystemMessage["type"]; + readonly type: APISystemMessage["type"]; /** * Construct System Message * @param client Client * @param type Type */ - constructor(client: Client, type: API.SystemMessage["type"]) { + constructor(client: Client, type: APISystemMessage["type"]) { this.client = client; this.type = type; } @@ -23,7 +25,7 @@ export abstract class SystemMessage { * @param embed Data * @returns System Message */ - static from(client: Client, message: API.SystemMessage): SystemMessage { + static from(client: Client, message: APISystemMessage): SystemMessage { switch (message.type) { case "text": return new TextSystemMessage(client, message); @@ -64,7 +66,7 @@ export class TextSystemMessage extends SystemMessage { */ constructor( client: Client, - systemMessage: API.SystemMessage & { type: "text" } + systemMessage: APISystemMessage & { type: "text" }, ) { super(client, systemMessage.type); this.content = systemMessage.content; @@ -84,7 +86,7 @@ export class UserSystemMessage extends SystemMessage { */ constructor( client: Client, - systemMessage: API.SystemMessage & { + systemMessage: APISystemMessage & { type: | "user_added" | "user_remove" @@ -92,7 +94,7 @@ export class UserSystemMessage extends SystemMessage { | "user_left" | "user_kicked" | "user_banned"; - } + }, ) { super(client, systemMessage.type); this.userId = systemMessage.id; @@ -119,9 +121,9 @@ export class UserModeratedSystemMessage extends UserSystemMessage { */ constructor( client: Client, - systemMessage: API.SystemMessage & { + systemMessage: APISystemMessage & { type: "user_added" | "user_remove"; - } + }, ) { super(client, systemMessage); this.byId = systemMessage.by; @@ -149,12 +151,12 @@ export class ChannelEditSystemMessage extends SystemMessage { */ constructor( client: Client, - systemMessage: API.SystemMessage & { + systemMessage: APISystemMessage & { type: | "channel_renamed" | "channel_description_changed" | "channel_icon_changed"; - } + }, ) { super(client, systemMessage.type); this.byId = systemMessage.by; @@ -181,9 +183,9 @@ export class ChannelRenamedSystemMessage extends ChannelEditSystemMessage { */ constructor( client: Client, - systemMessage: API.SystemMessage & { + systemMessage: APISystemMessage & { type: "channel_renamed"; - } + }, ) { super(client, systemMessage); this.name = systemMessage.name; @@ -204,9 +206,9 @@ export class ChannelOwnershipChangeSystemMessage extends SystemMessage { */ constructor( client: Client, - systemMessage: API.SystemMessage & { + systemMessage: APISystemMessage & { type: "channel_ownership_changed"; - } + }, ) { super(client, systemMessage.type); this.fromId = systemMessage.from; diff --git a/src/classes/User.ts b/src/classes/User.ts index b664c910..17d64b2a 100644 --- a/src/classes/User.ts +++ b/src/classes/User.ts @@ -1,10 +1,11 @@ import { DataEditUser, Presence } from "revolt-api"; import { decodeTime } from "ulid"; -import { UserCollection } from "../collections/index.js"; -import { UserProfile } from "../index.js"; +import { UserCollection } from "../collections/UserCollection.js"; import { U32_MAX, UserPermission } from "../permissions/definitions.js"; +import { UserProfile } from "./UserProfile.js"; + /** * User Class */ @@ -87,8 +88,9 @@ export class User { */ get status() { // TODO: issue with API, upstream fix required #319 - if (!this.online) + if (!this.online) { return { text: undefined, presence: "Invisible" as const }; + } return this.#collection.getUnderlyingObject(this.id).status; } @@ -138,9 +140,7 @@ export class User { * URL to the user's default avatar */ get defaultAvatarURL() { - return `${this.#collection.client.options.baseURL}/users/${ - this.id - }/default_avatar`; + return `${this.#collection.client.options.baseURL}/users/${this.id}/default_avatar`; } /** @@ -161,7 +161,7 @@ export class User { * Presence */ get presence() { - return this.online ? this.status?.presence ?? "Online" : "Invisible"; + return this.online ? (this.status?.presence ?? "Online") : "Invisible"; } /** @@ -171,8 +171,8 @@ export class User { */ statusMessage(translate: (presence: Presence) => string = (a) => a) { return this.online - ? this.status?.text ?? - (this.presence === "Focus" ? translate("Focus") : undefined) + ? (this.status?.text ?? + (this.presence === "Focus" ? translate("Focus") : undefined)) : undefined; } @@ -197,10 +197,10 @@ export class User { this.#collection.client.channels.find( (channel) => (channel.type === "Group" || channel.type === "DirectMessage") && - channel.recipientIds.has(this.id) + channel.recipientIds.has(this.id), ) || this.#collection.client.serverMembers.find( - (member) => member.id.user === this.id + (member) => member.id.user === this.id, ) ) { if (this.#collection.client.user?.bot || this.bot) { @@ -222,7 +222,7 @@ export class User { `/users/${ this.id === this.#collection.client.user?.id ? "@me" : this.id }`, - data + data, ); } @@ -244,20 +244,20 @@ export class User { */ async openDM() { let dm = [...this.#collection.client.channels.values()].find( - (x) => x.type === "DirectMessage" && x.recipient == this + (x) => x.type === "DirectMessage" && x.recipient == this, ); if (dm) { if (!dm.active) { - this.#collection.client.channels.updateUnderlyingObject( + this.#collection.client.channels.setKeyUnderlyingObject( dm.id, "active", - true + true, ); } } else { const data = await this.#collection.client.api.get( - `/users/${this.id as ""}/dm` + `/users/${this.id as ""}/dm`, ); dm = this.#collection.client.channels.getOrCreate(data._id, data)!; @@ -305,7 +305,7 @@ export class User { async fetchProfile() { return new UserProfile( this.#collection.client, - await this.#collection.client.api.get(`/users/${this.id as ""}/profile`) + await this.#collection.client.api.get(`/users/${this.id as ""}/profile`), ); } @@ -315,7 +315,7 @@ export class User { */ async fetchMutual() { return await this.#collection.client.api.get( - `/users/${this.id as ""}/mutual` + `/users/${this.id as ""}/mutual`, ); } } diff --git a/src/classes/UserProfile.ts b/src/classes/UserProfile.ts index a2e10b7e..7ff5e7f3 100644 --- a/src/classes/UserProfile.ts +++ b/src/classes/UserProfile.ts @@ -1,4 +1,8 @@ -import { API, Client, File } from "../index.js"; +import { UserProfile as APIUserProfile } from "revolt-api"; + +import { Client } from "../Client.js"; + +import { File } from "./File.js"; /** * User Profile Class @@ -12,7 +16,7 @@ export class UserProfile { * @param client Client * @param data Data */ - constructor(client: Client, data: API.UserProfile) { + constructor(client: Client, data: APIUserProfile) { this.content = data.content!; this.banner = data.background ? new File(client, data.background) diff --git a/src/collections/AccountCollection.ts b/src/collections/AccountCollection.ts index bcdcd8f2..e2a1547f 100644 --- a/src/collections/AccountCollection.ts +++ b/src/collections/AccountCollection.ts @@ -1,7 +1,7 @@ import { DataCreateAccount, WebPushSubscription } from "revolt-api"; +import { Client } from "../Client.js"; import { MFA } from "../classes/MFA.js"; -import { Client } from "../index.js"; /** * Utility functions for working with accounts @@ -89,7 +89,7 @@ export class AccountCollection { confirmPasswordReset( token: string, newPassword: string, - removeSessions: boolean + removeSessions: boolean, ) { return this.client.api.patch("/auth/account/reset_password", { token, diff --git a/src/collections/BotCollection.ts b/src/collections/BotCollection.ts index 03296b18..db1852fa 100644 --- a/src/collections/BotCollection.ts +++ b/src/collections/BotCollection.ts @@ -1,11 +1,10 @@ -import { batch } from "solid-js"; - -import { OwnedBotsResponse } from "revolt-api"; +import { Bot as APIBot, OwnedBotsResponse } from "revolt-api"; +import { Bot } from "../classes/Bot.js"; +import { PublicBot } from "../classes/PublicBot.js"; import { HydratedBot } from "../hydration/bot.js"; -import { API, Bot, PublicBot } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { ClassCollection } from "./Collection.js"; /** * Collection of Bots @@ -30,12 +29,8 @@ export class BotCollection extends ClassCollection { */ async fetchOwned(): Promise { const data = (await this.client.api.get("/bots/@me")) as OwnedBotsResponse; - return batch(() => { - data.users.forEach((user) => - this.client.users.getOrCreate(user._id, user) - ); - return data.bots.map((bot) => this.getOrCreate(bot._id, bot)); - }); + data.users.forEach((user) => this.client.users.getOrCreate(user._id, user)); + return data.bots.map((bot) => this.getOrCreate(bot._id, bot)); } /** @@ -54,7 +49,7 @@ export class BotCollection extends ClassCollection { * @param data Data * @returns Bot */ - getOrCreate(id: string, data: API.Bot) { + getOrCreate(id: string, data: APIBot) { if (this.has(id)) { return this.get(id)!; } else { diff --git a/src/collections/ChannelCollection.ts b/src/collections/ChannelCollection.ts index 9d4c6d57..9f04b344 100644 --- a/src/collections/ChannelCollection.ts +++ b/src/collections/ChannelCollection.ts @@ -1,7 +1,10 @@ -import { HydratedChannel } from "../hydration/index.js"; -import { API, Channel, User } from "../index.js"; +import { Channel as APIChannel } from "revolt-api"; -import { ClassCollection } from "./index.js"; +import { Channel } from "../classes/Channel.js"; +import { User } from "../classes/User.js"; +import { HydratedChannel } from "../hydration/channel.js"; + +import { ClassCollection } from "./Collection.js"; /** * Collection of Channels @@ -38,13 +41,13 @@ export class ChannelCollection extends ClassCollection< * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: API.Channel, isNew = false) { + getOrCreate(id: string, data: APIChannel, isNew = false) { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { const instance = new Channel(this, id); this.create(id, "channel", instance, this.client, data); - isNew && this.client.emit("channelCreate", instance); + if (isNew) this.client.emit("channelCreate", instance); return instance; } } diff --git a/src/collections/ChannelUnreadCollection.ts b/src/collections/ChannelUnreadCollection.ts index 7615b65d..72218e7e 100644 --- a/src/collections/ChannelUnreadCollection.ts +++ b/src/collections/ChannelUnreadCollection.ts @@ -1,10 +1,9 @@ -import { batch } from "solid-js"; +import { ChannelUnread as APIChannelUnread } from "revolt-api"; import { ChannelUnread } from "../classes/ChannelUnread.js"; -import { HydratedChannelUnread } from "../hydration/index.js"; -import { API } from "../index.js"; +import { HydratedChannelUnread } from "../hydration/channelUnread.js"; -import { ClassCollection } from "./index.js"; +import { ClassCollection } from "./Collection.js"; /** * Collection of Channel Unreads @@ -18,19 +17,19 @@ export class ChannelUnreadCollection extends ClassCollection< */ async sync() { const unreads = await this.client.api.get("/sync/unreads"); - batch(() => { - this.reset(); - for (const unread of unreads) { - this.getOrCreate(unread._id.channel, unread); - } - }); + this.reset(); + for (const unread of unreads) { + this.getOrCreate(unread._id.channel, unread); + } } /** * Clear all unread data */ reset() { - this.updateUnderlyingObject({}); + for (const key of this.keys()) { + this.updateUnderlyingObject(key, {} as never); + } } /** @@ -38,7 +37,7 @@ export class ChannelUnreadCollection extends ClassCollection< * @param id Id * @param data Data */ - getOrCreate(id: string, data: API.ChannelUnread) { + getOrCreate(id: string, data: APIChannelUnread) { if (this.has(id)) { return this.get(id)!; } else { diff --git a/src/collections/ChannelWebhookCollection.ts b/src/collections/ChannelWebhookCollection.ts index 2c49ee7f..5c16fcb8 100644 --- a/src/collections/ChannelWebhookCollection.ts +++ b/src/collections/ChannelWebhookCollection.ts @@ -1,8 +1,9 @@ +import { Webhook } from "revolt-api"; + import { ChannelWebhook } from "../classes/ChannelWebhook.js"; import { HydratedChannelWebhook } from "../hydration/channelWebhook.js"; -import { API } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { ClassCollection } from "./Collection.js"; /** * Collection of Channel Webhooks @@ -22,7 +23,7 @@ export class ChannelWebhookCollection extends ClassCollection< // @ts-expect-error not in prod const data = await this.client.api.get(`/webhooks/${id as ""}`); // @ts-expect-error not in prod - return this.getOrCreate(data.id, data as API.Webhook); + return this.getOrCreate(data.id, data as Webhook); } /** @@ -36,7 +37,7 @@ export class ChannelWebhookCollection extends ClassCollection< if (webhook) return webhook; const data = await this.client.api.get( // @ts-expect-error not in prod - `/webhooks/${id as ""}/${token as ""}` + `/webhooks/${id as ""}/${token as ""}`, ); // @ts-expect-error not in prod return this.getOrCreate(data.id, data); @@ -47,7 +48,7 @@ export class ChannelWebhookCollection extends ClassCollection< * @param id Id * @param data Data */ - getOrCreate(id: string, data: API.Webhook) { + getOrCreate(id: string, data: Webhook) { if (this.has(id)) { return this.get(id)!; } else { diff --git a/src/collections/Collection.ts b/src/collections/Collection.ts index 83808f4e..3aaf1a56 100644 --- a/src/collections/Collection.ts +++ b/src/collections/Collection.ts @@ -1,9 +1,5 @@ -import { SetStoreFunction } from "solid-js/store"; - -import { ReactiveMap } from "@solid-primitives/map"; - +import { Client } from "../Client.js"; import { Hydrators } from "../hydration/index.js"; -import { Client } from "../index.js"; import { ObjectStorage } from "../storage/ObjectStorage.js"; /** @@ -59,7 +55,7 @@ export abstract class Collection { * @param cb Callback for each pair */ abstract forEach( - cb: (value: T, key: string, map: ReactiveMap) => void + cb: (value: T, key: string, map: Map) => void, ): void; /** @@ -116,9 +112,14 @@ export abstract class Collection { */ export abstract class StoreCollection extends Collection { #storage = new ObjectStorage(); - #objects = new ReactiveMap(); + #objects = new Map(); readonly getUnderlyingObject: (id: string) => V; - readonly updateUnderlyingObject: SetStoreFunction>; + readonly setKeyUnderlyingObject: ( + id: string, + key: K, + value: V[K], + ) => void; + readonly updateUnderlyingObject: (id: string, value: V) => void; /** * Construct store backed collection @@ -126,6 +127,12 @@ export abstract class StoreCollection extends Collection { constructor() { super(); this.getUnderlyingObject = (key) => this.#storage.get(key) ?? ({} as V); + this.setKeyUnderlyingObject = (id, key, value) => { + this.#storage.set(id, { + [key]: value, + ...this.getUnderlyingObject(id), + }); + }; this.updateUnderlyingObject = this.#storage.set; } @@ -169,7 +176,7 @@ export abstract class StoreCollection extends Collection { type: keyof Hydrators, instance: T, context: unknown, - data?: unknown + data?: unknown, ) { this.#storage.hydrate(id, type, context, data); this.#objects.set(id, instance); @@ -221,7 +228,7 @@ export abstract class StoreCollection extends Collection { * @param cb Callback for each pair * @returns Iterable */ - forEach(cb: (value: T, key: string, map: ReactiveMap) => void) { + forEach(cb: (value: T, key: string, map: Map) => void) { return this.#objects.forEach(cb); } } diff --git a/src/collections/EmojiCollection.ts b/src/collections/EmojiCollection.ts index 86f6efbb..f270097a 100644 --- a/src/collections/EmojiCollection.ts +++ b/src/collections/EmojiCollection.ts @@ -1,7 +1,9 @@ -import { HydratedEmoji } from "../hydration/index.js"; -import { API, Emoji } from "../index.js"; +import { Emoji as APIEmoji } from "revolt-api"; -import { ClassCollection } from "./index.js"; +import { Emoji } from "../classes/Emoji.js"; +import { HydratedEmoji } from "../hydration/emoji.js"; + +import { ClassCollection } from "./Collection.js"; /** * Collection of Emoji @@ -25,13 +27,13 @@ export class EmojiCollection extends ClassCollection { * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: API.Emoji, isNew = false) { + getOrCreate(id: string, data: APIEmoji, isNew = false) { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { const instance = new Emoji(this, id); this.create(id, "emoji", instance, this.client, data); - isNew && this.client.emit("emojiCreate", instance); + if (isNew) this.client.emit("emojiCreate", instance); return instance; } } diff --git a/src/collections/MessageCollection.ts b/src/collections/MessageCollection.ts index 7bb9975c..759193b0 100644 --- a/src/collections/MessageCollection.ts +++ b/src/collections/MessageCollection.ts @@ -1,7 +1,9 @@ -import { HydratedMessage } from "../hydration"; -import { API, Message } from "../index.js"; +import { Message as APIMessage } from "revolt-api"; -import { ClassCollection } from "./index.js"; +import { Message } from "../classes/Message.js"; +import { HydratedMessage } from "../hydration/message.js"; + +import { ClassCollection } from "./Collection.js"; /** * Collection of Messages @@ -21,7 +23,7 @@ export class MessageCollection extends ClassCollection< if (message && !this.isPartial(messageId)) return message; const data = await this.client.api.get( - `/channels/${channelId as ""}/messages/${messageId as ""}` + `/channels/${channelId as ""}/messages/${messageId as ""}`, ); return this.getOrCreate(data._id, data, false); @@ -33,13 +35,13 @@ export class MessageCollection extends ClassCollection< * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: API.Message, isNew = false) { + getOrCreate(id: string, data: APIMessage, isNew = false) { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { const instance = new Message(this, id); this.create(id, "message", instance, this.client, data); - isNew && this.client.emit("messageCreate", instance); + if (isNew) this.client.emit("messageCreate", instance); return instance; } } diff --git a/src/collections/ServerCollection.ts b/src/collections/ServerCollection.ts index 1496902c..06c2bb1a 100644 --- a/src/collections/ServerCollection.ts +++ b/src/collections/ServerCollection.ts @@ -1,11 +1,9 @@ -import { batch } from "solid-js"; +import { Server as APIServer, Channel, DataCreateServer } from "revolt-api"; -import { DataCreateServer } from "revolt-api"; +import { Server } from "../classes/Server.js"; +import { HydratedServer } from "../hydration/server.js"; -import { HydratedServer } from "../hydration/index.js"; -import { API, Server } from "../index.js"; - -import { ClassCollection } from "./index.js"; +import { ClassCollection } from "./Collection.js"; /** * Collection of Servers @@ -25,15 +23,13 @@ export class ServerCollection extends ClassCollection { include_channels: true, }); - return batch(() => { - for (const channel of data.channels as unknown as API.Channel[]) { - if (typeof channel !== "string") { - this.client.channels.getOrCreate(channel._id, channel); - } + for (const channel of data.channels as unknown as Channel[]) { + if (typeof channel !== "string") { + this.client.channels.getOrCreate(channel._id, channel); } + } - return this.getOrCreate(data._id, data); - }); + return this.getOrCreate(data._id, data); } /** @@ -42,13 +38,13 @@ export class ServerCollection extends ClassCollection { * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: API.Server, isNew = false) { + getOrCreate(id: string, data: APIServer, isNew = false) { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { const instance = new Server(this, id); this.create(id, "server", instance, this.client, data); - isNew && this.client.emit("serverCreate", instance); + if (isNew) this.client.emit("serverCreate", instance); return instance; } } @@ -78,15 +74,13 @@ export class ServerCollection extends ClassCollection { async createServer(data: DataCreateServer) { const { server, channels } = await this.client.api.post( `/servers/create`, - data + data, ); - return batch(() => { - for (const channel of channels) { - this.client.channels.getOrCreate(channel._id, channel); - } + for (const channel of channels) { + this.client.channels.getOrCreate(channel._id, channel); + } - return this.getOrCreate(server._id, server, true); - }); + return this.getOrCreate(server._id, server, true); } } diff --git a/src/collections/ServerMemberCollection.ts b/src/collections/ServerMemberCollection.ts index 7461d15e..822cc3f8 100644 --- a/src/collections/ServerMemberCollection.ts +++ b/src/collections/ServerMemberCollection.ts @@ -1,7 +1,9 @@ -import { HydratedServerMember } from "../hydration/index.js"; -import { API, ServerMember } from "../index.js"; +import { Member, MemberCompositeKey } from "revolt-api"; -import { ClassCollection } from "./index.js"; +import { ServerMember } from "../classes/ServerMember.js"; +import { HydratedServerMember } from "../hydration/serverMember.js"; + +import { ClassCollection } from "./Collection.js"; /** * Collection of Server Members @@ -15,7 +17,7 @@ export class ServerMemberCollection extends ClassCollection< * @param id Id * @returns Whether it exists */ - hasByKey(id: API.MemberCompositeKey) { + hasByKey(id: MemberCompositeKey) { return super.has(id.server + id.user); } @@ -24,7 +26,7 @@ export class ServerMemberCollection extends ClassCollection< * @param id Id * @returns Member */ - getByKey(id: API.MemberCompositeKey) { + getByKey(id: MemberCompositeKey) { return super.get(id.server + id.user); } @@ -33,7 +35,7 @@ export class ServerMemberCollection extends ClassCollection< * @param id Id * @returns Member */ - isPartialByKey(id: API.MemberCompositeKey) { + isPartialByKey(id: MemberCompositeKey) { return super.isPartial(id.server + id.user); } @@ -51,9 +53,9 @@ export class ServerMemberCollection extends ClassCollection< `/servers/${serverId as ""}/members/${userId as ""}`, { roles: false, - } + }, // TODO: fix typings in revolt-api - )) as API.Member; + )) as Member; return this.getOrCreate(data._id, data); } @@ -63,7 +65,7 @@ export class ServerMemberCollection extends ClassCollection< * @param id Id * @param data Data */ - getOrCreate(id: API.MemberCompositeKey, data: API.Member) { + getOrCreate(id: MemberCompositeKey, data: Member): ServerMember { if (this.hasByKey(id) && !this.isPartialByKey(id)) { return this.getByKey(id)!; } else { @@ -73,7 +75,7 @@ export class ServerMemberCollection extends ClassCollection< "serverMember", instance, this.client, - data + data, ); return instance; } @@ -83,7 +85,7 @@ export class ServerMemberCollection extends ClassCollection< * Get or return partial * @param id Id */ - getOrPartial(id: API.MemberCompositeKey) { + getOrPartial(id: MemberCompositeKey): ServerMember | undefined { if (this.hasByKey(id)) { return this.getByKey(id)!; } else if (this.client.options.partials) { diff --git a/src/collections/SessionCollection.ts b/src/collections/SessionCollection.ts index 60e04b91..69f16eda 100644 --- a/src/collections/SessionCollection.ts +++ b/src/collections/SessionCollection.ts @@ -1,10 +1,9 @@ -import { batch } from "solid-js"; +import { SessionInfo } from "revolt-api"; -import { Session } from "../classes/index.js"; +import { Session } from "../classes/Session.js"; import { HydratedSession } from "../hydration/session.js"; -import { API } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { ClassCollection } from "./Collection.js"; /** * Collection of Sessions @@ -19,9 +18,7 @@ export class SessionCollection extends ClassCollection< */ async fetch(): Promise { const data = await this.client.api.get("/auth/session/all"); - return batch(() => - data.map((session) => this.getOrCreate(session._id, session)) - ); + return data.map((session) => this.getOrCreate(session._id, session)); } /** @@ -45,7 +42,7 @@ export class SessionCollection extends ClassCollection< * @param data Data * @returns Session */ - getOrCreate(id: string, data: API.SessionInfo) { + getOrCreate(id: string, data: SessionInfo) { if (this.has(id)) { return this.get(id)!; } else { diff --git a/src/collections/UserCollection.ts b/src/collections/UserCollection.ts index a052eab2..6597b115 100644 --- a/src/collections/UserCollection.ts +++ b/src/collections/UserCollection.ts @@ -1,7 +1,10 @@ -import { HydratedUser } from "../hydration/index.js"; -import { API, Client, User } from "../index.js"; +import { User as APIUser } from "revolt-api"; -import { ClassCollection } from "./index.js"; +import { Client } from "../Client.js"; +import { User } from "../classes/User.js"; +import { HydratedUser } from "../hydration/user.js"; + +import { ClassCollection } from "./Collection.js"; /** * Collection of Users @@ -41,7 +44,7 @@ export class UserCollection extends ClassCollection { * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: API.User) { + getOrCreate(id: string, data: APIUser) { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { diff --git a/src/events/EventClient.ts b/src/events/EventClient.ts index f3cbb887..fb5f38a9 100644 --- a/src/events/EventClient.ts +++ b/src/events/EventClient.ts @@ -1,10 +1,24 @@ -import { Accessor, Setter, createSignal } from "solid-js"; - import EventEmitter from "eventemitter3"; -import WebSocket from "isomorphic-ws"; import { Error } from "revolt-api"; -import type { AvailableProtocols, EventProtocol } from "./index.js"; +import { ProtocolV1 } from "./v1.js"; + +/** + * Available protocols to connect with + */ +export type AvailableProtocols = 1; + +/** + * Protocol mapping + */ +type Protocols = { + 1: ProtocolV1; +}; + +/** + * Select a protocol by its key + */ +export type EventProtocol = Protocols[T]; /** * All possible event client states. @@ -65,19 +79,16 @@ export class EventClient extends EventEmitter< #protocolVersion: T; #transportFormat: "json" | "msgpack"; - readonly ping: Accessor; - #setPing: Setter; - - readonly state: Accessor; - #setStateSetter: Setter; + ping = -1; + state = ConnectionState.Idle; #socket: WebSocket | undefined; #heartbeatIntervalReference: number | undefined; #pongTimeoutReference: number | undefined; #connectTimeoutReference: number | undefined; - #lastError: // eslint-disable-next-line @typescript-eslint/no-explicit-any - { type: "socket"; data: any } | { type: "revolt"; data: Error } | undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + #lastError?: { type: "socket"; data: any } | { type: "revolt"; data: Error }; /** * Create a new event client. @@ -88,7 +99,7 @@ export class EventClient extends EventEmitter< constructor( protocolVersion: T, transportFormat: "json" = "json", - options?: Partial + options?: Partial, ) { super(); @@ -103,14 +114,6 @@ export class EventClient extends EventEmitter< ...options, }; - const [state, setState] = createSignal(ConnectionState.Idle); - this.state = state; - this.#setStateSetter = setState; - - const [ping, setPing] = createSignal(-1); - this.ping = ping; - this.#setPing = setPing; - this.disconnect = this.disconnect.bind(this); } @@ -119,7 +122,7 @@ export class EventClient extends EventEmitter< * @param state state */ private setState(state: ConnectionState) { - this.#setStateSetter(state); + this.state = state; this.emit("state", state); } @@ -135,13 +138,11 @@ export class EventClient extends EventEmitter< this.#connectTimeoutReference = setTimeout( () => this.disconnect(), - this.options.pongTimeout * 1e3 + this.options.pongTimeout * 1e3, ) as never; this.#socket = new WebSocket( - `${uri}?version=${this.#protocolVersion}&format=${ - this.#transportFormat - }&token=${token}` + `${uri}?version=${this.#protocolVersion}&format=${this.#transportFormat}&token=${token}`, ); this.#socket.onopen = () => { @@ -149,7 +150,7 @@ export class EventClient extends EventEmitter< this.send({ type: "Ping", data: +new Date() }); this.#pongTimeoutReference = setTimeout( () => this.disconnect(), - this.options.pongTimeout * 1e3 + this.options.pongTimeout * 1e3, ) as never; }, this.options.heartbeatInterval * 1e3) as never; }; @@ -197,7 +198,7 @@ export class EventClient extends EventEmitter< * @param event Event */ send(event: EventProtocol["client"]) { - this.options.debug && console.debug("[C->S]", event); + if (this.options.debug) console.debug("[C->S]", event); if (!this.#socket) throw "Socket closed, trying to send."; this.#socket.send(JSON.stringify(event)); } @@ -207,7 +208,7 @@ export class EventClient extends EventEmitter< * @param event Event */ handle(event: EventProtocol["server"]) { - this.options.debug && console.debug("[S->C]", event); + if (this.options.debug) console.debug("[S->C]", event); switch (event.type) { case "Ping": this.send({ @@ -217,8 +218,8 @@ export class EventClient extends EventEmitter< return; case "Pong": clearTimeout(this.#pongTimeoutReference); - this.#setPing(+new Date() - event.data); - this.options.debug && console.debug(`[ping] ${this.ping()}ms`); + this.ping = +new Date() - event.data; + if (this.options.debug) console.debug(`[ping] ${this.ping}ms`); return; case "Error": this.#lastError = { @@ -230,7 +231,7 @@ export class EventClient extends EventEmitter< return; } - switch (this.state()) { + switch (this.state) { case ConnectionState.Connecting: if (event.type === "Authenticated") { // no-op @@ -249,9 +250,7 @@ export class EventClient extends EventEmitter< } break; default: - throw `Unreachable code. Received ${ - event.type - } in state ${this.state()}.`; + throw `Unreachable code. Received ${event.type} in state ${this.state}.`; } } diff --git a/src/events/index.ts b/src/events/index.ts deleted file mode 100644 index 33a26217..00000000 --- a/src/events/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { ProtocolV1 } from "./v1.js"; - -export { handleEvent as handleEventV1 } from "./v1.js"; - -export * from "./EventClient.js"; - -/** - * Available protocols to connect with - */ -export type AvailableProtocols = 1; - -/** - * Protocol mapping - */ -type Protocols = { - 1: ProtocolV1; -}; - -/** - * Select a protocol by its key - */ -export type EventProtocol = Protocols[T]; diff --git a/src/events/v1.ts b/src/events/v1.ts index c0eb3e46..92eb282a 100644 --- a/src/events/v1.ts +++ b/src/events/v1.ts @@ -1,6 +1,3 @@ -import { Setter, batch } from "solid-js"; - -import { ReactiveSet } from "@solid-primitives/set"; import type { Channel, Emoji, @@ -18,8 +15,9 @@ import type { User, } from "revolt-api"; +import { Client } from "../Client.js"; +import { MessageEmbed } from "../classes/MessageEmbed.js"; import { hydrate } from "../hydration/index.js"; -import { Client, MessageEmbed } from "../index.js"; /** * Version 1 of the events protocol @@ -188,7 +186,7 @@ type ReadyData = { export async function handleEvent( client: Client, event: ServerMessage, - setReady: Setter + setReady: (value: boolean) => void, ) { if (client.options.debug) { console.debug("[S->C]", event); @@ -202,31 +200,29 @@ export async function handleEvent( break; } case "Ready": { - batch(() => { - for (const user of event.users) { - const u = client.users.getOrCreate(user._id, user); + for (const user of event.users) { + const u = client.users.getOrCreate(user._id, user); - if (u.relationship === "User") { - client.user = u; - } + if (u.relationship === "User") { + client.user = u; } + } - for (const server of event.servers) { - client.servers.getOrCreate(server._id, server); - } + for (const server of event.servers) { + client.servers.getOrCreate(server._id, server); + } - for (const member of event.members) { - client.serverMembers.getOrCreate(member._id, member); - } + for (const member of event.members) { + client.serverMembers.getOrCreate(member._id, member); + } - for (const channel of event.channels) { - client.channels.getOrCreate(channel._id, channel); - } + for (const channel of event.channels) { + client.channels.getOrCreate(channel._id, channel); + } - for (const emoji of event.emojis) { - client.emojis.getOrCreate(emoji._id, emoji); - } - }); + for (const emoji of event.emojis) { + client.emojis.getOrCreate(emoji._id, emoji); + } if (client.options.syncUnreads) { await client.channelUnreads.sync(); @@ -239,25 +235,23 @@ export async function handleEvent( } case "Message": { if (!client.messages.has(event._id)) { - batch(() => { - if (event.member) { - client.serverMembers.getOrCreate(event.member._id, event.member); - } + if (event.member) { + client.serverMembers.getOrCreate(event.member._id, event.member); + } - if (event.user) { - client.users.getOrCreate(event.user._id, event.user); - } + if (event.user) { + client.users.getOrCreate(event.user._id, event.user); + } - delete event.member; - delete event.user; + delete event.member; + delete event.user; - client.messages.getOrCreate(event._id, event, true); - client.channels.updateUnderlyingObject( - event.channel, - "lastMessageId", - event._id - ); - }); + client.messages.getOrCreate(event._id, event, true); + client.channels.setKeyUnderlyingObject( + event.channel, + "lastMessageId", + event._id, + ); } break; } @@ -274,7 +268,7 @@ export async function handleEvent( "message", { ...event.data, channel: event.channel }, client, - false + false, ), editedAt: new Date(), }); @@ -291,17 +285,17 @@ export async function handleEvent( channelId: event.channel, }; - client.messages.updateUnderlyingObject(event.id, "embeds", (embeds) => [ - ...(embeds ?? []), + client.messages.setKeyUnderlyingObject(event.id, "embeds", [ + ...(previousMessage.embeds ?? []), ...(event.append.embeds?.map((embed) => - MessageEmbed.from(client, embed) + MessageEmbed.from(client, embed), ) ?? []), ]); - client.messages.updateUnderlyingObject( + client.messages.setKeyUnderlyingObject( event.id, "channelId", - event.channel + event.channel, ); client.emit("messageUpdate", message, previousMessage); @@ -317,22 +311,20 @@ export async function handleEvent( break; } case "BulkMessageDelete": { - batch(() => - client.emit( - "messageDeleteBulk", - event.ids - .map((id) => { - if (client.messages.has(id)) { - const message = client.messages.getUnderlyingObject(id); - client.messages.delete(id); - return message!; - } - - return undefined!; - }) - .filter((x) => x), - client.channels.get(event.channel) - ) + client.emit( + "messageDeleteBulk", + event.ids + .map((id) => { + if (client.messages.has(id)) { + const message = client.messages.getUnderlyingObject(id); + client.messages.delete(id); + return message!; + } + + return undefined!; + }) + .filter((x) => x), + client.channels.get(event.channel), ); break; } @@ -345,14 +337,14 @@ export async function handleEvent( if (set.has(event.user_id)) return; set.add(event.user_id); } else { - reactions.set(event.emoji_id, new ReactiveSet([event.user_id])); + reactions.set(event.emoji_id, new Set([event.user_id])); } client.emit( "messageReactionAdd", message, event.user_id, - event.emoji_id + event.emoji_id, ); } break; @@ -371,7 +363,7 @@ export async function handleEvent( "messageReactionRemove", message, event.user_id, - event.emoji_id + event.emoji_id, ); } break; @@ -446,7 +438,7 @@ export async function handleEvent( client.emit( "channelGroupJoin", channel, - await client.users.fetch(event.user) + await client.users.fetch(event.user), ); } break; @@ -463,7 +455,7 @@ export async function handleEvent( client.emit( "channelGroupLeave", channel, - client.users.getOrPartial(event.user)! + client.users.getOrPartial(event.user)!, ); } break; @@ -480,7 +472,7 @@ export async function handleEvent( client.emit( "channelStartTyping", channel, - client.users.getOrPartial(event.user)! + client.users.getOrPartial(event.user)!, ); } break; @@ -497,7 +489,7 @@ export async function handleEvent( client.emit( "channelStopTyping", channel, - client.users.getOrPartial(event.user)! + client.users.getOrPartial(event.user)!, ); } break; @@ -511,13 +503,11 @@ export async function handleEvent( } case "ServerCreate": { if (!client.servers.has(event.server._id)) { - batch(() => { - for (const channel of event.channels) { - client.channels.getOrCreate(channel._id, channel); - } + for (const channel of event.channels) { + client.channels.getOrCreate(channel._id, channel); + } - client.servers.getOrCreate(event.server._id, event.server, true); - }); + client.servers.getOrCreate(event.server._id, event.server, true); } break; } @@ -612,7 +602,7 @@ export async function handleEvent( client.serverMembers.getOrCreate(id, { _id: id, joined_at: new Date().toUTCString(), - }) + }), ); } break; @@ -622,7 +612,7 @@ export async function handleEvent( if (member) { const previousMember = { ...client.serverMembers.getUnderlyingObject( - event.id.server + event.id.user + event.id.server + event.id.user, ), }; @@ -649,7 +639,7 @@ export async function handleEvent( client.serverMembers.updateUnderlyingObject( event.id.server + event.id.user, - changes as never + changes as never, ); client.emit("serverMemberUpdate", member, previousMember); @@ -664,7 +654,7 @@ export async function handleEvent( type: "ServerDelete", id: event.id, }, - setReady + setReady, ); return; @@ -677,7 +667,7 @@ export async function handleEvent( if (client.serverMembers.getOrPartial(id)) { const member = client.serverMembers.getUnderlyingObject( - id.server + id.user + id.server + id.user, ); client.emit("serverMemberLeave", member); @@ -733,7 +723,7 @@ export async function handleEvent( relationship: event.user.relationship!, }, }, - setReady + setReady, ); break; } @@ -747,7 +737,7 @@ export async function handleEvent( online: event.online, }, }, - setReady + setReady, ); break; } @@ -756,37 +746,35 @@ export async function handleEvent( break; } case "UserPlatformWipe": { - batch(() => { - handleEvent( - client, - { - type: "BulkMessageDelete", - channel: "0", - ids: client.messages - .toList() - .filter((message) => message.authorId === event.user_id) - .map((message) => message.id), - }, - setReady - ); + handleEvent( + client, + { + type: "BulkMessageDelete", + channel: "0", + ids: client.messages + .toList() + .filter((message) => message.authorId === event.user_id) + .map((message) => message.id), + }, + setReady, + ); - handleEvent( - client, - { - type: "UserUpdate", - id: event.user_id, - data: { - username: `Deleted User`, - online: false, - flags: event.flags, - badges: 0, - relationship: "None", - }, - clear: ["Avatar", "StatusPresence", "StatusText"], + handleEvent( + client, + { + type: "UserUpdate", + id: event.user_id, + data: { + username: `Deleted User`, + online: false, + flags: event.flags, + badges: 0, + relationship: "None", }, - setReady - ); - }); + clear: ["Avatar", "StatusPresence", "StatusText"], + }, + setReady, + ); break; } diff --git a/src/hydration/bot.ts b/src/hydration/bot.ts index 666b6af3..78ac5892 100644 --- a/src/hydration/bot.ts +++ b/src/hydration/bot.ts @@ -1,4 +1,4 @@ -import { Bot as ApiBot } from "revolt-api"; +import { Bot } from "revolt-api"; import { Hydrate } from "./index.js"; @@ -15,7 +15,7 @@ export type HydratedBot = { flags: BotFlags; }; -export const botHydration: Hydrate = { +export const botHydration: Hydrate = { keyMapping: { _id: "id", owner: "ownerId", diff --git a/src/hydration/channel.ts b/src/hydration/channel.ts index aef59c30..6f50054f 100644 --- a/src/hydration/channel.ts +++ b/src/hydration/channel.ts @@ -1,22 +1,22 @@ -import { ReactiveSet } from "@solid-primitives/set"; -import { Channel as ApiChannel, OverrideField } from "revolt-api"; +import { Channel, OverrideField } from "revolt-api"; -import { Client, File } from "../index.js"; +import { Client } from "../Client.js"; +import { File } from "../classes/File.js"; import type { Merge } from "../lib/merge.js"; import { Hydrate } from "./index.js"; export type HydratedChannel = { id: string; - channelType: ApiChannel["channel_type"]; + channelType: Channel["channel_type"]; name: string; description?: string; icon?: File; active: boolean; - typingIds: ReactiveSet; - recipientIds: ReactiveSet; + typingIds: Set; + recipientIds: Set; userId?: string; ownerId?: string; @@ -30,7 +30,7 @@ export type HydratedChannel = { lastMessageId?: string; }; -export const channelHydration: Hydrate, HydratedChannel> = { +export const channelHydration: Hydrate, HydratedChannel> = { keyMapping: { _id: "id", channel_type: "channelType", @@ -49,8 +49,8 @@ export const channelHydration: Hydrate, HydratedChannel> = { description: (channel) => channel.description!, icon: (channel, ctx) => new File(ctx as Client, channel.icon!), active: (channel) => channel.active || false, - typingIds: () => new ReactiveSet(), - recipientIds: (channel) => new ReactiveSet(channel.recipients), + typingIds: () => new Set(), + recipientIds: (channel) => new Set(channel.recipients), userId: (channel) => channel.user, ownerId: (channel) => channel.owner, serverId: (channel) => channel.server, @@ -61,7 +61,7 @@ export const channelHydration: Hydrate, HydratedChannel> = { lastMessageId: (channel) => channel.last_message_id!, }, initialHydration: () => ({ - typingIds: new ReactiveSet(), - recipientIds: new ReactiveSet(), + typingIds: new Set(), + recipientIds: new Set(), }), }; diff --git a/src/hydration/channelUnread.ts b/src/hydration/channelUnread.ts index f293327e..22589071 100644 --- a/src/hydration/channelUnread.ts +++ b/src/hydration/channelUnread.ts @@ -1,6 +1,5 @@ -import { ReactiveSet } from "@solid-primitives/set"; +import { ChannelUnread } from "revolt-api"; -import { API } from "../index.js"; import type { Merge } from "../lib/merge.js"; import { Hydrate } from "./index.js"; @@ -8,11 +7,11 @@ import { Hydrate } from "./index.js"; export type HydratedChannelUnread = { id: string; lastMessageId?: string; - messageMentionIds: ReactiveSet; + messageMentionIds: Set; }; export const channelUnreadHydration: Hydrate< - Merge, + Merge, HydratedChannelUnread > = { keyMapping: { @@ -23,9 +22,9 @@ export const channelUnreadHydration: Hydrate< functions: { id: (unread) => unread._id.channel, lastMessageId: (unread) => unread.last_id!, - messageMentionIds: (unread) => new ReactiveSet(unread.mentions!), + messageMentionIds: (unread) => new Set(unread.mentions!), }, initialHydration: () => ({ - messageMentionIds: new ReactiveSet(), + messageMentionIds: new Set(), }), }; diff --git a/src/hydration/channelWebhook.ts b/src/hydration/channelWebhook.ts index 3a2dd564..fb9ab879 100644 --- a/src/hydration/channelWebhook.ts +++ b/src/hydration/channelWebhook.ts @@ -1,4 +1,7 @@ -import { API, Client, File } from "../index.js"; +import { Webhook } from "revolt-api"; + +import { Client } from "../Client.js"; +import { File } from "../classes/File.js"; import type { Merge } from "../lib/merge.js"; import { Hydrate } from "./index.js"; @@ -12,7 +15,7 @@ export type HydratedChannelWebhook = { }; export const channelWebhookHydration: Hydrate< - Merge, + Merge, HydratedChannelWebhook > = { keyMapping: { diff --git a/src/hydration/emoji.ts b/src/hydration/emoji.ts index c86aa70f..20d52695 100644 --- a/src/hydration/emoji.ts +++ b/src/hydration/emoji.ts @@ -1,4 +1,4 @@ -import { Emoji as ApiEmoji, EmojiParent } from "revolt-api"; +import { Emoji, EmojiParent } from "revolt-api"; import type { Merge } from "../lib/merge.js"; @@ -13,7 +13,7 @@ export type HydratedEmoji = { nsfw: boolean; }; -export const emojiHydration: Hydrate, HydratedEmoji> = { +export const emojiHydration: Hydrate, HydratedEmoji> = { keyMapping: { _id: "id", creator_id: "creatorId", diff --git a/src/hydration/index.ts b/src/hydration/index.ts index 8d872acb..ea4e7596 100644 --- a/src/hydration/index.ts +++ b/src/hydration/index.ts @@ -9,21 +9,6 @@ import { serverMemberHydration } from "./serverMember.js"; import { sessionHydration } from "./session.js"; import { userHydration } from "./user.js"; -export { BotFlags } from "./bot.js"; -export { ServerFlags } from "./server.js"; -export { UserBadges, UserFlags } from "./user.js"; - -export type { HydratedBot } from "./bot.js"; -export type { HydratedChannel } from "./channel.js"; -export type { HydratedChannelUnread } from "./channelUnread.js"; -export type { HydratedChannelWebhook } from "./channelWebhook.js"; -export type { HydratedEmoji } from "./emoji.js"; -export type { HydratedMessage } from "./message.js"; -export type { HydratedServer } from "./server.js"; -export type { HydratedServerMember } from "./serverMember.js"; -export type { HydratedSession } from "./session.js"; -export type { HydratedUser } from "./user.js"; - /** * Functions to map from one object to another */ @@ -55,19 +40,20 @@ export type Hydrate = { function hydrateInternal( hydration: Hydrate, input: Input, - context: unknown + context: unknown, ): Output { return (Object.keys(input) as (keyof Input)[]).reduce((acc, key) => { let targetKey, value; try { targetKey = hydration.keyMapping[key] ?? key; value = hydration.functions[targetKey as keyof Output](input, context); - } catch (err) { - if (key === "partial") + } catch { + if (key === "partial") { return { ...acc, partial: input["partial" as never], }; + } if (key === "type") return acc; console.debug(`Skipping key ${String(key)} during hydration!`); return acc; @@ -112,11 +98,11 @@ export function hydrate( type: T, input: Partial>, context: unknown, - initial?: boolean + initial?: boolean, ) { return hydrateInternal( hydrators[type] as never, initial ? { ...hydrators[type].initialHydration(), ...input } : input, - context + context, ) as ExtractOutput; } diff --git a/src/hydration/message.ts b/src/hydration/message.ts index a75ed487..254aabd0 100644 --- a/src/hydration/message.ts +++ b/src/hydration/message.ts @@ -1,14 +1,10 @@ -import { ReactiveMap } from "@solid-primitives/map"; -import { ReactiveSet } from "@solid-primitives/set"; +import { Interactions, Masquerade, Message } from "revolt-api"; -import { - API, - Client, - File, - MessageEmbed, - MessageWebhook, - SystemMessage, -} from "../index.js"; +import { Client } from "../Client.js"; +import { File } from "../classes/File.js"; +import { MessageWebhook } from "../classes/Message.js"; +import { MessageEmbed } from "../classes/MessageEmbed.js"; +import { SystemMessage } from "../classes/SystemMessage.js"; import type { Merge } from "../lib/merge.js"; import { Hydrate } from "./index.js"; @@ -26,13 +22,13 @@ export type HydratedMessage = { embeds?: MessageEmbed[]; mentionIds?: string[]; replyIds?: string[]; - reactions: ReactiveMap>; - interactions?: API.Interactions; - masquerade?: API.Masquerade; + reactions: Map>; + interactions?: Interactions; + masquerade?: Masquerade; flags?: number; }; -export const messageHydration: Hydrate, HydratedMessage> = { +export const messageHydration: Hydrate, HydratedMessage> = { keyMapping: { _id: "id", channel: "channelId", @@ -62,10 +58,10 @@ export const messageHydration: Hydrate, HydratedMessage> = { mentionIds: (message) => message.mentions!, replyIds: (message) => message.replies!, reactions: (message) => { - const map = new ReactiveMap>(); + const map = new Map>(); if (message.reactions) { for (const reaction of Object.keys(message.reactions)) { - map.set(reaction, new ReactiveSet(message.reactions![reaction])); + map.set(reaction, new Set(message.reactions![reaction])); } } return map; @@ -75,6 +71,6 @@ export const messageHydration: Hydrate, HydratedMessage> = { flags: (message) => message.flags!, }, initialHydration: () => ({ - reactions: new ReactiveMap(), + reactions: new Map(), }), }; diff --git a/src/hydration/server.ts b/src/hydration/server.ts index f47e0be9..64e0e391 100644 --- a/src/hydration/server.ts +++ b/src/hydration/server.ts @@ -1,13 +1,7 @@ -import { ReactiveMap } from "@solid-primitives/map"; -import { ReactiveSet } from "@solid-primitives/set"; -import { - Server as ApiServer, - Category, - Role, - SystemMessageChannels, -} from "revolt-api"; +import { Category, Role, Server, SystemMessageChannels } from "revolt-api"; -import { Client, File } from "../index.js"; +import { Client } from "../Client.js"; +import { File } from "../classes/File.js"; import { Hydrate } from "./index.js"; @@ -21,11 +15,11 @@ export type HydratedServer = { icon?: File; banner?: File; - channelIds: ReactiveSet; + channelIds: Set; categories?: Category[]; systemMessages?: SystemMessageChannels; - roles: ReactiveMap; + roles: Map; defaultPermissions: number; flags: ServerFlags; @@ -34,7 +28,7 @@ export type HydratedServer = { nsfw: boolean; }; -export const serverHydration: Hydrate = { +export const serverHydration: Hydrate = { keyMapping: { _id: "id", owner: "ownerId", @@ -47,13 +41,11 @@ export const serverHydration: Hydrate = { ownerId: (server) => server.owner, name: (server) => server.name, description: (server) => server.description!, - channelIds: (server) => new ReactiveSet(server.channels), + channelIds: (server) => new Set(server.channels), categories: (server) => server.categories ?? [], systemMessages: (server) => server.system_messages ?? {}, roles: (server) => - new ReactiveMap( - Object.keys(server.roles!).map((id) => [id, server.roles![id]]) - ), + new Map(Object.keys(server.roles!).map((id) => [id, server.roles![id]])), defaultPermissions: (server) => server.default_permissions, icon: (server, ctx) => new File(ctx as Client, server.icon!), banner: (server, ctx) => new File(ctx as Client, server.banner!), @@ -63,8 +55,8 @@ export const serverHydration: Hydrate = { nsfw: (server) => server.nsfw || false, }, initialHydration: () => ({ - channelIds: new ReactiveSet(), - roles: new ReactiveMap(), + channelIds: new Set(), + roles: new Map(), }), }; diff --git a/src/hydration/serverMember.ts b/src/hydration/serverMember.ts index 1d2c6ce2..e6518b0b 100644 --- a/src/hydration/serverMember.ts +++ b/src/hydration/serverMember.ts @@ -1,6 +1,7 @@ -import { Member as ApiMember, MemberCompositeKey } from "revolt-api"; +import { Member, MemberCompositeKey } from "revolt-api"; -import { Client, File } from "../index.js"; +import { Client } from "../Client.js"; +import { File } from "../classes/File.js"; import type { Merge } from "../lib/merge.js"; import { Hydrate } from "./index.js"; @@ -15,7 +16,7 @@ export type HydratedServerMember = { }; export const serverMemberHydration: Hydrate< - Merge, + Merge, HydratedServerMember > = { keyMapping: { diff --git a/src/hydration/session.ts b/src/hydration/session.ts index 11b0c31b..4782c459 100644 --- a/src/hydration/session.ts +++ b/src/hydration/session.ts @@ -1,4 +1,4 @@ -import { SessionInfo as ApiSession } from "revolt-api"; +import { SessionInfo } from "revolt-api"; import { Hydrate } from "./index.js"; @@ -7,7 +7,7 @@ export type HydratedSession = { name: string; }; -export const sessionHydration: Hydrate = { +export const sessionHydration: Hydrate = { keyMapping: { _id: "id", }, diff --git a/src/hydration/user.ts b/src/hydration/user.ts index d57a18ec..7a3c7be7 100644 --- a/src/hydration/user.ts +++ b/src/hydration/user.ts @@ -1,11 +1,12 @@ import { - User as ApiUser, BotInformation, RelationshipStatus, + User, UserStatus, } from "revolt-api"; -import { Client, File } from "../index.js"; +import { Client } from "../Client.js"; +import { File } from "../classes/File.js"; import { Hydrate } from "./index.js"; @@ -28,7 +29,7 @@ export type HydratedUser = { bot?: BotInformation; }; -export const userHydration: Hydrate = { +export const userHydration: Hydrate = { keyMapping: { _id: "id", display_name: "displayName", diff --git a/src/index.ts b/src/index.ts index f32105c5..7c037626 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,9 @@ -export * as API from "revolt-api"; export { Client } from "./Client.js"; export type { ClientOptions, Session as PrivateSession } from "./Client.js"; export * from "./classes/index.js"; export * from "./collections/index.js"; -export { ConnectionState, EventClient } from "./events/index.js"; -export { - BotFlags, - ServerFlags, - UserBadges, - UserFlags, -} from "./hydration/index.js"; +export { ConnectionState, EventClient } from "./events/EventClient.js"; +export { BotFlags } from "./hydration/bot.js"; +export { ServerFlags } from "./hydration/server.js"; +export { UserBadges, UserFlags } from "./hydration/user.js"; export * from "./lib/regex.js"; diff --git a/src/lib/merge.ts b/src/lib/merge.ts index 7c74bd8e..99324d55 100644 --- a/src/lib/merge.ts +++ b/src/lib/merge.ts @@ -5,9 +5,8 @@ export type Merge = { [k in NonCommonKeys]?: PickTypeOf; }; -type PickTypeOf = K extends AllKeys - ? PickType - : never; +type PickTypeOf = + K extends AllKeys ? PickType : never; // eslint-disable-next-line type PickType> = T extends { [k in K]?: any } diff --git a/src/permissions/calculator.ts b/src/permissions/calculator.ts index 816fa249..9b99bc2c 100644 --- a/src/permissions/calculator.ts +++ b/src/permissions/calculator.ts @@ -1,6 +1,7 @@ -import Long from "long"; - -import { Channel, Client, Server, ServerMember } from "../index.js"; +import { Client } from "../Client.js"; +import { Channel } from "../classes/Channel.js"; +import { Server } from "../classes/Server.js"; +import { ServerMember } from "../classes/ServerMember.js"; import { ALLOW_IN_TIMEOUT, @@ -16,8 +17,8 @@ import { * @param b Inputs (OR'd together) */ export function bitwiseAndEq(a: number, ...b: number[]) { - const value = b.reduce((prev, cur) => prev.or(cur), Long.fromNumber(0)); - return value.and(a).eq(value); + const value = b.reduce((prev, cur) => prev | BigInt(cur), 0n); + return (value & BigInt(a)) === value; } /** @@ -33,7 +34,7 @@ export function calculatePermission( * Pretend to be another ServerMember */ member?: ServerMember; - } + }, ): number { const user = options?.member ? options?.member.user : client.user; if (user?.privileged) { @@ -55,26 +56,26 @@ export function calculatePermission( if (!member) return 0; // 3. Apply allows from default_permissions. - let perm = Long.fromNumber(target.defaultPermissions); + let perm = BigInt(target.defaultPermissions); // 4. If user has roles, iterate in order. if (member.roles && target.roles) { // 5. Apply allows and denies from roles. const permissions = member.orderedRoles.map( - (role) => role.permissions ?? { a: 0, d: 0 } + (role) => role.permissions ?? { a: 0, d: 0 }, ); for (const permission of permissions) { - perm = perm.or(permission.a).and(Long.fromNumber(permission.d).not()); + perm = (perm | BigInt(permission.a)) & ~BigInt(permission.d); } } // 5. Revoke permissions if ServerMember is timed out. if (member.timeout && member.timeout > new Date()) { - perm = perm.and(ALLOW_IN_TIMEOUT); + perm = perm & BigInt(ALLOW_IN_TIMEOUT); } - return perm.toNumber(); + return Number(perm); } } else { // 1. Check channel type. @@ -121,15 +122,13 @@ export function calculatePermission( if (!member) return 0; // 5. Calculate server base permissions. - let perm = Long.fromNumber( - calculatePermission(client, server, options) - ); + let perm = BigInt(calculatePermission(client, server, options)); // 6. Apply default allows and denies for channel. if (target.defaultPermissions) { - perm = perm - .or(target.defaultPermissions.a) - .and(Long.fromNumber(target.defaultPermissions.d).not()); + perm = + (perm | BigInt(target.defaultPermissions.a)) & + ~BigInt(target.defaultPermissions.d); } // 7. If user has roles, iterate in order. @@ -140,19 +139,17 @@ export function calculatePermission( for (const id of roles) { const override = target.rolePermissions[id]; if (override) { - perm = perm - .or(override.a) - .and(Long.fromNumber(override.d).not()); + perm = (perm | BigInt(override.a)) & ~BigInt(override.d); } } } // 8. Revoke permissions if ServerMember is timed out. if (member.timeout && member.timeout > new Date()) { - perm = perm.and(ALLOW_IN_TIMEOUT); + perm = perm & BigInt(ALLOW_IN_TIMEOUT); } - return perm.toNumber(); + return Number(perm); } } } diff --git a/src/storage/ObjectStorage.ts b/src/storage/ObjectStorage.ts index 458b50c3..73b23333 100644 --- a/src/storage/ObjectStorage.ts +++ b/src/storage/ObjectStorage.ts @@ -1,23 +1,10 @@ -import { SetStoreFunction, createStore } from "solid-js/store"; - import { Hydrators, hydrate } from "../hydration/index.js"; /** * Wrapper around Solid.js store */ export class ObjectStorage { - private store: Record; - readonly set: SetStoreFunction>; - - /** - * Create new object storage - */ - constructor() { - const [store, setStore] = createStore({}); - this.store = store as never; - this.set = setStore; - this.get = this.get.bind(this); - } + private store: Record = {}; /** * Get object by ID @@ -28,6 +15,15 @@ export class ObjectStorage { return this.store[id]; } + /** + * Set object by ID + * @param id ID + * @param value New value + */ + set(id: string, value: T) { + this.store[id] = value; + } + /** * Hydrate some data into storage * @param id ID diff --git a/test.js b/test.js deleted file mode 100644 index 9bf053bd..00000000 --- a/test.js +++ /dev/null @@ -1,12 +0,0 @@ -require("dotenv").config(); - -const { Client } = require("."); - -const client = new Client({ debug: true }); - -client.on("ready", () => console.info(`Logged in as ${client.user.username}!`)); -client.on("disconnected", () => console.info("Disconnected.")); - -client.on("messageCreate", (message) => console.info(message.content)); - -client.loginBot(process.env.TOKEN); diff --git a/test.mjs b/test.mjs old mode 100644 new mode 100755 index c514b316..1f48b108 --- a/test.mjs +++ b/test.mjs @@ -1,6 +1,6 @@ -import "dotenv/config"; - -import { Client } from "./lib/esm/index.js"; +#!/usr/bin/env -S node --env-file test.mjs +/* eslint-disable no-undef */ +import { Client } from "./lib/index.js"; const client = new Client({ debug: true }); diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json deleted file mode 100644 index 084cf2f7..00000000 --- a/tsconfig.cjs.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "target": "es2016", - "module": "commonjs", - "declaration": true, - "declarationMap": true, - "outDir": "./lib/cjs" - } -} diff --git a/tsconfig.json b/tsconfig.json index 2fd75e8f..a39ec41d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,7 @@ "rootDir": "./src", "declaration": true, "declarationMap": true, - "outDir": "./lib/esm", + "outDir": "./lib", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, From 74b8a9e9e9795734b53a6e9f819953590eb20039 Mon Sep 17 00:00:00 2001 From: Jersey Date: Thu, 13 Mar 2025 21:16:27 -0400 Subject: [PATCH 2/9] BREAKING CHANGE: simplify Collection interface Signed-off-by: Jersey --- .vscode/settings.json | 5 +- src/classes/Channel.ts | 4 +- src/classes/ChannelWebhook.ts | 2 +- src/classes/PublicBot.ts | 6 +- src/classes/Server.ts | 8 +- src/classes/Session.ts | 2 +- src/classes/User.ts | 2 +- src/collections/AccountCollection.ts | 72 +++--- src/collections/BotCollection.ts | 8 +- src/collections/ChannelCollection.ts | 13 +- src/collections/ChannelUnreadCollection.ts | 12 +- src/collections/ChannelWebhookCollection.ts | 6 +- src/collections/Collection.ts | 230 ++++++++------------ src/collections/EmojiCollection.ts | 8 +- src/collections/MessageCollection.ts | 11 +- src/collections/ServerCollection.ts | 10 +- src/collections/ServerMemberCollection.ts | 10 +- src/collections/SessionCollection.ts | 11 +- src/collections/UserCollection.ts | 8 +- src/collections/index.ts | 3 +- src/events/v1.ts | 55 ++--- src/storage/ObjectStorage.ts | 40 ---- 22 files changed, 212 insertions(+), 314 deletions(-) delete mode 100644 src/storage/ObjectStorage.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 9bf4d12b..c4aecfc3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true + "editor.formatOnSave": true, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } diff --git a/src/classes/Channel.ts b/src/classes/Channel.ts index d38c16b7..03ff7c68 100644 --- a/src/classes/Channel.ts +++ b/src/classes/Channel.ts @@ -421,7 +421,7 @@ export class Channel { }); if (this.type === "DirectMessage") { - this.#collection.setKeyUnderlyingObject(this.id, "active", false); + this.#collection.setUnderlyingKey(this.id, "active", false); return; } @@ -663,7 +663,7 @@ export class Channel { const unreads = this.#collection.client.channelUnreads; const channelUnread = unreads.get(this.id); if (channelUnread) { - unreads.updateUnderlyingObject(this.id, { + unreads.setUnderlyingObject(this.id, { ...channelUnread, lastMessageId, messageMentionIds: unreads.getUnderlyingObject(this.id) diff --git a/src/classes/ChannelWebhook.ts b/src/classes/ChannelWebhook.ts index 14468c14..f59b2396 100644 --- a/src/classes/ChannelWebhook.ts +++ b/src/classes/ChannelWebhook.ts @@ -82,7 +82,7 @@ export class ChannelWebhook { data, ); - this.#collection.updateUnderlyingObject( + this.#collection.setUnderlyingObject( this.id, // @ts-expect-error not in prod hydrate("channelWebhook", webhook, this.#collection.client), diff --git a/src/classes/PublicBot.ts b/src/classes/PublicBot.ts index 39f3ecc3..42abb8f6 100644 --- a/src/classes/PublicBot.ts +++ b/src/classes/PublicBot.ts @@ -28,9 +28,9 @@ export class PublicBot { this.username = data.username; this.avatar = data.avatar ? new File(client, { - _id: data.avatar, - tag: "avatars", - } as APIFile) + _id: data.avatar, + tag: "avatars", + } as APIFile) : undefined; this.description = data.description!; } diff --git a/src/classes/Server.ts b/src/classes/Server.ts index d333d9e7..43006876 100644 --- a/src/classes/Server.ts +++ b/src/classes/Server.ts @@ -119,9 +119,9 @@ export class Server { * Channels */ get channels() { - return [ - ...this.#collection.getUnderlyingObject(this.id).channelIds.values(), - ] + return Array.from( + this.#collection.getUnderlyingObject(this.id).channelIds.values(), + ) .map((id) => this.#collection.client.channels.get(id)!) .filter((x) => x); } @@ -374,7 +374,7 @@ export class Server { * @param data Changes */ async edit(data: DataEditServer) { - this.#collection.updateUnderlyingObject( + this.#collection.setUnderlyingObject( this.id, hydrate( "server", diff --git a/src/classes/Session.ts b/src/classes/Session.ts index 305cea3c..fee4ec85 100644 --- a/src/classes/Session.ts +++ b/src/classes/Session.ts @@ -64,7 +64,7 @@ export class Session { friendly_name: name, }); - this.#collection.setKeyUnderlyingObject(this.id, "name", name); + this.#collection.setUnderlyingKey(this.id, "name", name); } /** diff --git a/src/classes/User.ts b/src/classes/User.ts index 17d64b2a..51b1d797 100644 --- a/src/classes/User.ts +++ b/src/classes/User.ts @@ -249,7 +249,7 @@ export class User { if (dm) { if (!dm.active) { - this.#collection.client.channels.setKeyUnderlyingObject( + this.#collection.client.channels.setUnderlyingKey( dm.id, "active", true, diff --git a/src/collections/AccountCollection.ts b/src/collections/AccountCollection.ts index e2a1547f..40135dc2 100644 --- a/src/collections/AccountCollection.ts +++ b/src/collections/AccountCollection.ts @@ -21,16 +21,14 @@ export class AccountCollection { * Fetch current account email * @returns Email */ - fetchEmail() { - return this.client.api - .get("/auth/account/") - .then((account) => account.email); + async fetchEmail(): Promise { + return (await this.client.api.get("/auth/account/")).email; } /** * Create a MFA helper */ - async mfa() { + async mfa(): Promise { const state = await this.client.api.get("/auth/mfa/"); return new MFA(this.client, state); } @@ -39,8 +37,8 @@ export class AccountCollection { * Create a new account * @param data Account details */ - create(data: DataCreateAccount) { - return this.client.api.post("/auth/account/create", data); + async create(data: DataCreateAccount): Promise { + return await this.client.api.post("/auth/account/create", data); } /** @@ -48,8 +46,11 @@ export class AccountCollection { * @param email Email * @param captcha Captcha if enabled */ - reverify(email: string, captcha?: string) { - return this.client.api.post("/auth/account/reverify", { email, captcha }); + async reverify(email: string, captcha?: string): Promise { + return await this.client.api.post("/auth/account/reverify", { + email, + captcha, + }); } /** @@ -57,8 +58,8 @@ export class AccountCollection { * @param email Email * @param captcha Captcha if enabled */ - resetPassword(email: string, captcha?: string) { - return this.client.api.post("/auth/account/reset_password", { + async resetPassword(email: string, captcha?: string): Promise { + return await this.client.api.post("/auth/account/reset_password", { email, captcha, }); @@ -68,16 +69,16 @@ export class AccountCollection { * Verify an account given the code * @param code Verification code */ - verify(code: string) { - return this.client.api.post(`/auth/account/verify/${code}`); + async verify(code: string): Promise { + return await this.client.api.post(`/auth/account/verify/${code}`); } /** * Confirm account deletion * @param token Deletion token */ - confirmDelete(token: string) { - return this.client.api.put("/auth/account/delete", { token }); + async confirmDelete(token: string): Promise { + return await this.client.api.put("/auth/account/delete", { token }); } /** @@ -86,12 +87,12 @@ export class AccountCollection { * @param newPassword New password * @param removeSessions Whether to remove existing sessions */ - confirmPasswordReset( + async confirmPasswordReset( token: string, newPassword: string, removeSessions: boolean, - ) { - return this.client.api.patch("/auth/account/reset_password", { + ): Promise { + return await this.client.api.patch("/auth/account/reset_password", { token, password: newPassword, remove_sessions: removeSessions, @@ -103,8 +104,11 @@ export class AccountCollection { * @param newPassword New password * @param currentPassword Current password */ - changePassword(newPassword: string, currentPassword: string) { - return this.client.api.patch("/auth/account/change/password", { + async changePassword( + newPassword: string, + currentPassword: string, + ): Promise { + return await this.client.api.patch("/auth/account/change/password", { password: newPassword, current_password: currentPassword, }); @@ -115,8 +119,8 @@ export class AccountCollection { * @param newEmail New email * @param currentPassword Current password */ - changeEmail(newEmail: string, currentPassword: string) { - return this.client.api.patch("/auth/account/change/email", { + async changeEmail(newEmail: string, currentPassword: string): Promise { + return await this.client.api.patch("/auth/account/change/email", { email: newEmail, current_password: currentPassword, }); @@ -127,10 +131,10 @@ export class AccountCollection { * @param keys Keys * @returns Settings */ - fetchSettings(keys: string[]) { - return this.client.api.post("/sync/settings/fetch", { keys }) as Promise< - Record - >; + async fetchSettings( + keys: string[], + ): Promise> { + return await this.client.api.post("/sync/settings/fetch", { keys }); } /* eslint-disable @typescript-eslint/no-explicit-any */ @@ -139,26 +143,28 @@ export class AccountCollection { * @param settings Settings * @param timestamp Timestamp */ - setSettings(settings: Record, timestamp = +new Date()) { - return this.client.api.post("/sync/settings/set", { + async setSettings( + settings: Record, + timestamp = new Date().getTime(), + ): Promise { + return await this.client.api.post("/sync/settings/set", { ...settings, timestamp, }); } - /* eslint-enable @typescript-eslint/no-explicit-any */ /** * Create a new Web Push subscription * @param subscription Subscription */ - webPushSubscribe(subscription: WebPushSubscription) { - return this.client.api.post("/push/subscribe", subscription); + async webPushSubscribe(subscription: WebPushSubscription): Promise { + return await this.client.api.post("/push/subscribe", subscription); } /** * Remove existing Web Push subscription */ - webPushUnsubscribe() { - return this.client.api.post("/push/unsubscribe"); + async webPushUnsubscribe(): Promise { + return await this.client.api.post("/push/unsubscribe"); } } diff --git a/src/collections/BotCollection.ts b/src/collections/BotCollection.ts index db1852fa..af1b7342 100644 --- a/src/collections/BotCollection.ts +++ b/src/collections/BotCollection.ts @@ -4,12 +4,12 @@ import { Bot } from "../classes/Bot.js"; import { PublicBot } from "../classes/PublicBot.js"; import { HydratedBot } from "../hydration/bot.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Bots */ -export class BotCollection extends ClassCollection { +export class BotCollection extends Collection { /** * Fetch bot by ID * @param id Id @@ -49,7 +49,7 @@ export class BotCollection extends ClassCollection { * @param data Data * @returns Bot */ - getOrCreate(id: string, data: APIBot) { + getOrCreate(id: string, data: APIBot): Bot { if (this.has(id)) { return this.get(id)!; } else { @@ -64,7 +64,7 @@ export class BotCollection extends ClassCollection { * @param name Bot name * @returns The newly-created bot */ - async createBot(name: string) { + async createBot(name: string): Promise { const bot = await this.client.api.post(`/bots/create`, { name, }); diff --git a/src/collections/ChannelCollection.ts b/src/collections/ChannelCollection.ts index 9f04b344..c5858e13 100644 --- a/src/collections/ChannelCollection.ts +++ b/src/collections/ChannelCollection.ts @@ -4,15 +4,12 @@ import { Channel } from "../classes/Channel.js"; import { User } from "../classes/User.js"; import { HydratedChannel } from "../hydration/channel.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Channels */ -export class ChannelCollection extends ClassCollection< - Channel, - HydratedChannel -> { +export class ChannelCollection extends Collection { /** * Delete an object * @param id Id @@ -41,7 +38,7 @@ export class ChannelCollection extends ClassCollection< * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: APIChannel, isNew = false) { + getOrCreate(id: string, data: APIChannel, isNew = false): Channel { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { @@ -56,7 +53,7 @@ export class ChannelCollection extends ClassCollection< * Get or return partial * @param id Id */ - getOrPartial(id: string) { + getOrPartial(id: string): Channel | undefined { if (this.has(id)) { return this.get(id)!; } else if (this.client.options.partials) { @@ -75,7 +72,7 @@ export class ChannelCollection extends ClassCollection< * @param users Users to add * @returns The newly-created group */ - async createGroup(name: string, users: (User | string)[]) { + async createGroup(name: string, users: (User | string)[]): Promise { const group = await this.client.api.post(`/channels/create`, { name, users: users.map((user) => (user instanceof User ? user.id : user)), diff --git a/src/collections/ChannelUnreadCollection.ts b/src/collections/ChannelUnreadCollection.ts index 72218e7e..e09d2b2c 100644 --- a/src/collections/ChannelUnreadCollection.ts +++ b/src/collections/ChannelUnreadCollection.ts @@ -3,19 +3,19 @@ import { ChannelUnread as APIChannelUnread } from "revolt-api"; import { ChannelUnread } from "../classes/ChannelUnread.js"; import { HydratedChannelUnread } from "../hydration/channelUnread.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Channel Unreads */ -export class ChannelUnreadCollection extends ClassCollection< +export class ChannelUnreadCollection extends Collection< ChannelUnread, HydratedChannelUnread > { /** * Load unread information from server */ - async sync() { + async sync(): Promise { const unreads = await this.client.api.get("/sync/unreads"); this.reset(); for (const unread of unreads) { @@ -26,9 +26,9 @@ export class ChannelUnreadCollection extends ClassCollection< /** * Clear all unread data */ - reset() { + reset(): void { for (const key of this.keys()) { - this.updateUnderlyingObject(key, {} as never); + this.setUnderlyingObject(key, {} as never); } } @@ -37,7 +37,7 @@ export class ChannelUnreadCollection extends ClassCollection< * @param id Id * @param data Data */ - getOrCreate(id: string, data: APIChannelUnread) { + getOrCreate(id: string, data: APIChannelUnread): ChannelUnread { if (this.has(id)) { return this.get(id)!; } else { diff --git a/src/collections/ChannelWebhookCollection.ts b/src/collections/ChannelWebhookCollection.ts index 5c16fcb8..ac6dfe10 100644 --- a/src/collections/ChannelWebhookCollection.ts +++ b/src/collections/ChannelWebhookCollection.ts @@ -3,12 +3,12 @@ import { Webhook } from "revolt-api"; import { ChannelWebhook } from "../classes/ChannelWebhook.js"; import { HydratedChannelWebhook } from "../hydration/channelWebhook.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Channel Webhooks */ -export class ChannelWebhookCollection extends ClassCollection< +export class ChannelWebhookCollection extends Collection< ChannelWebhook, HydratedChannelWebhook > { @@ -48,7 +48,7 @@ export class ChannelWebhookCollection extends ClassCollection< * @param id Id * @param data Data */ - getOrCreate(id: string, data: Webhook) { + getOrCreate(id: string, data: Webhook): ChannelWebhook { if (this.has(id)) { return this.get(id)!; } else { diff --git a/src/collections/Collection.ts b/src/collections/Collection.ts index 3aaf1a56..0cf499a6 100644 --- a/src/collections/Collection.ts +++ b/src/collections/Collection.ts @@ -1,157 +1,66 @@ import { Client } from "../Client.js"; -import { Hydrators } from "../hydration/index.js"; -import { ObjectStorage } from "../storage/ObjectStorage.js"; +import { Hydrators, hydrate } from "../hydration/index.js"; /** - * Abstract Collection type + * Collection backed by a store */ -export abstract class Collection { - /** - * Get an existing object - * @param id Id - * @returns Object - */ - abstract get(id: string): T | undefined; +export class Collection { + #storage = new Map(); + #objects = new Map(); /** - * Check whether an id exists in the Collection - * @param id Id - * @returns Whether it exists + * Construct store backed collection */ - abstract has(id: string): boolean; + constructor(public readonly client: Client) {} /** - * Delete an object + * Get an existing object * @param id Id */ - abstract delete(id: string): void; - - /** - * Number of stored objects - * @returns Size - */ - abstract size(): number; - - /** - * Iterable of keys in the map - * @returns Iterable - */ - abstract keys(): IterableIterator; - - /** - * Iterable of values in the map - * @returns Iterable - */ - abstract values(): IterableIterator; - - /** - * Iterable of key, value pairs in the map - * @returns Iterable - */ - abstract entries(): IterableIterator<[string, T]>; - - /** - * Execute a provided function over each key, value pair in the map - * @param cb Callback for each pair - */ - abstract forEach( - cb: (value: T, key: string, map: Map) => void, - ): void; - - /** - * List of values in the map - * @returns List - */ - toList() { - return [...this.values()]; - } - - /** - * Filter the collection by a given predicate - * @param predicate Predicate to satisfy - */ - filter(predicate: (value: T, key: string) => boolean): T[] { - const list: T[] = []; - for (const [key, value] of this.entries()) { - if (predicate(value, key)) { - list.push(value); - } - } - - return list; + get(id: string): T | undefined { + return this.#objects.get(id); } /** - * Map the collection using a given callback - * @param cb Callback + * Get an underlying object */ - map(cb: (value: T, key: string) => O): O[] { - const list: O[] = []; - for (const [key, value] of this.entries()) { - list.push(cb(value, key)); - } - - return list; + getUnderlyingObject(id: string): V { + return this.#storage.get(id) ?? ({} as V); } /** - * Find some value based on a predicate - * @param predicate Predicate to satisfy + * Set a key of an underlying object */ - find(predicate: (value: T, key: string) => boolean): T | undefined { - for (const [key, value] of this.entries()) { - if (predicate(value, key)) { - return value; - } - } + setUnderlyingKey(id: string, key: K, value: V[K]) { + this.#storage.set(id, { + [key]: value, + ...((this.#storage.get(id) ?? {}) as V), + }); } -} - -/** - * Collection backed by a Solid.js Store - */ -export abstract class StoreCollection extends Collection { - #storage = new ObjectStorage(); - #objects = new Map(); - readonly getUnderlyingObject: (id: string) => V; - readonly setKeyUnderlyingObject: ( - id: string, - key: K, - value: V[K], - ) => void; - readonly updateUnderlyingObject: (id: string, value: V) => void; /** - * Construct store backed collection + * Set an underlying object */ - constructor() { - super(); - this.getUnderlyingObject = (key) => this.#storage.get(key) ?? ({} as V); - this.setKeyUnderlyingObject = (id, key, value) => { - this.#storage.set(id, { - [key]: value, - ...this.getUnderlyingObject(id), - }); - }; - this.updateUnderlyingObject = this.#storage.set; + setUnderlyingObject(id: string, value: V) { + this.#storage.set(id, value); } /** - * Get an existing object + * Check whether an id exists in the Collection * @param id Id - * @returns Object + * @returns Whether it exists */ - get(id: string): T | undefined { - return this.#objects.get(id); + has(id: string): boolean { + return this.#objects.has(id); } /** - * Check whether an id exists in the Collection + * Check whether the underlying id exists * @param id Id * @returns Whether it exists */ - has(id: string) { - return this.#objects.has(id); + hasUnderlying(id: string): boolean { + return !!((this.#storage.get(id) as { id: string }) ?? { id: false }).id; } /** @@ -160,7 +69,7 @@ export abstract class StoreCollection extends Collection { */ delete(id: string): void { this.#objects.delete(id); - this.updateUnderlyingObject(id, undefined as never); + this.#storage.delete(id); } /** @@ -177,8 +86,13 @@ export abstract class StoreCollection extends Collection { instance: T, context: unknown, data?: unknown, - ) { - this.#storage.hydrate(id, type, context, data); + ): void { + if (data) { + this.#storage.set( + id, + hydrate(type, { partial: false, ...data } as never, context, true) as V, + ); + } this.#objects.set(id, instance); } @@ -188,14 +102,16 @@ export abstract class StoreCollection extends Collection { * @returns Whether it is a partial */ isPartial(id: string): boolean { - return !!(this.getUnderlyingObject(id) as { partial: boolean }).partial; + return !!( + (this.#storage.get(id) ?? { partial: true }) as { partial: boolean } + ).partial; } /** * Number of stored objects * @returns Size */ - size() { + size(): number { return this.#objects.size; } @@ -203,7 +119,7 @@ export abstract class StoreCollection extends Collection { * Iterable of keys in the map * @returns Iterable */ - keys() { + keys(): MapIterator { return this.#objects.keys(); } @@ -211,7 +127,7 @@ export abstract class StoreCollection extends Collection { * Iterable of values in the map * @returns Iterable */ - values() { + values(): MapIterator { return this.#objects.values(); } @@ -219,32 +135,64 @@ export abstract class StoreCollection extends Collection { * Iterable of key, value pairs in the map * @returns Iterable */ - entries() { + entries(): MapIterator<[string, T]> { return this.#objects.entries(); } /** * Execute a provided function over each key, value pair in the map * @param cb Callback for each pair - * @returns Iterable */ - forEach(cb: (value: T, key: string, map: Map) => void) { + forEach(cb: (value: T, key: string, map: Map) => void): void { return this.#objects.forEach(cb); } -} -/** - * Generic class collection backed by store - */ -export class ClassCollection extends StoreCollection { - readonly client: Client; + /** + * List of values in the map + * @returns List + */ + toList(): T[] { + return [...this.values()]; + } /** - * Create generic class collection - * @param client Client + * Filter the collection by a given predicate + * @param predicate Predicate to satisfy */ - constructor(client: Client) { - super(); - this.client = client; + filter(predicate: (value: T, key: string) => boolean): T[] { + const list: T[] = []; + for (const [key, value] of this.entries()) { + if (predicate(value, key)) { + list.push(value); + } + } + + return list; + } + + /** + * Map the collection using a given callback + * @param cb Callback + */ + map(cb: (value: T, key: string) => O): O[] { + const list: O[] = []; + for (const [key, value] of this.entries()) { + list.push(cb(value, key)); + } + + return list; + } + + /** + * Find some value based on a predicate + * @param predicate Predicate to satisfy + */ + find(predicate: (value: T, key: string) => boolean): T | undefined { + for (const [key, value] of this.entries()) { + if (predicate(value, key)) { + return value; + } + } + return undefined; } } diff --git a/src/collections/EmojiCollection.ts b/src/collections/EmojiCollection.ts index f270097a..7246138e 100644 --- a/src/collections/EmojiCollection.ts +++ b/src/collections/EmojiCollection.ts @@ -3,12 +3,12 @@ import { Emoji as APIEmoji } from "revolt-api"; import { Emoji } from "../classes/Emoji.js"; import { HydratedEmoji } from "../hydration/emoji.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Emoji */ -export class EmojiCollection extends ClassCollection { +export class EmojiCollection extends Collection { /** * Fetch emoji by ID * @param id Id @@ -27,7 +27,7 @@ export class EmojiCollection extends ClassCollection { * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: APIEmoji, isNew = false) { + getOrCreate(id: string, data: APIEmoji, isNew = false): Emoji { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { @@ -42,7 +42,7 @@ export class EmojiCollection extends ClassCollection { * Get or return partial * @param id Id */ - getOrPartial(id: string) { + getOrPartial(id: string): Emoji | undefined { if (this.has(id)) { return this.get(id)!; } else if (this.client.options.partials) { diff --git a/src/collections/MessageCollection.ts b/src/collections/MessageCollection.ts index 759193b0..e3df06f6 100644 --- a/src/collections/MessageCollection.ts +++ b/src/collections/MessageCollection.ts @@ -3,15 +3,12 @@ import { Message as APIMessage } from "revolt-api"; import { Message } from "../classes/Message.js"; import { HydratedMessage } from "../hydration/message.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Messages */ -export class MessageCollection extends ClassCollection< - Message, - HydratedMessage -> { +export class MessageCollection extends Collection { /** * Fetch message by Id * @param channelId Channel Id @@ -35,7 +32,7 @@ export class MessageCollection extends ClassCollection< * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: APIMessage, isNew = false) { + getOrCreate(id: string, data: APIMessage, isNew = false): Message { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { @@ -50,7 +47,7 @@ export class MessageCollection extends ClassCollection< * Get or return partial * @param id Id */ - getOrPartial(id: string) { + getOrPartial(id: string): Message | undefined { if (this.has(id)) { return this.get(id)!; } else if (this.client.options.partials) { diff --git a/src/collections/ServerCollection.ts b/src/collections/ServerCollection.ts index 06c2bb1a..b794b605 100644 --- a/src/collections/ServerCollection.ts +++ b/src/collections/ServerCollection.ts @@ -3,12 +3,12 @@ import { Server as APIServer, Channel, DataCreateServer } from "revolt-api"; import { Server } from "../classes/Server.js"; import { HydratedServer } from "../hydration/server.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Servers */ -export class ServerCollection extends ClassCollection { +export class ServerCollection extends Collection { /** * Fetch server by ID * @@ -38,7 +38,7 @@ export class ServerCollection extends ClassCollection { * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: APIServer, isNew = false) { + getOrCreate(id: string, data: APIServer, isNew = false): Server { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { @@ -53,7 +53,7 @@ export class ServerCollection extends ClassCollection { * Get or return partial * @param id Id */ - getOrPartial(id: string) { + getOrPartial(id: string): Server | undefined { if (this.has(id)) { return this.get(id)!; } else if (this.client.options.partials) { @@ -71,7 +71,7 @@ export class ServerCollection extends ClassCollection { * @param data Server options * @returns The newly-created server */ - async createServer(data: DataCreateServer) { + async createServer(data: DataCreateServer): Promise { const { server, channels } = await this.client.api.post( `/servers/create`, data, diff --git a/src/collections/ServerMemberCollection.ts b/src/collections/ServerMemberCollection.ts index 822cc3f8..a5bdb65a 100644 --- a/src/collections/ServerMemberCollection.ts +++ b/src/collections/ServerMemberCollection.ts @@ -3,12 +3,12 @@ import { Member, MemberCompositeKey } from "revolt-api"; import { ServerMember } from "../classes/ServerMember.js"; import { HydratedServerMember } from "../hydration/serverMember.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Server Members */ -export class ServerMemberCollection extends ClassCollection< +export class ServerMemberCollection extends Collection< ServerMember, HydratedServerMember > { @@ -17,7 +17,7 @@ export class ServerMemberCollection extends ClassCollection< * @param id Id * @returns Whether it exists */ - hasByKey(id: MemberCompositeKey) { + hasByKey(id: MemberCompositeKey): boolean { return super.has(id.server + id.user); } @@ -26,7 +26,7 @@ export class ServerMemberCollection extends ClassCollection< * @param id Id * @returns Member */ - getByKey(id: MemberCompositeKey) { + getByKey(id: MemberCompositeKey): ServerMember | undefined { return super.get(id.server + id.user); } @@ -35,7 +35,7 @@ export class ServerMemberCollection extends ClassCollection< * @param id Id * @returns Member */ - isPartialByKey(id: MemberCompositeKey) { + isPartialByKey(id: MemberCompositeKey): boolean { return super.isPartial(id.server + id.user); } diff --git a/src/collections/SessionCollection.ts b/src/collections/SessionCollection.ts index 69f16eda..56de5497 100644 --- a/src/collections/SessionCollection.ts +++ b/src/collections/SessionCollection.ts @@ -3,15 +3,12 @@ import { SessionInfo } from "revolt-api"; import { Session } from "../classes/Session.js"; import { HydratedSession } from "../hydration/session.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Sessions */ -export class SessionCollection extends ClassCollection< - Session, - HydratedSession -> { +export class SessionCollection extends Collection { /** * Fetch active sessions * @returns List of sessions @@ -25,7 +22,7 @@ export class SessionCollection extends ClassCollection< * Delete all sessions, optionally including self * @param revokeSelf Whether to remove current session too */ - async deleteAll(revokeSelf = false) { + async deleteAll(revokeSelf = false): Promise { await this.client.api.delete("/auth/session/all", { revoke_self: revokeSelf, }); @@ -42,7 +39,7 @@ export class SessionCollection extends ClassCollection< * @param data Data * @returns Session */ - getOrCreate(id: string, data: SessionInfo) { + getOrCreate(id: string, data: SessionInfo): Session { if (this.has(id)) { return this.get(id)!; } else { diff --git a/src/collections/UserCollection.ts b/src/collections/UserCollection.ts index 6597b115..266cd40d 100644 --- a/src/collections/UserCollection.ts +++ b/src/collections/UserCollection.ts @@ -4,12 +4,12 @@ import { Client } from "../Client.js"; import { User } from "../classes/User.js"; import { HydratedUser } from "../hydration/user.js"; -import { ClassCollection } from "./Collection.js"; +import { Collection } from "./Collection.js"; /** * Collection of Users */ -export class UserCollection extends ClassCollection { +export class UserCollection extends Collection { /** * Construct User collection */ @@ -44,7 +44,7 @@ export class UserCollection extends ClassCollection { * @param data Data * @param isNew Whether this object is new */ - getOrCreate(id: string, data: APIUser) { + getOrCreate(id: string, data: APIUser): User { if (this.has(id) && !this.isPartial(id)) { return this.get(id)!; } else { @@ -58,7 +58,7 @@ export class UserCollection extends ClassCollection { * Get or return partial * @param id Id */ - getOrPartial(id: string) { + getOrPartial(id: string): User | undefined { if (this.has(id)) { return this.get(id)!; } else if (this.client.options.partials) { diff --git a/src/collections/index.ts b/src/collections/index.ts index d192286a..b2a79d6c 100644 --- a/src/collections/index.ts +++ b/src/collections/index.ts @@ -1,9 +1,8 @@ -export * from "./Collection.js"; - export { BotCollection } from "./BotCollection.js"; export { ChannelCollection } from "./ChannelCollection.js"; export { ChannelUnreadCollection } from "./ChannelUnreadCollection.js"; export { ChannelWebhookCollection } from "./ChannelWebhookCollection.js"; +export { Collection as ClassCollection } from "./Collection.js"; export { EmojiCollection } from "./EmojiCollection.js"; export { MessageCollection } from "./MessageCollection.js"; export { ServerCollection } from "./ServerCollection.js"; diff --git a/src/events/v1.ts b/src/events/v1.ts index 92eb282a..703387c1 100644 --- a/src/events/v1.ts +++ b/src/events/v1.ts @@ -247,7 +247,7 @@ export async function handleEvent( delete event.user; client.messages.getOrCreate(event._id, event, true); - client.channels.setKeyUnderlyingObject( + client.channels.setUnderlyingKey( event.channel, "lastMessageId", event._id, @@ -263,7 +263,7 @@ export async function handleEvent( channelId: event.channel, }; - client.messages.updateUnderlyingObject(event.id, { + client.messages.setUnderlyingObject(event.id, { ...hydrate( "message", { ...event.data, channel: event.channel }, @@ -285,18 +285,14 @@ export async function handleEvent( channelId: event.channel, }; - client.messages.setKeyUnderlyingObject(event.id, "embeds", [ + client.messages.setUnderlyingKey(event.id, "embeds", [ ...(previousMessage.embeds ?? []), ...(event.append.embeds?.map((embed) => MessageEmbed.from(client, embed), ) ?? []), ]); - client.messages.setKeyUnderlyingObject( - event.id, - "channelId", - event.channel, - ); + client.messages.setUnderlyingKey(event.id, "channelId", event.channel); client.emit("messageUpdate", message, previousMessage); } @@ -304,8 +300,10 @@ export async function handleEvent( } case "MessageDelete": { if (client.messages.getOrPartial(event.id)) { - const message = client.messages.getUnderlyingObject(event.id); - client.emit("messageDelete", message); + client.emit( + "messageDelete", + client.messages.getUnderlyingObject(event.id), + ); client.messages.delete(event.id); } break; @@ -391,9 +389,7 @@ export async function handleEvent( case "ChannelUpdate": { const channel = client.channels.getOrPartial(event.id); if (channel) { - const previousChannel = { - ...client.channels.getUnderlyingObject(event.id), - }; + const previousChannel = client.channels.getUnderlyingObject(event.id); const changes = hydrate("channel", event.data, client, false); @@ -413,15 +409,17 @@ export async function handleEvent( } } - client.channels.updateUnderlyingObject(event.id, changes); + client.channels.setUnderlyingObject(event.id, changes); client.emit("channelUpdate", channel, previousChannel); } break; } case "ChannelDelete": { if (client.channels.getOrPartial(event.id)) { - const channel = client.channels.getUnderlyingObject(event.id); - client.emit("channelDelete", channel); + client.emit( + "channelDelete", + client.channels.getUnderlyingObject(event.id), + ); client.channels.delete(event.id); } break; @@ -514,9 +512,7 @@ export async function handleEvent( case "ServerUpdate": { const server = client.servers.getOrPartial(event.id); if (server) { - const previousServer = { - ...client.servers.getUnderlyingObject(event.id), - }; + const previousServer = client.servers.getUnderlyingObject(event.id); const changes = hydrate("server", event.data, client, false); @@ -542,7 +538,7 @@ export async function handleEvent( } } - client.servers.updateUnderlyingObject(event.id, changes); + client.servers.setUnderlyingObject(event.id, changes); client.emit("serverUpdate", server, previousServer); } break; @@ -610,11 +606,9 @@ export async function handleEvent( case "ServerMemberUpdate": { const member = client.serverMembers.getOrPartial(event.id); if (member) { - const previousMember = { - ...client.serverMembers.getUnderlyingObject( - event.id.server + event.id.user, - ), - }; + const previousMember = client.serverMembers.getUnderlyingObject( + event.id.server + event.id.user, + ); const changes = hydrate("serverMember", event.data, client, false); @@ -637,7 +631,7 @@ export async function handleEvent( } } - client.serverMembers.updateUnderlyingObject( + client.serverMembers.setUnderlyingObject( event.id.server + event.id.user, changes as never, ); @@ -678,9 +672,7 @@ export async function handleEvent( case "UserUpdate": { const user = client.users.getOrPartial(event.id); if (user) { - const previousUser = { - ...client.users.getUnderlyingObject(event.id), - }; + const previousUser = client.users.getUnderlyingObject(event.id); const changes = hydrate("user", event.data, client, false); @@ -708,7 +700,7 @@ export async function handleEvent( } } - client.users.updateUnderlyingObject(event.id, changes as never); + client.users.setUnderlyingObject(event.id, changes as never); client.emit("userUpdate", user, previousUser); } break; @@ -786,8 +778,7 @@ export async function handleEvent( } case "EmojiDelete": { if (client.emojis.getOrPartial(event.id)) { - const emoji = client.emojis.getUnderlyingObject(event.id); - client.emit("emojiDelete", emoji); + client.emit("emojiDelete", client.emojis.getUnderlyingObject(event.id)); client.emojis.delete(event.id); } break; diff --git a/src/storage/ObjectStorage.ts b/src/storage/ObjectStorage.ts deleted file mode 100644 index 73b23333..00000000 --- a/src/storage/ObjectStorage.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Hydrators, hydrate } from "../hydration/index.js"; - -/** - * Wrapper around Solid.js store - */ -export class ObjectStorage { - private store: Record = {}; - - /** - * Get object by ID - * @param id ID - * @returns Object - */ - get(id: string) { - return this.store[id]; - } - - /** - * Set object by ID - * @param id ID - * @param value New value - */ - set(id: string, value: T) { - this.store[id] = value; - } - - /** - * Hydrate some data into storage - * @param id ID - * @param type Hydration type - * @param context Context - * @param data Input Data - */ - hydrate(id: string, type: keyof Hydrators, context: unknown, data?: unknown) { - if (data) { - data = { partial: false, ...data }; - this.set(id, hydrate(type, data as never, context, true) as T); - } - } -} From ee015e55a8fd0dfb62daf6f10139d17f9a2f064b Mon Sep 17 00:00:00 2001 From: Jersey Date: Thu, 13 Mar 2025 22:25:37 -0400 Subject: [PATCH 3/9] chore: add return types to all functions --- src/Client.ts | 22 +++--- src/classes/Bot.ts | 35 +++++---- src/classes/Channel.ts | 142 ++++++++++++++++++++-------------- src/classes/ChannelUnread.ts | 6 +- src/classes/ChannelWebhook.ts | 21 ++--- src/classes/Emoji.ts | 21 ++--- src/classes/File.ts | 10 +-- src/classes/Invite.ts | 12 ++- src/classes/MFA.ts | 47 +++++------ src/classes/Message.ts | 83 +++++++++++--------- src/classes/MessageEmbed.ts | 10 +-- src/classes/PublicBot.ts | 4 +- src/classes/PublicInvite.ts | 3 +- src/classes/Server.ts | 118 +++++++++++++++------------- src/classes/ServerBan.ts | 5 +- src/classes/ServerMember.ts | 49 ++++++------ src/classes/Session.ts | 14 ++-- src/classes/SystemMessage.ts | 13 ++-- src/classes/User.ts | 74 ++++++++++-------- src/classes/UserProfile.ts | 4 +- src/collections/Collection.ts | 4 +- src/events/EventClient.ts | 15 ++-- src/events/v1.ts | 2 +- src/hydration/index.ts | 4 +- src/permissions/calculator.ts | 2 +- 25 files changed, 402 insertions(+), 318 deletions(-) diff --git a/src/Client.ts b/src/Client.ts index 1f8ebf29..9e99cb39 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -250,28 +250,28 @@ export class Client extends EventEmitter { /** * Whether the client is ready */ - get ready() { + get ready(): boolean { return this.#ready; } /** * Set whether the client is ready */ - #setReady(value: boolean) { + #setReady(value: boolean): void { this.#ready = value; } /** * Current session id */ - get sessionId() { + get sessionId(): string | undefined { return typeof this.#session === "string" ? undefined : this.#session?._id; } /** * Get authentication header */ - get authenticationHeader() { + get authenticationHeader(): string[] { return typeof this.#session === "string" ? ["X-Bot-Token", this.#session] : ["X-Session-Token", this.#session?.token as string]; @@ -280,7 +280,7 @@ export class Client extends EventEmitter { /** * Connect to Revolt */ - connect() { + connect(): void { clearTimeout(this.#reconnectTimeout); this.events.disconnect(); this.#setReady(false); @@ -293,7 +293,7 @@ export class Client extends EventEmitter { /** * Fetches the configuration of the server if it has not been already fetched. */ - async #fetchConfiguration() { + async #fetchConfiguration(): Promise { if (!this.configuration) { this.configuration = await this.api.get("/"); } @@ -302,7 +302,7 @@ export class Client extends EventEmitter { /** * Update API object to use authentication. */ - #updateHeaders() { + #updateHeaders(): void { (this.api as API) = new API({ baseURL: this.options.baseURL, authentication: { @@ -316,7 +316,7 @@ export class Client extends EventEmitter { * @param details Login data object * @returns An on-boarding function if on-boarding is required, undefined otherwise */ - async login(details: DataLogin) { + async login(details: DataLogin): Promise { await this.#fetchConfiguration(); const data = await this.api.post("/auth/session/login", details); if (data.result === "Success") { @@ -330,7 +330,7 @@ export class Client extends EventEmitter { /** * Use an existing session */ - async useExistingSession(session: Session) { + async useExistingSession(session: Session): Promise { this.#session = session; this.#updateHeaders(); } @@ -339,7 +339,7 @@ export class Client extends EventEmitter { * Log in as a bot * @param token Bot token */ - async loginBot(token: string) { + async loginBot(token: string): Promise { await this.#fetchConfiguration(); this.#session = token; this.#updateHeaders(); @@ -351,7 +351,7 @@ export class Client extends EventEmitter { * @param source Source markdown text * @returns Modified plain text */ - markdownToText(source: string) { + markdownToText(source: string): string { return source .replace(RE_MENTIONS, (sub: string, id: string) => { const user = this.users.get(id as string); diff --git a/src/classes/Bot.ts b/src/classes/Bot.ts index 689fd316..0b165baf 100644 --- a/src/classes/Bot.ts +++ b/src/classes/Bot.ts @@ -2,6 +2,9 @@ import { DataEditBot } from "revolt-api"; import { decodeTime } from "ulid"; import { BotCollection } from "../collections/BotCollection.js"; +import { BotFlags } from "../hydration/bot.js"; + +import { User } from "./User.js"; /** * Bot Class @@ -24,98 +27,98 @@ export class Bot { * Convert to string * @returns String */ - toString() { + toString(): string { return `<@${this.id}>`; } /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Time when this user created their account */ - get createdAt() { + get createdAt(): Date { return new Date(decodeTime(this.id)); } /** * Corresponding user */ - get user() { + get user(): User | undefined { return this.#collection.client.users.get(this.id); } /** * Owner's Id */ - get ownerId() { + get ownerId(): string { return this.#collection.getUnderlyingObject(this.id).ownerId; } /** * Owner */ - get owner() { + get owner(): User | undefined { return this.#collection.client.users.get(this.ownerId); } /** * Bot Token */ - get token() { + get token(): string { return this.#collection.getUnderlyingObject(this.id).token; } /** * Whether this bot can be invited by anyone */ - get public() { + get public(): boolean { return this.#collection.getUnderlyingObject(this.id).public; } /** * Whether this bot has analytics enabled */ - get analytics() { + get analytics(): boolean { return this.#collection.getUnderlyingObject(this.id).analytics; } /** * Whether this bot shows up on Discover */ - get discoverable() { + get discoverable(): boolean { return this.#collection.getUnderlyingObject(this.id).discoverable; } /** * Interactions URL */ - get interactionsUrl() { + get interactionsUrl(): string | undefined { return this.#collection.getUnderlyingObject(this.id).interactionsUrl; } /** * Link to terms of service */ - get termsOfServiceUrl() { + get termsOfServiceUrl(): string | undefined { return this.#collection.getUnderlyingObject(this.id).termsOfServiceUrl; } /** * Link to privacy policy */ - get privacyPolicyUrl() { + get privacyPolicyUrl(): string | undefined { return this.#collection.getUnderlyingObject(this.id).privacyPolicyUrl; } /** * Bot Flags */ - get flags() { + get flags(): BotFlags { return this.#collection.getUnderlyingObject(this.id).flags; } @@ -123,14 +126,14 @@ export class Bot { * Edit a bot * @param data Changes */ - async edit(data: DataEditBot) { + async edit(data: DataEditBot): Promise { await this.#collection.client.api.patch(`/bots/${this.id as ""}`, data); } /** * Delete a bot */ - async delete() { + async delete(): Promise { await this.#collection.client.api.delete(`/bots/${this.id as ""}`); this.#collection.delete(this.id); } diff --git a/src/classes/Channel.ts b/src/classes/Channel.ts index 03ff7c68..5a0ce445 100644 --- a/src/classes/Channel.ts +++ b/src/classes/Channel.ts @@ -1,4 +1,5 @@ import type { + Channel as APIChannel, Member as APIMember, Message as APIMessage, User as APIUser, @@ -17,7 +18,12 @@ import { } from "../permissions/calculator.js"; import { Permission } from "../permissions/definitions.js"; +import { ChannelWebhook } from "./ChannelWebhook.js"; +import { File } from "./File.js"; import { Message } from "./Message.js"; +import { Server } from "./Server.js"; +import { ServerMember } from "./ServerMember.js"; +import { User } from "./User.js"; /** * Channel Class @@ -40,35 +46,35 @@ export class Channel { * Write to string as a channel mention * @returns Formatted String */ - toString() { + toString(): string { return `<#${this.id}>`; } /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Time when this server was created */ - get createdAt() { + get createdAt(): Date { return new Date(decodeTime(this.id)); } /** * Channel type */ - get type() { + get type(): APIChannel["channel_type"] { return this.#collection.getUnderlyingObject(this.id).channelType; } /** * Absolute pathname to this channel in the client */ - get path() { + get path(): string { if (this.serverId) { return `/server/${this.serverId}/channel/${this.id}`; } else { @@ -79,21 +85,21 @@ export class Channel { /** * URL to this channel */ - get url() { + get url(): string { return this.#collection.client.configuration?.app + this.path; } /** * Channel name */ - get name() { + get name(): string { return this.#collection.getUnderlyingObject(this.id).name; } /** * Display name */ - get displayName() { + get displayName(): string | undefined { return this.type === "SavedMessages" ? this.user?.username : this.type === "DirectMessage" @@ -104,35 +110,35 @@ export class Channel { /** * Channel description */ - get description() { + get description(): string | undefined { return this.#collection.getUnderlyingObject(this.id).description; } /** * Channel icon */ - get icon() { + get icon(): File | undefined { return this.#collection.getUnderlyingObject(this.id).icon; } /** * Whether the conversation is active */ - get active() { + get active(): boolean { return this.#collection.getUnderlyingObject(this.id).active; } /** * User ids of people currently typing in channel */ - get typingIds() { + get typingIds(): Set { return this.#collection.getUnderlyingObject(this.id).typingIds; } /** * Users currently trying in channel */ - get typing() { + get typing(): User[] { return [...this.typingIds.values()].map( (id) => this.#collection.client.users.get(id)!, ); @@ -141,14 +147,14 @@ export class Channel { /** * User ids of recipients of the group */ - get recipientIds() { + get recipientIds(): Set { return this.#collection.getUnderlyingObject(this.id).recipientIds; } /** * Recipients of the group */ - get recipients() { + get recipients(): User[] { return [ ...this.#collection.getUnderlyingObject(this.id).recipientIds.values(), ].map((id) => this.#collection.client.users.get(id)!); @@ -157,7 +163,7 @@ export class Channel { /** * Find recipient of this DM */ - get recipient() { + get recipient(): User | undefined { return this.type === "DirectMessage" ? this.recipients?.find( (user) => user?.id !== this.#collection.client.user!.id, @@ -168,14 +174,14 @@ export class Channel { /** * User ID */ - get userId() { + get userId(): string { return this.#collection.getUnderlyingObject(this.id).userId!; } /** * User this channel belongs to */ - get user() { + get user(): User | undefined { return this.#collection.client.users.get( this.#collection.getUnderlyingObject(this.id).userId!, ); @@ -184,14 +190,14 @@ export class Channel { /** * Owner ID */ - get ownerId() { + get ownerId(): string { return this.#collection.getUnderlyingObject(this.id).ownerId!; } /** * Owner of the group */ - get owner() { + get owner(): User | undefined { return this.#collection.client.users.get( this.#collection.getUnderlyingObject(this.id).ownerId!, ); @@ -200,14 +206,14 @@ export class Channel { /** * Server ID */ - get serverId() { + get serverId(): string { return this.#collection.getUnderlyingObject(this.id).serverId!; } /** * Server this channel is in */ - get server() { + get server(): Server | undefined { return this.#collection.client.servers.get( this.#collection.getUnderlyingObject(this.id).serverId!, ); @@ -216,49 +222,49 @@ export class Channel { /** * Permissions allowed for users in this group */ - get permissions() { + get permissions(): number | undefined { return this.#collection.getUnderlyingObject(this.id).permissions; } /** * Default permissions for this server channel */ - get defaultPermissions() { + get defaultPermissions(): { a: number; d: number } | undefined { return this.#collection.getUnderlyingObject(this.id).defaultPermissions; } /** * Role permissions for this server channel */ - get rolePermissions() { + get rolePermissions(): Record | undefined { return this.#collection.getUnderlyingObject(this.id).rolePermissions; } /** * Whether this channel is marked as mature */ - get mature() { + get mature(): boolean { return this.#collection.getUnderlyingObject(this.id).nsfw; } /** * ID of the last message sent in this channel */ - get lastMessageId() { + get lastMessageId(): string | undefined { return this.#collection.getUnderlyingObject(this.id).lastMessageId; } /** * Last message sent in this channel */ - get lastMessage() { + get lastMessage(): Message | undefined { return this.#collection.client.messages.get(this.lastMessageId!); } /** * Time when the last message was sent */ - get lastMessageAt() { + get lastMessageAt(): Date | undefined { return this.lastMessageId ? new Date(decodeTime(this.lastMessageId)) : undefined; @@ -267,14 +273,14 @@ export class Channel { /** * Time when the channel was last updated (either created or a message was sent) */ - get updatedAt() { + get updatedAt(): Date { return this.lastMessageAt ?? this.createdAt; } /** * Get whether this channel is unread. */ - get unread() { + get unread(): boolean { if ( !this.lastMessageId || this.type === "SavedMessages" || @@ -295,7 +301,7 @@ export class Channel { /** * Get mentions in this channel for user. */ - get mentions() { + get mentions(): Set | undefined { if (this.type === "SavedMessages" || this.type === "VoiceChannel") { return undefined; } @@ -307,21 +313,21 @@ export class Channel { /** * URL to the channel icon */ - get iconURL() { + get iconURL(): string | undefined { return this.icon?.createFileURL() ?? this.recipient?.avatarURL; } /** * URL to the animated channel icon */ - get animatedIconURL() { + get animatedIconURL(): string | undefined { return this.icon?.createFileURL(true) ?? this.recipient?.animatedAvatarURL; } /** * Whether this channel may be hidden to some users */ - get potentiallyRestrictedChannel() { + get potentiallyRestrictedChannel(): string | boolean | undefined { if (!this.serverId) return false; return ( bitwiseAndEq(this.defaultPermissions?.d ?? 0, Permission.ViewChannel) || @@ -343,7 +349,7 @@ export class Channel { /** * Permission the currently authenticated user has against this channel */ - get permission() { + get permission(): number { return calculatePermission(this.#collection.client, this); } @@ -352,7 +358,7 @@ export class Channel { * @param permission Permission Names * @returns Whether we have this permission */ - havePermission(...permission: (keyof typeof Permission)[]) { + havePermission(...permission: (keyof typeof Permission)[]): boolean { return bitwiseAndEq( this.permission, ...permission.map((x) => Permission[x]), @@ -364,7 +370,7 @@ export class Channel { * @param permission Permission Names * @returns Whether we have one of the permissions */ - orPermission(...permission: (keyof typeof Permission)[]) { + orPermission(...permission: (keyof typeof Permission)[]): boolean { return ( permission.findIndex((x) => bitwiseAndEq(this.permission, Permission[x]), @@ -377,7 +383,7 @@ export class Channel { * @requires `Group` * @returns An array of the channel's members. */ - async fetchMembers() { + async fetchMembers(): Promise { const members = await this.#collection.client.api.get( `/channels/${this.id as ""}/members`, ); @@ -392,7 +398,7 @@ export class Channel { * @requires `TextChannel`, `Group` * @returns Webhooks */ - async fetchWebhooks() { + async fetchWebhooks(): Promise { const webhooks = await this.#collection.client.api.get( `/channels/${this.id as ""}/webhooks`, ); @@ -406,7 +412,7 @@ export class Channel { * Edit a channel * @param data Changes */ - async edit(data: DataEditChannel) { + async edit(data: DataEditChannel): Promise { await this.#collection.client.api.patch(`/channels/${this.id as ""}`, data); } @@ -415,7 +421,7 @@ export class Channel { * @param leaveSilently Whether to not send a message on leave * @requires `DirectMessage`, `Group`, `TextChannel`, `VoiceChannel` */ - async delete(leaveSilently?: boolean) { + async delete(leaveSilently?: boolean): Promise { await this.#collection.client.api.delete(`/channels/${this.id as ""}`, { leave_silently: leaveSilently, }); @@ -433,7 +439,7 @@ export class Channel { * @param user_id ID of the target user * @requires `Group` */ - async addMember(user_id: string) { + async addMember(user_id: string): Promise { return await this.#collection.client.api.put( `/channels/${this.id as ""}/recipients/${user_id as ""}`, ); @@ -444,7 +450,7 @@ export class Channel { * @param user_id ID of the target user * @requires `Group` */ - async removeMember(user_id: string) { + async removeMember(user_id: string): Promise { return await this.#collection.client.api.delete( `/channels/${this.id as ""}/recipients/${user_id as ""}`, ); @@ -459,7 +465,7 @@ export class Channel { async sendMessage( data: string | DataMessageSend, idempotencyKey: string = ulid(), - ) { + ): Promise { const msg: DataMessageSend = typeof data === "string" ? { content: data } : data; @@ -493,7 +499,7 @@ export class Channel { * @requires `SavedMessages`, `DirectMessage`, `Group`, `TextChannel` * @returns Message */ - async fetchMessage(messageId: string) { + async fetchMessage(messageId: string): Promise { const message = await this.#collection.client.api.get( `/channels/${this.id as ""}/messages/${messageId as ""}`, ); @@ -515,7 +521,7 @@ export class Channel { })["params"], "include_users" >, - ) { + ): Promise { const messages = (await this.#collection.client.api.get( `/channels/${this.id as ""}/messages`, { ...params }, @@ -540,7 +546,11 @@ export class Channel { })["params"], "include_users" >, - ) { + ): Promise<{ + messages: Message[]; + users: User[]; + members: ServerMember[] | undefined; + }> { const data = (await this.#collection.client.api.get( `/channels/${this.id as ""}/messages`, { ...params, include_users: true }, @@ -565,7 +575,9 @@ export class Channel { * @requires `SavedMessages`, `DirectMessage`, `Group`, `TextChannel` * @returns Messages */ - async search(params: Omit) { + async search( + params: Omit, + ): Promise { const messages = (await this.#collection.client.api.post( `/channels/${this.id as ""}/search`, params, @@ -582,7 +594,13 @@ export class Channel { * @requires `SavedMessages`, `DirectMessage`, `Group`, `TextChannel` * @returns Object including messages and users */ - async searchWithUsers(params: Omit) { + async searchWithUsers( + params: Omit, + ): Promise<{ + messages: Message[]; + users: User[]; + members: ServerMember[] | undefined; + }> { const data = (await this.#collection.client.api.post( `/channels/${this.id as ""}/search`, { @@ -609,7 +627,7 @@ export class Channel { * @param ids List of message IDs * @requires `SavedMessages`, `DirectMessage`, `Group`, `TextChannel` */ - async deleteMessages(ids: string[]) { + async deleteMessages(ids: string[]): Promise { await this.#collection.client.api.delete( `/channels/${this.id as ""}/messages/bulk`, { @@ -623,7 +641,16 @@ export class Channel { * @requires `TextChannel`, `VoiceChannel` * @returns Newly created invite code */ - async createInvite() { + async createInvite(): Promise< + | { + type: "Server"; + _id: string; + server: string; + creator: string; + channel: string; + } + | { type: "Group"; _id: string; creator: string; channel: string } + > { return await this.#collection.client.api.post( `/channels/${this.id as ""}/invites`, ); @@ -646,7 +673,7 @@ export class Channel { skipRateLimiter?: boolean, skipRequest?: boolean, skipNextMarking?: boolean, - ) { + ): Promise { if (!message && this.#manuallyMarked) { this.#manuallyMarked = false; return; @@ -709,7 +736,10 @@ export class Channel { * @param permissions Permission value * @requires `Group`, `TextChannel`, `VoiceChannel` */ - async setPermissions(role_id = "default", permissions: Override) { + async setPermissions( + role_id = "default", + permissions: Override, + ): Promise { return await this.#collection.client.api.put( `/channels/${this.id as ""}/permissions/${role_id as ""}`, { permissions }, @@ -720,7 +750,7 @@ export class Channel { * Start typing in this channel * @requires `DirectMessage`, `Group`, `TextChannel` */ - startTyping() { + startTyping(): void { this.#collection.client.events.send({ type: "BeginTyping", channel: this.id, @@ -731,7 +761,7 @@ export class Channel { * Stop typing in this channel * @requires `DirectMessage`, `Group`, `TextChannel` */ - stopTyping() { + stopTyping(): void { this.#collection.client.events.send({ type: "EndTyping", channel: this.id, diff --git a/src/classes/ChannelUnread.ts b/src/classes/ChannelUnread.ts index adfd24e1..deb1b980 100644 --- a/src/classes/ChannelUnread.ts +++ b/src/classes/ChannelUnread.ts @@ -20,21 +20,21 @@ export class ChannelUnread { /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Last read message id */ - get lastMessageId() { + get lastMessageId(): string | undefined { return this.#collection.getUnderlyingObject(this.id).lastMessageId; } /** * List of message IDs that we were mentioned in */ - get messageMentionIds() { + get messageMentionIds(): Set { return this.#collection.getUnderlyingObject(this.id).messageMentionIds; } } diff --git a/src/classes/ChannelWebhook.ts b/src/classes/ChannelWebhook.ts index f59b2396..7bf1696d 100644 --- a/src/classes/ChannelWebhook.ts +++ b/src/classes/ChannelWebhook.ts @@ -1,6 +1,9 @@ import { ChannelWebhookCollection } from "../collections/ChannelWebhookCollection.js"; import { hydrate } from "../hydration/index.js"; +import { Channel } from "./Channel.js"; +import { File } from "./File.js"; + /** * Channel Webhook Class */ @@ -21,28 +24,28 @@ export class ChannelWebhook { /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Webhook name */ - get name() { + get name(): string { return this.#collection.getUnderlyingObject(this.id).name; } /** * Webhook avatar */ - get avatar() { + get avatar(): File | undefined { return this.#collection.getUnderlyingObject(this.id).avatar; } /** * Webhook avatar URL */ - get avatarURL() { + get avatarURL(): string | undefined { return this.#collection .getUnderlyingObject(this.id) .avatar?.createFileURL(); @@ -51,14 +54,14 @@ export class ChannelWebhook { /** * Channel ID this webhook belongs to */ - get channelId() { + get channelId(): string { return this.#collection.getUnderlyingObject(this.id).channelId; } /** * Channel this webhook belongs to */ - get channel() { + get channel(): Channel | undefined { return this.#collection.client.channels.get( this.#collection.getUnderlyingObject(this.id).channelId, ); @@ -67,7 +70,7 @@ export class ChannelWebhook { /** * Secret token for sending messages to this webhook */ - get token() { + get token(): string { return this.#collection.getUnderlyingObject(this.id).token; } @@ -75,7 +78,7 @@ export class ChannelWebhook { * Edit this webhook * TODO: not in production */ - async edit(data: unknown /*: DataEditWebhook*/) { + async edit(data: unknown /*: DataEditWebhook*/): Promise { const webhook = await this.#collection.client.api.patch( // @ts-expect-error not in prod `/webhooks/${this.id as ""}/${this.token as ""}`, @@ -93,7 +96,7 @@ export class ChannelWebhook { * Delete this webhook * TODO: not in production */ - async delete() { + async delete(): Promise { await this.#collection.client.api.delete( // @ts-expect-error not in prod `/webhooks/${this.id}/${this.token}`, diff --git a/src/classes/Emoji.ts b/src/classes/Emoji.ts index 8f578c34..8e4e8d55 100644 --- a/src/classes/Emoji.ts +++ b/src/classes/Emoji.ts @@ -1,7 +1,10 @@ +import { EmojiParent } from "revolt-api"; import { decodeTime } from "ulid"; import { EmojiCollection } from "../collections/EmojiCollection.js"; +import { User } from "./User.js"; + /** * Emoji Class */ @@ -23,35 +26,35 @@ export class Emoji { * Convert to string * @returns String */ - toString() { + toString(): string { return `:${this.id}:`; } /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Time when this emoji was created */ - get createdAt() { + get createdAt(): Date { return new Date(decodeTime(this.id)); } /** * Information about the parent of this emoji */ - get parent() { + get parent(): EmojiParent { return this.#collection.getUnderlyingObject(this.id).parent; } /** * Creator of the emoji */ - get creator() { + get creator(): User | undefined { return this.#collection.client.users.get( this.#collection.getUnderlyingObject(this.id).creatorId, ); @@ -60,28 +63,28 @@ export class Emoji { /** * Name */ - get name() { + get name(): string { return this.#collection.getUnderlyingObject(this.id).name; } /** * Whether the emoji is animated */ - get animated() { + get animated(): boolean { return this.#collection.getUnderlyingObject(this.id).animated; } /** * Whether the emoji is marked as mature */ - get mature() { + get mature(): boolean { return this.#collection.getUnderlyingObject(this.id).nsfw; } /** * Delete Emoji */ - async delete() { + async delete(): Promise { await this.#collection.client.api.delete(`/custom/emoji/${this.id}`); const emoji = this.#collection.getUnderlyingObject(this.id); diff --git a/src/classes/File.ts b/src/classes/File.ts index b78abbd4..f6c16bba 100644 --- a/src/classes/File.ts +++ b/src/classes/File.ts @@ -59,7 +59,7 @@ export class File { /** * Direct URL to the file */ - get url() { + get url(): string { return `${this.#client.configuration?.features.autumn.url}/${this.tag}/${ this.id }/${this.filename}`; @@ -68,7 +68,7 @@ export class File { /** * Download URL for the file */ - get downloadURL() { + get downloadURL(): string { return `${this.#client.configuration?.features.autumn.url}/${ this.tag }/download/${this.id}/${this.filename}`; @@ -77,7 +77,7 @@ export class File { /** * Human readable file size */ - get humanReadableSize() { + get humanReadableSize(): string { if (!this.size) return "Unknown size"; if (this.size > 1e6) { @@ -92,7 +92,7 @@ export class File { /** * Whether this file should have a spoiler */ - get isSpoiler() { + get isSpoiler(): boolean { return this.filename?.toLowerCase().startsWith("spoiler_") ?? false; } @@ -101,7 +101,7 @@ export class File { * @param forceAnimation Returns GIF if applicable (for avatars/icons) * @returns Generated URL or nothing */ - createFileURL(forceAnimation?: boolean) { + createFileURL(forceAnimation?: boolean): string | undefined { const autumn = this.#client.configuration?.features.autumn; if (!autumn?.enabled) return; diff --git a/src/classes/Invite.ts b/src/classes/Invite.ts index f8f09af0..e43268a5 100644 --- a/src/classes/Invite.ts +++ b/src/classes/Invite.ts @@ -2,6 +2,10 @@ import { Invite } from "revolt-api"; import { Client } from "../Client.js"; +import { Channel } from "./Channel.js"; +import { Server } from "./Server.js"; +import { User } from "./User.js"; + /** * Channel Invite */ @@ -66,28 +70,28 @@ export class ServerInvite extends ChannelInvite { /** * Creator of the invite */ - get creator() { + get creator(): User | undefined { return this.client!.users.get(this.creatorId); } /** * Server this invite points to */ - get server() { + get server(): Server | undefined { return this.client!.servers.get(this.serverId); } /** * Channel this invite points to */ - get channel() { + get channel(): Channel | undefined { return this.client!.channels.get(this.channelId); } /** * Delete the invite */ - async delete() { + async delete(): Promise { await this.client!.api.delete(`/invites/${this.id}`); } } diff --git a/src/classes/MFA.ts b/src/classes/MFA.ts index eb0c5438..14851bdc 100644 --- a/src/classes/MFA.ts +++ b/src/classes/MFA.ts @@ -29,21 +29,21 @@ export class MFA { * @param key key to set * @param value boolean */ - #setStore(key: keyof MultiFactorStatus, value: boolean) { + #setStore(key: keyof MultiFactorStatus, value: boolean): void { this.#store[key] = value; } /** * Whether authenticator app is enabled */ - get authenticatorEnabled() { + get authenticatorEnabled(): boolean { return this.#store.totp_mfa; } /** * Whether recovery codes are enabled */ - get recoveryEnabled() { + get recoveryEnabled(): boolean { return this.#store.recovery_active; } @@ -63,17 +63,19 @@ export class MFA { * @param params * @returns Token */ - createTicket(params: MFAResponse) { - return this.#client.api - .put("/auth/mfa/ticket", params) - .then((ticket) => new MFATicket(this.#client, ticket, this.#setStore)); + async createTicket(params: MFAResponse): Promise { + return new MFATicket( + this.#client, + await this.#client.api.put("/auth/mfa/ticket", params), + this.#setStore, + ); } /** * Enable authenticator using token generated from secret found earlier * @param token Token */ - async enableAuthenticator(token: string) { + async enableAuthenticator(token: string): Promise { await this.#client.api.put("/auth/mfa/totp", { totp_code: token }); this.#setStore("totp_mfa", true); } @@ -107,14 +109,14 @@ export class MFATicket { /** * Token */ - get token() { + get token(): string { return this.#ticket.token; } /** * Use the ticket */ - #consume() { + #consume(): void { if (this.#used) throw "Already used this ticket!"; this.#used = true; } @@ -123,7 +125,7 @@ export class MFATicket { * Fetch recovery codes * @returns List of codes */ - fetchRecoveryCodes() { + fetchRecoveryCodes(): Promise { this.#consume(); return this.#client.api.post("/auth/mfa/recovery", undefined, { headers: { @@ -136,7 +138,7 @@ export class MFATicket { * Generate new set of recovery codes * @returns List of codes */ - async generateRecoveryCodes() { + async generateRecoveryCodes(): Promise { this.#consume(); const codes = await this.#client.api.patch( @@ -157,21 +159,20 @@ export class MFATicket { * Generate new authenticator secret * @returns Secret */ - generateAuthenticatorSecret() { + async generateAuthenticatorSecret(): Promise { this.#consume(); - return this.#client.api - .post("/auth/mfa/totp", undefined, { - headers: { - "X-MFA-Ticket": this.token, - }, - }) - .then((response) => response.secret); + const response = await this.#client.api.post("/auth/mfa/totp", undefined, { + headers: { + "X-MFA-Ticket": this.token, + }, + }); + return response.secret; } /** * Disable authenticator */ - async disableAuthenticator() { + async disableAuthenticator(): Promise { this.#consume(); await this.#client.api.delete("/auth/mfa/totp", undefined, { @@ -186,7 +187,7 @@ export class MFATicket { /** * Disable account */ - disableAccount() { + disableAccount(): Promise { this.#consume(); return this.#client.api.post("/auth/account/disable", undefined, { headers: { @@ -198,7 +199,7 @@ export class MFATicket { /** * Delete account */ - deleteAccount() { + deleteAccount(): Promise { this.#consume(); return this.#client.api.post("/auth/account/delete", undefined, { headers: { diff --git a/src/classes/Message.ts b/src/classes/Message.ts index dec706af..70aaffe2 100644 --- a/src/classes/Message.ts +++ b/src/classes/Message.ts @@ -1,4 +1,5 @@ import { + Message as APIMessage, MessageWebhook as APIMessageWebhook, DataEditMessage, DataMessageSend, @@ -8,7 +9,13 @@ import { decodeTime } from "ulid"; import { Client } from "../Client.js"; import { MessageCollection } from "../collections/MessageCollection.js"; +import { Channel } from "./Channel.js"; import { File } from "./File.js"; +import { MessageEmbed } from "./MessageEmbed.js"; +import { Server } from "./Server.js"; +import { ServerMember } from "./ServerMember.js"; +import { SystemMessage } from "./SystemMessage.js"; +import { User } from "./User.js"; /** * Message Class @@ -30,49 +37,49 @@ export class Message { /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Time when this message was posted */ - get createdAt() { + get createdAt(): Date { return new Date(decodeTime(this.id)); } /** * Absolute pathname to this message in the client */ - get path() { + get path(): string { return `${this.channel?.path}/${this.id}`; } /** * URL to this message */ - get url() { + get url(): string { return this.#collection.client.configuration?.app + this.path; } /** * Nonce value */ - get nonce() { + get nonce(): string | undefined { return this.#collection.getUnderlyingObject(this.id).nonce; } /** * Id of channel this message was sent in */ - get channelId() { + get channelId(): string { return this.#collection.getUnderlyingObject(this.id).channelId; } /** * Channel this message was sent in */ - get channel() { + get channel(): Channel | undefined { return this.#collection.client.channels.get( this.#collection.getUnderlyingObject(this.id).channelId, ); @@ -81,14 +88,14 @@ export class Message { /** * Server this message was sent in */ - get server() { + get server(): Server | undefined { return this.channel?.server; } /** * Member this message was sent by */ - get member() { + get member(): ServerMember | undefined { return this.#collection.client.serverMembers.getByKey({ server: this.channel?.serverId as string, user: this.authorId!, @@ -98,14 +105,14 @@ export class Message { /** * Id of user or webhook this message was sent by */ - get authorId() { + get authorId(): string | undefined { return this.#collection.getUnderlyingObject(this.id).authorId; } /** * User this message was sent by */ - get author() { + get author(): User | undefined { return this.#collection.client.users.get( this.#collection.getUnderlyingObject(this.id).authorId!, ); @@ -114,98 +121,98 @@ export class Message { /** * Webhook information for this message */ - get webhook() { + get webhook(): MessageWebhook | undefined { return this.#collection.getUnderlyingObject(this.id).webhook!; } /** * Content */ - get content() { + get content(): string { return this.#collection.getUnderlyingObject(this.id).content ?? ""; } /** * System message content */ - get systemMessage() { + get systemMessage(): SystemMessage | undefined { return this.#collection.getUnderlyingObject(this.id).systemMessage; } /** * Attachments */ - get attachments() { + get attachments(): File[] | undefined { return this.#collection.getUnderlyingObject(this.id).attachments; } /** * Time at which this message was edited */ - get editedAt() { + get editedAt(): Date | undefined { return this.#collection.getUnderlyingObject(this.id).editedAt; } /** * Embeds */ - get embeds() { + get embeds(): MessageEmbed[] | undefined { return this.#collection.getUnderlyingObject(this.id).embeds; } /** * IDs of users this message mentions */ - get mentionIds() { + get mentionIds(): string[] | undefined { return this.#collection.getUnderlyingObject(this.id).mentionIds; } /** * Whether this message mentions us */ - get mentioned() { + get mentioned(): boolean | undefined { return this.mentionIds?.includes(this.#collection.client.user!.id); } /** * IDs of messages this message replies to */ - get replyIds() { + get replyIds(): string[] | undefined { return this.#collection.getUnderlyingObject(this.id).replyIds; } /** * Reactions */ - get reactions() { + get reactions(): Map> { return this.#collection.getUnderlyingObject(this.id).reactions; } /** * Interactions */ - get interactions() { + get interactions(): APIMessage["interactions"] { return this.#collection.getUnderlyingObject(this.id).interactions; } /** * Masquerade */ - get masquerade() { + get masquerade(): APIMessage["masquerade"] { return this.#collection.getUnderlyingObject(this.id).masquerade; } /** * Flags */ - get flags() { + get flags(): number { return this.#collection.getUnderlyingObject(this.id).flags || 0; } /** * Get the username for this message */ - get username() { + get username(): string | undefined { const webhook = this.webhook; return ( @@ -219,14 +226,14 @@ export class Message { /** * Get the role colour for this message */ - get roleColour() { + get roleColour(): string | null | undefined { return this.masquerade?.colour ?? this.member?.roleColour; } /** * Get the avatar URL for this message */ - get avatarURL() { + get avatarURL(): string | undefined { const webhook = this.webhook; return ( @@ -240,7 +247,7 @@ export class Message { /** * Get the animated avatar URL for this message */ - get animatedAvatarURL() { + get animatedAvatarURL(): string | undefined { const webhook = this.webhook; return ( @@ -256,7 +263,7 @@ export class Message { /** * Avatar URL from the masquerade */ - get masqueradeAvatarURL() { + get masqueradeAvatarURL(): string | undefined { const avatar = this.masquerade?.avatar; return avatar ? this.#collection.client.proxyFile(avatar) : undefined; } @@ -264,7 +271,7 @@ export class Message { /** * Whether this message has suppressed desktop/push notifications */ - get isSuppressed() { + get isSuppressed(): boolean { return (this.flags & 1) === 1; } @@ -272,7 +279,7 @@ export class Message { * Edit a message * @param data Message edit route data */ - async edit(data: DataEditMessage) { + async edit(data: DataEditMessage): Promise { return await this.#collection.client.api.patch( `/channels/${this.channelId as ""}/messages/${this.id as ""}`, data, @@ -282,7 +289,7 @@ export class Message { /** * Delete a message */ - async delete() { + async delete(): Promise { return await this.#collection.client.api.delete( `/channels/${this.channelId as ""}/messages/${this.id as ""}`, ); @@ -291,7 +298,7 @@ export class Message { /** * Acknowledge this message as read */ - ack() { + ack(): void { this.channel?.ack(this); } @@ -305,7 +312,7 @@ export class Message { nonce?: string; }), mention = true, - ) { + ): Promise | undefined { const obj = typeof data === "string" ? { content: data } : data; return this.channel?.sendMessage({ ...obj, @@ -316,7 +323,7 @@ export class Message { /** * Clear all reactions from this message */ - async clearReactions() { + async clearReactions(): Promise { return await this.#collection.client.api.delete( `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions`, ); @@ -326,7 +333,7 @@ export class Message { * React to a message * @param emoji Unicode or emoji ID */ - async react(emoji: string) { + async react(emoji: string): Promise { return await this.#collection.client.api.put( `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${ emoji as "" @@ -338,7 +345,7 @@ export class Message { * Un-react from a message * @param emoji Unicode or emoji ID */ - async unreact(emoji: string) { + async unreact(emoji: string): Promise { return await this.#collection.client.api.delete( `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${ emoji as "" @@ -382,7 +389,7 @@ export class MessageWebhook { /** * Get the avatar URL for this message webhook */ - get avatarURL() { + get avatarURL(): string | undefined { return ( this.avatar?.createFileURL() ?? `${this.#client.options.baseURL}/users/${this.id}/default_avatar` diff --git a/src/classes/MessageEmbed.ts b/src/classes/MessageEmbed.ts index 09bb72c6..384f2c6e 100644 --- a/src/classes/MessageEmbed.ts +++ b/src/classes/MessageEmbed.ts @@ -74,7 +74,7 @@ export class ImageEmbed extends MessageEmbed { /** * Proxied image URL */ - get proxiedURL() { + get proxiedURL(): string | undefined { return this.client?.proxyFile(this.url); } } @@ -103,7 +103,7 @@ export class VideoEmbed extends MessageEmbed { /** * Proxied video URL */ - get proxiedURL() { + get proxiedURL(): string | undefined { return this.client?.proxyFile(this.url); } } @@ -149,14 +149,14 @@ export class WebsiteEmbed extends MessageEmbed { /** * Proxied icon URL */ - get proxiedIconURL() { + get proxiedIconURL(): string | undefined { return this.iconUrl ? this.client?.proxyFile(this.iconUrl) : undefined; } /** * If special content is present, generate the embed URL */ - get embedURL() { + get embedURL(): string | undefined { switch (this.specialContent?.type) { case "YouTube": { let timestamp = ""; @@ -221,7 +221,7 @@ export class TextEmbed extends MessageEmbed { /** * Proxied icon URL */ - get proxiedIconURL() { + get proxiedIconURL(): string | undefined { return this.iconUrl ? this.client?.proxyFile(this.iconUrl) : undefined; } } diff --git a/src/classes/PublicBot.ts b/src/classes/PublicBot.ts index 42abb8f6..205caba2 100644 --- a/src/classes/PublicBot.ts +++ b/src/classes/PublicBot.ts @@ -39,7 +39,7 @@ export class PublicBot { * Add the bot to a server * @param server Server */ - addToServer(server: Server | string) { + addToServer(server: Server | string): void { this.#client.api.post(`/bots/${this.id as ""}/invite`, { server: server instanceof Server ? server.id : server, }); @@ -49,7 +49,7 @@ export class PublicBot { * Add the bot to a group * @param group Group */ - addToGroup(group: Channel | string) { + addToGroup(group: Channel | string): void { // TODO: should use GroupChannel once that is added this.#client.api.post(`/bots/${this.id as ""}/invite`, { group: group instanceof Channel ? group.id : group, diff --git a/src/classes/PublicInvite.ts b/src/classes/PublicInvite.ts index d1f2b972..bc35c9fc 100644 --- a/src/classes/PublicInvite.ts +++ b/src/classes/PublicInvite.ts @@ -4,6 +4,7 @@ import { Client } from "../Client.js"; import { ServerFlags } from "../hydration/server.js"; import { File } from "./File.js"; +import { Server } from "./Server.js"; /** * Public Channel Invite @@ -95,7 +96,7 @@ export class ServerPublicInvite extends PublicChannelInvite { /** * Join the server */ - async join() { + async join(): Promise { const existingServer = this.client!.servers.get(this.serverId); if (existingServer) return existingServer; diff --git a/src/classes/Server.ts b/src/classes/Server.ts index 43006876..6230bef7 100644 --- a/src/classes/Server.ts +++ b/src/classes/Server.ts @@ -1,4 +1,5 @@ import type { + Server as APIServer, AllMemberResponse, BannedUser, Category, @@ -8,11 +9,13 @@ import type { DataEditRole, DataEditServer, Override, + Role, } from "revolt-api"; import { decodeTime } from "ulid"; import { ServerCollection } from "../collections/ServerCollection.js"; import { hydrate } from "../hydration/index.js"; +import { ServerFlags } from "../hydration/server.js"; import { bitwiseAndEq, calculatePermission, @@ -20,6 +23,8 @@ import { import { Permission } from "../permissions/definitions.js"; import { Channel } from "./Channel.js"; +import { Emoji } from "./Emoji.js"; +import { File } from "./File.js"; import { ChannelInvite } from "./Invite.js"; import { ServerBan } from "./ServerBan.js"; import { ServerMember } from "./ServerMember.js"; @@ -46,35 +51,35 @@ export class Server { * Convert to string * @returns String */ - toString() { + toString(): string { return `<%${this.id}>`; } /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Time when this server was created */ - get createdAt() { + get createdAt(): Date { return new Date(decodeTime(this.id)); } /** * Owner's user ID */ - get ownerId() { + get ownerId(): string { return this.#collection.getUnderlyingObject(this.id).ownerId; } /** * Owner */ - get owner() { + get owner(): User | undefined { return this.#collection.client.users.get( this.#collection.getUnderlyingObject(this.id).ownerId, ); @@ -83,42 +88,42 @@ export class Server { /** * Name */ - get name() { + get name(): string { return this.#collection.getUnderlyingObject(this.id).name; } /** * Description */ - get description() { + get description(): string | undefined { return this.#collection.getUnderlyingObject(this.id).description; } /** * Icon */ - get icon() { + get icon(): File | undefined { return this.#collection.getUnderlyingObject(this.id).icon; } /** * Banner */ - get banner() { + get banner(): File | undefined { return this.#collection.getUnderlyingObject(this.id).banner; } /** * Channel IDs */ - get channelIds() { + get channelIds(): Set { return this.#collection.getUnderlyingObject(this.id).channelIds; } /** * Channels */ - get channels() { + get channels(): Channel[] { return Array.from( this.#collection.getUnderlyingObject(this.id).channelIds.values(), ) @@ -129,56 +134,56 @@ export class Server { /** * Categories */ - get categories() { + get categories(): APIServer["categories"] { return this.#collection.getUnderlyingObject(this.id).categories; } /** * System message channels */ - get systemMessages() { + get systemMessages(): APIServer["system_messages"] { return this.#collection.getUnderlyingObject(this.id).systemMessages; } /** * Roles */ - get roles() { + get roles(): Map { return this.#collection.getUnderlyingObject(this.id).roles; } /** * Default permissions */ - get defaultPermissions() { + get defaultPermissions(): number { return this.#collection.getUnderlyingObject(this.id).defaultPermissions; } /** * Server flags */ - get flags() { + get flags(): ServerFlags { return this.#collection.getUnderlyingObject(this.id).flags; } /** * Whether analytics are enabled for this server */ - get analytics() { + get analytics(): boolean { return this.#collection.getUnderlyingObject(this.id).analytics; } /** * Whether this server is publicly discoverable */ - get discoverable() { + get discoverable(): boolean { return this.#collection.getUnderlyingObject(this.id).discoverable; } /** * Whether this server is marked as mature */ - get mature() { + get mature(): boolean { return this.#collection.getUnderlyingObject(this.id).nsfw; } @@ -251,7 +256,7 @@ export class Server { * ranking roles. This is dictated by the "rank" property * which is smaller for higher priority roles. */ - get orderedRoles() { + get orderedRoles(): Role[] { const roles = this.roles; return roles ? [...roles.entries()] @@ -264,7 +269,7 @@ export class Server { * Check whether the server is currently unread * @returns Whether the server is unread */ - get unread() { + get unread(): Channel | undefined { return this.channels.find((channel) => channel.unread); } @@ -272,7 +277,7 @@ export class Server { * Find all message IDs of unread messages * @returns Array of message IDs which are unread */ - get mentions() { + get mentions(): string[] { const arr = this.channels.map((channel) => Array.from(channel.mentions?.values() ?? []), ); @@ -283,28 +288,28 @@ export class Server { /** * URL to the server's icon */ - get iconURL() { + get iconURL(): string | undefined { return this.icon?.createFileURL(); } /** * URL to the server's animated icon */ - get animatedIconURL() { + get animatedIconURL(): string | undefined { return this.icon?.createFileURL(true); } /** * URL to the server's banner */ - get bannerURL() { + get bannerURL(): string | undefined { return this.banner?.createFileURL(); } /** * Own member object for this server */ - get member() { + get member(): ServerMember | undefined { return this.#collection.client.serverMembers.getByKey({ server: this.id, user: this.#collection.client.user!.id, @@ -314,7 +319,7 @@ export class Server { /** * Permission the currently authenticated user has against this server */ - get permission() { + get permission(): number { return calculatePermission(this.#collection.client, this); } @@ -323,7 +328,7 @@ export class Server { * @param permission Permission Names * @returns Whether we have this permission */ - havePermission(...permission: (keyof typeof Permission)[]) { + havePermission(...permission: (keyof typeof Permission)[]): boolean { return bitwiseAndEq( this.permission, ...permission.map((x) => Permission[x]), @@ -335,7 +340,7 @@ export class Server { * @param permission Permission Names * @returns Whether we have one of the permissions */ - orPermission(...permission: (keyof typeof Permission)[]) { + orPermission(...permission: (keyof typeof Permission)[]): boolean { return ( permission.findIndex((x) => bitwiseAndEq(this.permission, Permission[x]), @@ -348,7 +353,7 @@ export class Server { * @param userId User's ID * @returns Server Member (if cached) */ - getMember(userId: string) { + getMember(userId: string): ServerMember | undefined { return this.#collection.client.serverMembers.getByKey({ server: this.id, user: userId, @@ -360,7 +365,7 @@ export class Server { * @param data Channel create route data * @returns The newly-created channel */ - async createChannel(data: DataCreateServerChannel) { + async createChannel(data: DataCreateServerChannel): Promise { const channel = await this.#collection.client.api.post( `/servers/${this.id as ""}/channels`, data, @@ -373,7 +378,7 @@ export class Server { * Edit a server * @param data Changes */ - async edit(data: DataEditServer) { + async edit(data: DataEditServer): Promise { this.#collection.setUnderlyingObject( this.id, hydrate( @@ -392,7 +397,7 @@ export class Server { * Delete the underlying server * @param leaveEvent Whether we are leaving */ - $delete(leaveEvent?: boolean) { + $delete(leaveEvent?: boolean): void { const server = this.#collection.client.servers.getUnderlyingObject(this.id); // Avoid race conditions @@ -415,7 +420,7 @@ export class Server { * Delete or leave a server * @param leaveSilently Whether to not send a message on leave */ - async delete(leaveSilently?: boolean) { + async delete(leaveSilently?: boolean): Promise { await this.#collection.client.api.delete(`/servers/${this.id as ""}`, { leave_silently: leaveSilently, }); @@ -426,7 +431,7 @@ export class Server { /** * Mark a server as read */ - async ack() { + async ack(): Promise { for (const channel of this.channels) { channel.ack(undefined, false, true); } @@ -442,7 +447,7 @@ export class Server { async banUser( user: string | User | ServerMember, options: DataBanCreate = {}, - ) { + ): Promise { const userId = user instanceof User ? user.id @@ -462,7 +467,7 @@ export class Server { * Kick user from this server * @param user User */ - async kickUser(user: string | User | ServerMember) { + async kickUser(user: string | User | ServerMember): Promise { return await this.#collection.client.api.delete( `/servers/${this.id as ""}/members/${ typeof user === "string" @@ -478,7 +483,7 @@ export class Server { * Pardon user's ban * @param user User */ - async unbanUser(user: string | User) { + async unbanUser(user: string | User): Promise { const userId = user instanceof User ? user.id : user; return await this.#collection.client.api.delete( `/servers/${this.id as ""}/bans/${userId}`, @@ -489,7 +494,7 @@ export class Server { * Fetch a server's invites * @returns An array of the server's invites */ - async fetchInvites() { + async fetchInvites(): Promise { const invites = await this.#collection.client.api.get( `/servers/${this.id as ""}/invites`, ); @@ -503,7 +508,7 @@ export class Server { * Fetch a server's bans * @returns An array of the server's bans. */ - async fetchBans() { + async fetchBans(): Promise { const { users, bans } = await this.#collection.client.api.get( `/servers/${this.id as ""}/bans`, ); @@ -524,7 +529,10 @@ export class Server { * @param roleId Role Id, set to 'default' to affect all users * @param permissions Permission value */ - async setPermissions(roleId = "default", permissions: Override | number) { + async setPermissions( + roleId = "default", + permissions: Override | number, + ): Promise { return await this.#collection.client.api.put( `/servers/${this.id as ""}/permissions/${roleId as ""}`, { permissions: permissions as Override }, @@ -535,7 +543,7 @@ export class Server { * Create role * @param name Role name */ - async createRole(name: string) { + async createRole(name: string): Promise<{ id: string; role: Role }> { return await this.#collection.client.api.post( `/servers/${this.id as ""}/roles`, { @@ -549,7 +557,7 @@ export class Server { * @param roleId Role ID * @param data Role editing route data */ - async editRole(roleId: string, data: DataEditRole) { + async editRole(roleId: string, data: DataEditRole): Promise { return await this.#collection.client.api.patch( `/servers/${this.id as ""}/roles/${roleId as ""}`, data, @@ -560,7 +568,7 @@ export class Server { * Delete role * @param roleId Role ID */ - async deleteRole(roleId: string) { + async deleteRole(roleId: string): Promise { return await this.#collection.client.api.delete( `/servers/${this.id as ""}/roles/${roleId as ""}`, ); @@ -571,7 +579,7 @@ export class Server { * @param user User * @returns Server member object */ - async fetchMember(user: User | string) { + async fetchMember(user: User | string): Promise { const userId = typeof user === "string" ? user : user.id; const existing = this.#collection.client.serverMembers.getByKey({ server: this.id, @@ -588,7 +596,7 @@ export class Server { * Optimised member fetch route * @param excludeOffline */ - async syncMembers(excludeOffline?: boolean) { + async syncMembers(excludeOffline?: boolean): Promise { if (this.#synced && (this.#synced === "full" || excludeOffline)) return; const data = await this.#collection.client.api.get( @@ -624,7 +632,7 @@ export class Server { /** * Reset member sync status */ - resetSyncStatus() { + resetSyncStatus(): void { this.#synced = undefined; } @@ -632,7 +640,7 @@ export class Server { * Fetch a server's members * @returns List of the server's members and their user objects */ - async fetchMembers() { + async fetchMembers(): Promise<{ members: ServerMember[]; users: User[] }> { const data = (await this.#collection.client.api.get( // @ts-expect-error TODO weird typing issue `/servers/${this.id as ""}/members`, @@ -653,7 +661,9 @@ export class Server { * @param query Name * @returns List of the server's members and their user objects */ - async queryMembersExperimental(query: string) { + async queryMembersExperimental( + query: string, + ): Promise<{ members: ServerMember[]; users: User[] }> { const data = (await this.#collection.client.api.get( `/servers/${ this.id as "" @@ -680,7 +690,7 @@ export class Server { async createEmoji( autumnId: string, options: Omit, - ) { + ): Promise { const emoji = await this.#collection.client.api.put( `/custom/emoji/${autumnId as ""}`, { @@ -699,7 +709,7 @@ export class Server { * Fetch a server's emoji * @returns List of server emoji */ - async fetchEmojis() { + async fetchEmojis(): Promise { const emojis = await this.#collection.client.api.get( `/servers/${this.id as ""}/emojis`, ); @@ -713,7 +723,9 @@ export class Server { * Delete emoji * @param emojiId Emoji ID */ - async deleteEmoji(emojiId: string) { - return await this.#collection.client.api.delete(`/custom/emoji/${emojiId}`); + async deleteEmoji(emojiId: string): Promise { + return (await this.#collection.client.api.delete( + `/custom/emoji/${emojiId}`, + )) as void; } } diff --git a/src/classes/ServerBan.ts b/src/classes/ServerBan.ts index a2909b35..40fb6c99 100644 --- a/src/classes/ServerBan.ts +++ b/src/classes/ServerBan.ts @@ -7,6 +7,7 @@ import { import { Client } from "../Client.js"; import { BannedUser } from "./BannedUser.js"; +import { Server } from "./Server.js"; /** * Server Ban @@ -32,14 +33,14 @@ export class ServerBan { /** * Server */ - get server() { + get server(): Server | undefined { return this.client.servers.get(this.id.server); } /** * Remove this server ban */ - async pardon() { + async pardon(): Promise { await this.client.api.delete( `/servers/${this.id.server as ""}/bans/${this.id.user as ""}`, ); diff --git a/src/classes/ServerMember.ts b/src/classes/ServerMember.ts index 78711838..98bb7086 100644 --- a/src/classes/ServerMember.ts +++ b/src/classes/ServerMember.ts @@ -2,6 +2,7 @@ import type { DataBanCreate, DataMemberEdit, MemberCompositeKey, + Role, } from "revolt-api"; import { ServerMemberCollection } from "../collections/ServerMemberCollection.js"; @@ -12,14 +13,16 @@ import { import { Permission } from "../permissions/definitions.js"; import { Channel } from "./Channel.js"; +import { File } from "./File.js"; import { Server } from "./Server.js"; +import { User } from "./User.js"; /** * Deterministic conversion of member composite key to string ID * @param key Key * @returns String key */ -function key(key: MemberCompositeKey) { +function key(key: MemberCompositeKey): string { return key.server + key.user; } @@ -44,70 +47,70 @@ export class ServerMember { * Convert to string * @returns String */ - toString() { + toString(): string { return `<@${this.id.user}>`; } /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !this.#collection.getUnderlyingObject(key(this.id)).id; } /** * Server this member belongs to */ - get server() { + get server(): Server | undefined { return this.#collection.client.servers.get(this.id.server); } /** * User corresponding to this member */ - get user() { + get user(): User | undefined { return this.#collection.client.users.get(this.id.user); } /** * When this user joined the server */ - get joinedAt() { + get joinedAt(): Date { return this.#collection.getUnderlyingObject(key(this.id)).joinedAt; } /** * Nickname */ - get nickname() { + get nickname(): string | undefined { return this.#collection.getUnderlyingObject(key(this.id)).nickname; } /** * Avatar */ - get avatar() { + get avatar(): File | undefined { return this.#collection.getUnderlyingObject(key(this.id)).avatar; } /** * List of role IDs */ - get roles() { + get roles(): string[] { return this.#collection.getUnderlyingObject(key(this.id)).roles; } /** * Time at which timeout expires */ - get timeout() { + get timeout(): Date | undefined { return this.#collection.getUnderlyingObject(key(this.id)).timeout; } /** * Ordered list of roles for this member, from lowest to highest priority. */ - get orderedRoles() { + get orderedRoles(): Partial[] { const server = this.server!; return ( this.roles @@ -122,7 +125,7 @@ export class ServerMember { /** * Member's currently hoisted role. */ - get hoistedRole() { + get hoistedRole(): Partial | null { const roles = this.orderedRoles.filter((x) => x.hoist); if (roles.length > 0) { return roles[roles.length - 1]; @@ -134,7 +137,7 @@ export class ServerMember { /** * Member's current role colour. */ - get roleColour() { + get roleColour(): string | null | undefined { const roles = this.orderedRoles.filter((x) => x.colour); if (roles.length > 0) { return roles[roles.length - 1].colour; @@ -147,7 +150,7 @@ export class ServerMember { * Member's ranking * Smaller values are ranked as higher priority */ - get ranking() { + get ranking(): number { if (this.id.user === this.server?.ownerId) { return -Infinity; } @@ -165,7 +168,7 @@ export class ServerMember { * @param target Target object to check permissions against * @returns Permissions that this member has */ - getPermissions(target: Server | Channel) { + getPermissions(target: Server | Channel): number { return calculatePermission(this.#collection.client, target, { member: this, }); @@ -180,7 +183,7 @@ export class ServerMember { hasPermission( target: Server | Channel, ...permission: (keyof typeof Permission)[] - ) { + ): boolean { return bitwiseAndEq( this.getPermissions(target), ...permission.map((x) => Permission[x]), @@ -192,28 +195,28 @@ export class ServerMember { * @param target The member to compare against * @returns Whether this member is inferior to the target */ - inferiorTo(target: ServerMember) { + inferiorTo(target: ServerMember): boolean { return target.ranking < this.ranking; } /** * Display name */ - get displayName() { + get displayName(): string | undefined { return this.nickname ?? this.user?.displayName; } /** * URL to the member's avatar */ - get avatarURL() { + get avatarURL(): string | undefined { return this.avatar?.createFileURL() ?? this.user?.avatarURL; } /** * URL to the member's animated avatar */ - get animatedAvatarURL() { + get animatedAvatarURL(): string | undefined { return this.avatar?.createFileURL(true) ?? this.user?.animatedAvatarURL; } @@ -221,7 +224,7 @@ export class ServerMember { * Edit a member * @param data Changes */ - async edit(data: DataMemberEdit) { + async edit(data: DataMemberEdit): Promise { await this.#collection.client.api.patch( `/servers/${this.id.server as ""}/members/${this.id.user as ""}`, data, @@ -232,14 +235,14 @@ export class ServerMember { * Ban this member from the server * @param options Ban options */ - async ban(options: DataBanCreate) { + async ban(options: DataBanCreate): Promise { this.server?.banUser(this, options); } /** * Kick this member from the server */ - async kick() { + async kick(): Promise { this.server?.kickUser(this); } } diff --git a/src/classes/Session.ts b/src/classes/Session.ts index fee4ec85..3c7c5e3f 100644 --- a/src/classes/Session.ts +++ b/src/classes/Session.ts @@ -23,35 +23,35 @@ export class Session { * Convert to string * @returns String */ - toString() { + toString(): string { return this.name; } /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Time when this session was created */ - get createdAt() { + get createdAt(): Date { return new Date(decodeTime(this.id)); } /** * Whether this is the current session */ - get current() { + get current(): boolean { return this.id === this.#collection.client.sessionId; } /** * Name */ - get name() { + get name(): string { return this.#collection.getUnderlyingObject(this.id).name; } @@ -59,7 +59,7 @@ export class Session { * Rename a session * @param name New name */ - async rename(name: string) { + async rename(name: string): Promise { await this.#collection.client.api.patch(`/auth/session/${this.id}`, { friendly_name: name, }); @@ -70,7 +70,7 @@ export class Session { /** * Delete a session */ - async delete() { + async delete(): Promise { await this.#collection.client.api.delete(`/auth/session/${this.id as ""}`); this.#collection.delete(this.id); } diff --git a/src/classes/SystemMessage.ts b/src/classes/SystemMessage.ts index 1afc8c5d..796c26fa 100644 --- a/src/classes/SystemMessage.ts +++ b/src/classes/SystemMessage.ts @@ -2,6 +2,8 @@ import { SystemMessage as APISystemMessage } from "revolt-api"; import { Client } from "../Client.js"; +import { User } from "./User.js"; + /** * System Message */ @@ -103,7 +105,7 @@ export class UserSystemMessage extends SystemMessage { /** * User this message concerns */ - get user() { + get user(): User | undefined { return this.client!.users.get(this.userId); } } @@ -132,8 +134,7 @@ export class UserModeratedSystemMessage extends UserSystemMessage { /** * User this action was performed by */ - get by() { - console.info("deez!", this.byId); + get by(): User | undefined { return this.client!.users.get(this.byId); } } @@ -165,7 +166,7 @@ export class ChannelEditSystemMessage extends SystemMessage { /** * User this action was performed by */ - get by() { + get by(): User | undefined { return this.client!.users.get(this.byId); } } @@ -218,14 +219,14 @@ export class ChannelOwnershipChangeSystemMessage extends SystemMessage { /** * User giving away channel ownership */ - get from() { + get from(): User | undefined { return this.client!.users.get(this.fromId); } /** * User receiving channel ownership */ - get to() { + get to(): User | undefined { return this.client!.users.get(this.toId); } } diff --git a/src/classes/User.ts b/src/classes/User.ts index 51b1d797..cba46d69 100644 --- a/src/classes/User.ts +++ b/src/classes/User.ts @@ -1,9 +1,17 @@ -import { DataEditUser, Presence } from "revolt-api"; +import { + User as APIUser, + DataEditUser, + Presence, + RelationshipStatus, +} from "revolt-api"; import { decodeTime } from "ulid"; import { UserCollection } from "../collections/UserCollection.js"; +import { UserBadges, UserFlags } from "../hydration/user.js"; import { U32_MAX, UserPermission } from "../permissions/definitions.js"; +import { Channel } from "./Channel.js"; +import { File } from "./File.js"; import { UserProfile } from "./UserProfile.js"; /** @@ -27,42 +35,42 @@ export class User { * Write to string as a user mention * @returns Formatted String */ - toString() { + toString(): string { return `<@${this.id}>`; } /** * Whether this object exists */ - get $exists() { + get $exists(): boolean { return !!this.#collection.getUnderlyingObject(this.id).id; } /** * Time when this user created their account */ - get createdAt() { + get createdAt(): Date { return new Date(decodeTime(this.id)); } /** * Username */ - get username() { + get username(): string { return this.#collection.getUnderlyingObject(this.id).username; } /** * Discriminator */ - get discriminator() { + get discriminator(): string { return this.#collection.getUnderlyingObject(this.id).discriminator; } /** * Display Name */ - get displayName() { + get displayName(): string { return ( this.#collection.getUnderlyingObject(this.id).displayName ?? this.#collection.getUnderlyingObject(this.id).username @@ -72,21 +80,23 @@ export class User { /** * Avatar */ - get avatar() { + get avatar(): File | undefined { return this.#collection.getUnderlyingObject(this.id).avatar; } /** * Badges */ - get badges() { + get badges(): UserBadges { return this.#collection.getUnderlyingObject(this.id).badges; } /** * User Status */ - get status() { + get status(): + | { text?: string | null; presence?: Presence | null } + | undefined { // TODO: issue with API, upstream fix required #319 if (!this.online) { return { text: undefined, presence: "Invisible" as const }; @@ -97,70 +107,70 @@ export class User { /** * Relationship with user */ - get relationship() { + get relationship(): RelationshipStatus { return this.#collection.getUnderlyingObject(this.id).relationship; } /** * Whether the user is online */ - get online() { + get online(): boolean { return this.#collection.getUnderlyingObject(this.id).online; } /** * Whether the user is privileged */ - get privileged() { + get privileged(): boolean { return this.#collection.getUnderlyingObject(this.id).privileged; } /** * Flags */ - get flags() { + get flags(): UserFlags { return this.#collection.getUnderlyingObject(this.id).flags; } /** * Bot information */ - get bot() { + get bot(): { owner: string } | undefined { return this.#collection.getUnderlyingObject(this.id).bot; } /** * Whether this user is ourselves */ - get self() { + get self(): boolean { return this.#collection.client.user === this; } /** * URL to the user's default avatar */ - get defaultAvatarURL() { + get defaultAvatarURL(): string { return `${this.#collection.client.options.baseURL}/users/${this.id}/default_avatar`; } /** * URL to the user's avatar */ - get avatarURL() { + get avatarURL(): string { return this.avatar?.createFileURL() ?? this.defaultAvatarURL; } /** * URL to the user's animated avatar */ - get animatedAvatarURL() { + get animatedAvatarURL(): string { return this.avatar?.createFileURL(true) ?? this.defaultAvatarURL; } /** * Presence */ - get presence() { + get presence(): Presence { return this.online ? (this.status?.presence ?? "Online") : "Invisible"; } @@ -169,7 +179,9 @@ export class User { * @param translate Translation function * @returns Status message */ - statusMessage(translate: (presence: Presence) => string = (a) => a) { + statusMessage( + translate: (presence: Presence) => string = (a) => a, + ): string | undefined { return this.online ? (this.status?.text ?? (this.presence === "Focus" ? translate("Focus") : undefined)) @@ -179,7 +191,7 @@ export class User { /** * Permissions against this user */ - get permission() { + get permission(): number { let permissions = 0; switch (this.relationship) { case "Friend": @@ -217,7 +229,7 @@ export class User { * Edit the user * @param data Changes */ - async edit(data: DataEditUser) { + async edit(data: DataEditUser): Promise { await this.#collection.client.api.patch( `/users/${ this.id === this.#collection.client.user?.id ? "@me" : this.id @@ -231,7 +243,7 @@ export class User { * @param username New username * @param password Current password */ - async changeUsername(username: string, password: string) { + async changeUsername(username: string, password: string): Promise { return await this.#collection.client.api.patch("/users/@me/username", { username, password, @@ -242,7 +254,7 @@ export class User { * Open a DM with a user * @returns DM Channel */ - async openDM() { + async openDM(): Promise { let dm = [...this.#collection.client.channels.values()].find( (x) => x.type === "DirectMessage" && x.recipient == this, ); @@ -269,7 +281,7 @@ export class User { /** * Send a friend request to a user */ - async addFriend() { + async addFriend(): Promise { const user = await this.#collection.client.api.post(`/users/friend`, { username: this.username + "#" + this.discriminator, }); @@ -280,21 +292,21 @@ export class User { /** * Remove a user from the friend list */ - async removeFriend() { + async removeFriend(): Promise { await this.#collection.client.api.delete(`/users/${this.id as ""}/friend`); } /** * Block a user */ - async blockUser() { + async blockUser(): Promise { await this.#collection.client.api.put(`/users/${this.id as ""}/block`); } /** * Unblock a user */ - async unblockUser() { + async unblockUser(): Promise { await this.#collection.client.api.delete(`/users/${this.id as ""}/block`); } @@ -302,7 +314,7 @@ export class User { * Fetch the profile of a user * @returns The profile of the user */ - async fetchProfile() { + async fetchProfile(): Promise { return new UserProfile( this.#collection.client, await this.#collection.client.api.get(`/users/${this.id as ""}/profile`), @@ -313,7 +325,7 @@ export class User { * Fetch the mutual connections of the current user and a target user * @returns The mutual connections of the current user and a target user */ - async fetchMutual() { + async fetchMutual(): Promise<{ users: string[]; servers: string[] }> { return await this.#collection.client.api.get( `/users/${this.id as ""}/mutual`, ); diff --git a/src/classes/UserProfile.ts b/src/classes/UserProfile.ts index 7ff5e7f3..4f9fc288 100644 --- a/src/classes/UserProfile.ts +++ b/src/classes/UserProfile.ts @@ -26,14 +26,14 @@ export class UserProfile { /** * URL to the user's banner */ - get bannerURL() { + get bannerURL(): string | undefined { return this.banner?.createFileURL(); } /** * URL to the user's animated banner */ - get animatedBannerURL() { + get animatedBannerURL(): string | undefined { return this.banner?.createFileURL(true); } } diff --git a/src/collections/Collection.ts b/src/collections/Collection.ts index 0cf499a6..4f9bd205 100644 --- a/src/collections/Collection.ts +++ b/src/collections/Collection.ts @@ -31,7 +31,7 @@ export class Collection { /** * Set a key of an underlying object */ - setUnderlyingKey(id: string, key: K, value: V[K]) { + setUnderlyingKey(id: string, key: K, value: V[K]): void { this.#storage.set(id, { [key]: value, ...((this.#storage.get(id) ?? {}) as V), @@ -41,7 +41,7 @@ export class Collection { /** * Set an underlying object */ - setUnderlyingObject(id: string, value: V) { + setUnderlyingObject(id: string, value: V): void { this.#storage.set(id, value); } diff --git a/src/events/EventClient.ts b/src/events/EventClient.ts index fb5f38a9..bb3c6d95 100644 --- a/src/events/EventClient.ts +++ b/src/events/EventClient.ts @@ -121,7 +121,7 @@ export class EventClient extends EventEmitter< * Set the current state * @param state state */ - private setState(state: ConnectionState) { + private setState(state: ConnectionState): void { this.state = state; this.emit("state", state); } @@ -131,7 +131,7 @@ export class EventClient extends EventEmitter< * @param uri WebSocket URI * @param token Authentication token */ - connect(uri: string, token: string) { + connect(uri: string, token: string): void { this.disconnect(); this.#lastError = undefined; this.setState(ConnectionState.Connecting); @@ -183,7 +183,7 @@ export class EventClient extends EventEmitter< /** * Disconnect the websocket client. */ - disconnect() { + disconnect(): void { if (!this.#socket) return; clearInterval(this.#heartbeatIntervalReference); clearInterval(this.#connectTimeoutReference); @@ -197,7 +197,7 @@ export class EventClient extends EventEmitter< * Send an event to the server. * @param event Event */ - send(event: EventProtocol["client"]) { + send(event: EventProtocol["client"]): void { if (this.options.debug) console.debug("[C->S]", event); if (!this.#socket) throw "Socket closed, trying to send."; this.#socket.send(JSON.stringify(event)); @@ -207,7 +207,7 @@ export class EventClient extends EventEmitter< * Handle events intended for client before passing them along. * @param event Event */ - handle(event: EventProtocol["server"]) { + handle(event: EventProtocol["server"]): void { if (this.options.debug) console.debug("[S->C]", event); switch (event.type) { case "Ping": @@ -257,7 +257,10 @@ export class EventClient extends EventEmitter< /** * Last error encountered by events client */ - get lastError() { + get lastError(): + | { type: "socket"; data: unknown } + | { type: "revolt"; data: Error } + | undefined { return this.#lastError; } } diff --git a/src/events/v1.ts b/src/events/v1.ts index 703387c1..113ee6b4 100644 --- a/src/events/v1.ts +++ b/src/events/v1.ts @@ -187,7 +187,7 @@ export async function handleEvent( client: Client, event: ServerMessage, setReady: (value: boolean) => void, -) { +): Promise { if (client.options.debug) { console.debug("[S->C]", event); } diff --git a/src/hydration/index.ts b/src/hydration/index.ts index ea4e7596..92d24a6a 100644 --- a/src/hydration/index.ts +++ b/src/hydration/index.ts @@ -99,10 +99,10 @@ export function hydrate( input: Partial>, context: unknown, initial?: boolean, -) { +): ExtractOutput { return hydrateInternal( hydrators[type] as never, initial ? { ...hydrators[type].initialHydration(), ...input } : input, context, - ) as ExtractOutput; + ); } diff --git a/src/permissions/calculator.ts b/src/permissions/calculator.ts index 9b99bc2c..ba4cf89b 100644 --- a/src/permissions/calculator.ts +++ b/src/permissions/calculator.ts @@ -16,7 +16,7 @@ import { * @param a Input A * @param b Inputs (OR'd together) */ -export function bitwiseAndEq(a: number, ...b: number[]) { +export function bitwiseAndEq(a: number, ...b: number[]): boolean { const value = b.reduce((prev, cur) => prev | BigInt(cur), 0n); return (value & BigInt(a)) === value; } From a42f57fc4be3080728239e46613e0031d98b4061 Mon Sep 17 00:00:00 2001 From: Jersey Date: Thu, 13 Mar 2025 22:49:49 -0400 Subject: [PATCH 4/9] chore: use type-only imports in places --- src/Client.ts | 30 ++++++++++----------- src/classes/BannedUser.ts | 4 +-- src/classes/Bot.ts | 8 +++--- src/classes/Channel.ts | 20 +++++++------- src/classes/ChannelUnread.ts | 2 +- src/classes/ChannelWebhook.ts | 6 ++--- src/classes/Emoji.ts | 6 ++--- src/classes/File.ts | 12 +++------ src/classes/Invite.ts | 10 +++---- src/classes/MFA.ts | 4 +-- src/classes/Message.ts | 30 ++++++++++----------- src/classes/MessageEmbed.ts | 16 +++++------ src/classes/PublicBot.ts | 4 +-- src/classes/PublicInvite.ts | 8 +++--- src/classes/Server.ts | 12 ++++----- src/classes/ServerBan.ts | 6 ++--- src/classes/ServerMember.ts | 16 +++++------ src/classes/Session.ts | 2 +- src/classes/SystemMessage.ts | 6 ++--- src/classes/User.ts | 10 +++---- src/classes/UserProfile.ts | 4 +-- src/collections/AccountCollection.ts | 4 +-- src/collections/BotCollection.ts | 4 +-- src/collections/ChannelCollection.ts | 4 +-- src/collections/ChannelUnreadCollection.ts | 4 +-- src/collections/ChannelWebhookCollection.ts | 4 +-- src/collections/Collection.ts | 4 +-- src/collections/EmojiCollection.ts | 4 +-- src/collections/MessageCollection.ts | 4 +-- src/collections/ServerCollection.ts | 8 ++++-- src/collections/ServerMemberCollection.ts | 4 +-- src/collections/SessionCollection.ts | 4 +-- src/collections/UserCollection.ts | 6 ++--- src/collections/index.ts | 2 +- src/events/EventClient.ts | 4 +-- src/events/v1.ts | 2 +- src/hydration/bot.ts | 4 +-- src/hydration/channel.ts | 6 ++--- src/hydration/channelUnread.ts | 4 +-- src/hydration/channelWebhook.ts | 6 ++--- src/hydration/emoji.ts | 4 +-- src/hydration/message.ts | 6 ++--- src/hydration/server.ts | 6 ++--- src/hydration/serverMember.ts | 6 ++--- src/hydration/session.ts | 4 +-- src/hydration/user.ts | 6 ++--- src/permissions/calculator.ts | 6 ++--- 47 files changed, 168 insertions(+), 168 deletions(-) diff --git a/src/Client.ts b/src/Client.ts index 9e99cb39..87900734 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,13 +1,13 @@ import EventEmitter from "eventemitter3"; import type { DataLogin, RevoltConfig } from "revolt-api"; -import { API, Role } from "revolt-api"; - -import { Channel } from "./classes/Channel.js"; -import { Emoji } from "./classes/Emoji.js"; -import { Message } from "./classes/Message.js"; -import { Server } from "./classes/Server.js"; -import { ServerMember } from "./classes/ServerMember.js"; -import { User } from "./classes/User.js"; +import { API, type Role } from "revolt-api"; + +import type { Channel } from "./classes/Channel.js"; +import type { Emoji } from "./classes/Emoji.js"; +import type { Message } from "./classes/Message.js"; +import type { Server } from "./classes/Server.js"; +import type { ServerMember } from "./classes/ServerMember.js"; +import type { User } from "./classes/User.js"; import { AccountCollection } from "./collections/AccountCollection.js"; import { BotCollection } from "./collections/BotCollection.js"; import { ChannelCollection } from "./collections/ChannelCollection.js"; @@ -22,15 +22,15 @@ import { UserCollection } from "./collections/UserCollection.js"; import { ConnectionState, EventClient, - EventClientOptions, + type EventClientOptions, } from "./events/EventClient.js"; import { handleEvent } from "./events/v1.js"; -import { HydratedChannel } from "./hydration/channel.js"; -import { HydratedEmoji } from "./hydration/emoji.js"; -import { HydratedMessage } from "./hydration/message.js"; -import { HydratedServer } from "./hydration/server.js"; -import { HydratedServerMember } from "./hydration/serverMember.js"; -import { HydratedUser } from "./hydration/user.js"; +import type { HydratedChannel } from "./hydration/channel.js"; +import type { HydratedEmoji } from "./hydration/emoji.js"; +import type { HydratedMessage } from "./hydration/message.js"; +import type { HydratedServer } from "./hydration/server.js"; +import type { HydratedServerMember } from "./hydration/serverMember.js"; +import type { HydratedUser } from "./hydration/user.js"; import { RE_CHANNELS, RE_MENTIONS, RE_SPOILER } from "./lib/regex.js"; export type Session = { _id: string; token: string; user_id: string } | string; diff --git a/src/classes/BannedUser.ts b/src/classes/BannedUser.ts index 4059a7e0..4283cc71 100644 --- a/src/classes/BannedUser.ts +++ b/src/classes/BannedUser.ts @@ -1,6 +1,6 @@ -import { BannedUser as APIBannedUser } from "revolt-api"; +import type { BannedUser as APIBannedUser } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "./File.js"; diff --git a/src/classes/Bot.ts b/src/classes/Bot.ts index 0b165baf..d28140e4 100644 --- a/src/classes/Bot.ts +++ b/src/classes/Bot.ts @@ -1,10 +1,10 @@ -import { DataEditBot } from "revolt-api"; +import type { DataEditBot } from "revolt-api"; import { decodeTime } from "ulid"; -import { BotCollection } from "../collections/BotCollection.js"; -import { BotFlags } from "../hydration/bot.js"; +import type { BotCollection } from "../collections/BotCollection.js"; +import type { BotFlags } from "../hydration/bot.js"; -import { User } from "./User.js"; +import type { User } from "./User.js"; /** * Bot Class diff --git a/src/classes/Channel.ts b/src/classes/Channel.ts index 5a0ce445..90d220a5 100644 --- a/src/classes/Channel.ts +++ b/src/classes/Channel.ts @@ -8,22 +8,22 @@ import type { DataMessageSend, Override, } from "revolt-api"; -import { APIRoutes } from "revolt-api/dist/routes"; +import type { APIRoutes } from "revolt-api/dist/routes"; import { decodeTime, ulid } from "ulid"; -import { ChannelCollection } from "../collections/ChannelCollection.js"; +import type { ChannelCollection } from "../collections/ChannelCollection.js"; import { bitwiseAndEq, calculatePermission, } from "../permissions/calculator.js"; import { Permission } from "../permissions/definitions.js"; -import { ChannelWebhook } from "./ChannelWebhook.js"; -import { File } from "./File.js"; -import { Message } from "./Message.js"; -import { Server } from "./Server.js"; -import { ServerMember } from "./ServerMember.js"; -import { User } from "./User.js"; +import type { ChannelWebhook } from "./ChannelWebhook.js"; +import type { File } from "./File.js"; +import type { Message } from "./Message.js"; +import type { Server } from "./Server.js"; +import type { ServerMember } from "./ServerMember.js"; +import type { User } from "./User.js"; /** * Channel Class @@ -668,12 +668,12 @@ export class Channel { * @param skipNextMarking For internal usage only * @requires `SavedMessages`, `DirectMessage`, `Group`, `TextChannel` */ - async ack( + ack( message?: Message | string, skipRateLimiter?: boolean, skipRequest?: boolean, skipNextMarking?: boolean, - ): Promise { + ): void { if (!message && this.#manuallyMarked) { this.#manuallyMarked = false; return; diff --git a/src/classes/ChannelUnread.ts b/src/classes/ChannelUnread.ts index deb1b980..2d89e65f 100644 --- a/src/classes/ChannelUnread.ts +++ b/src/classes/ChannelUnread.ts @@ -1,4 +1,4 @@ -import { ChannelUnreadCollection } from "../collections/ChannelUnreadCollection.js"; +import type { ChannelUnreadCollection } from "../collections/ChannelUnreadCollection.js"; /** * Channel Unread Class diff --git a/src/classes/ChannelWebhook.ts b/src/classes/ChannelWebhook.ts index 7bf1696d..f4243ae6 100644 --- a/src/classes/ChannelWebhook.ts +++ b/src/classes/ChannelWebhook.ts @@ -1,8 +1,8 @@ -import { ChannelWebhookCollection } from "../collections/ChannelWebhookCollection.js"; +import type { ChannelWebhookCollection } from "../collections/ChannelWebhookCollection.js"; import { hydrate } from "../hydration/index.js"; -import { Channel } from "./Channel.js"; -import { File } from "./File.js"; +import type { Channel } from "./Channel.js"; +import type { File } from "./File.js"; /** * Channel Webhook Class diff --git a/src/classes/Emoji.ts b/src/classes/Emoji.ts index 8e4e8d55..7b157fee 100644 --- a/src/classes/Emoji.ts +++ b/src/classes/Emoji.ts @@ -1,9 +1,9 @@ -import { EmojiParent } from "revolt-api"; +import type { EmojiParent } from "revolt-api"; import { decodeTime } from "ulid"; -import { EmojiCollection } from "../collections/EmojiCollection.js"; +import type { EmojiCollection } from "../collections/EmojiCollection.js"; -import { User } from "./User.js"; +import type { User } from "./User.js"; /** * Emoji Class diff --git a/src/classes/File.ts b/src/classes/File.ts index f6c16bba..9907f43b 100644 --- a/src/classes/File.ts +++ b/src/classes/File.ts @@ -1,6 +1,6 @@ -import { File as APIFile, Metadata } from "revolt-api"; +import type { File as APIFile, Metadata } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; /** * Uploaded File @@ -60,18 +60,14 @@ export class File { * Direct URL to the file */ get url(): string { - return `${this.#client.configuration?.features.autumn.url}/${this.tag}/${ - this.id - }/${this.filename}`; + return `${this.#client.configuration?.features.autumn.url}/${this.tag}/${this.id}/${this.filename}`; } /** * Download URL for the file */ get downloadURL(): string { - return `${this.#client.configuration?.features.autumn.url}/${ - this.tag - }/download/${this.id}/${this.filename}`; + return `${this.#client.configuration?.features.autumn.url}/${this.tag}/download/${this.id}/${this.filename}`; } /** diff --git a/src/classes/Invite.ts b/src/classes/Invite.ts index e43268a5..df197bc1 100644 --- a/src/classes/Invite.ts +++ b/src/classes/Invite.ts @@ -1,10 +1,10 @@ -import { Invite } from "revolt-api"; +import type { Invite } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; -import { Channel } from "./Channel.js"; -import { Server } from "./Server.js"; -import { User } from "./User.js"; +import type { Channel } from "./Channel.js"; +import type { Server } from "./Server.js"; +import type { User } from "./User.js"; /** * Channel Invite diff --git a/src/classes/MFA.ts b/src/classes/MFA.ts index 14851bdc..f2c55ba0 100644 --- a/src/classes/MFA.ts +++ b/src/classes/MFA.ts @@ -1,11 +1,11 @@ -import { +import type { MFAMethod, MFAResponse, MultiFactorStatus, MFATicket as TicketType, } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; /** * Multi-Factor Authentication diff --git a/src/classes/Message.ts b/src/classes/Message.ts index 70aaffe2..073206f4 100644 --- a/src/classes/Message.ts +++ b/src/classes/Message.ts @@ -1,4 +1,4 @@ -import { +import type { Message as APIMessage, MessageWebhook as APIMessageWebhook, DataEditMessage, @@ -6,16 +6,16 @@ import { } from "revolt-api"; import { decodeTime } from "ulid"; -import { Client } from "../Client.js"; -import { MessageCollection } from "../collections/MessageCollection.js"; +import type { Client } from "../Client.js"; +import type { MessageCollection } from "../collections/MessageCollection.js"; -import { Channel } from "./Channel.js"; +import type { Channel } from "./Channel.js"; import { File } from "./File.js"; -import { MessageEmbed } from "./MessageEmbed.js"; -import { Server } from "./Server.js"; -import { ServerMember } from "./ServerMember.js"; -import { SystemMessage } from "./SystemMessage.js"; -import { User } from "./User.js"; +import type { MessageEmbed } from "./MessageEmbed.js"; +import type { Server } from "./Server.js"; +import type { ServerMember } from "./ServerMember.js"; +import type { SystemMessage } from "./SystemMessage.js"; +import type { User } from "./User.js"; /** * Message Class @@ -335,9 +335,9 @@ export class Message { */ async react(emoji: string): Promise { return await this.#collection.client.api.put( - `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${ - emoji as "" - }`, + `/channels/${this.channelId as ""}/messages/${ + this.id as "" + }/reactions/${emoji as ""}`, ); } @@ -347,9 +347,9 @@ export class Message { */ async unreact(emoji: string): Promise { return await this.#collection.client.api.delete( - `/channels/${this.channelId as ""}/messages/${this.id as ""}/reactions/${ - emoji as "" - }`, + `/channels/${this.channelId as ""}/messages/${ + this.id as "" + }/reactions/${emoji as ""}`, ); } } diff --git a/src/classes/MessageEmbed.ts b/src/classes/MessageEmbed.ts index 384f2c6e..ff31fd70 100644 --- a/src/classes/MessageEmbed.ts +++ b/src/classes/MessageEmbed.ts @@ -1,6 +1,6 @@ -import { Embed, ImageSize, Special } from "revolt-api"; +import type { Embed, ImageSize, Special } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "./File.js"; @@ -168,9 +168,9 @@ export class WebsiteEmbed extends MessageEmbed { return `https://www.youtube-nocookie.com/embed/${this.specialContent.id}?modestbranding=1${timestamp}`; } case "Twitch": - return `https://player.twitch.tv/?${this.specialContent.content_type.toLowerCase()}=${ - this.specialContent.id - }&parent=${(window ?? {})?.location?.hostname}&autoplay=false`; + return `https://player.twitch.tv/?${this.specialContent.content_type.toLowerCase()}=${this.specialContent.id}&parent=${ + (window ?? {})?.location?.hostname + }&autoplay=false`; case "Lightspeed": return `https://new.lightspeed.tv/embed/${this.specialContent.id}/stream`; case "Spotify": @@ -180,13 +180,13 @@ export class WebsiteEmbed extends MessageEmbed { this.url!, )}&color=%23FF7F50&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true`; case "Bandcamp": { - return `https://bandcamp.com/EmbeddedPlayer/${this.specialContent.content_type.toLowerCase()}=${ - this.specialContent.id - }/size=large/bgcol=181a1b/linkcol=056cc4/tracklist=false/transparent=true/`; + return `https://bandcamp.com/EmbeddedPlayer/${this.specialContent.content_type.toLowerCase()}=${this.specialContent.id}/size=large/bgcol=181a1b/linkcol=056cc4/tracklist=false/transparent=true/`; } case "Streamable": { return `https://streamable.com/e/${this.specialContent.id}?loop=0`; } + default: + return undefined; } } } diff --git a/src/classes/PublicBot.ts b/src/classes/PublicBot.ts index 205caba2..3653d3f9 100644 --- a/src/classes/PublicBot.ts +++ b/src/classes/PublicBot.ts @@ -1,6 +1,6 @@ -import { File as APIFile, PublicBot as APIPublicBot } from "revolt-api"; +import type { File as APIFile, PublicBot as APIPublicBot } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { Channel } from "./Channel.js"; import { File } from "./File.js"; diff --git a/src/classes/PublicInvite.ts b/src/classes/PublicInvite.ts index bc35c9fc..c09782c8 100644 --- a/src/classes/PublicInvite.ts +++ b/src/classes/PublicInvite.ts @@ -1,10 +1,10 @@ -import { Invite, InviteResponse } from "revolt-api"; +import type { Invite, InviteResponse } from "revolt-api"; -import { Client } from "../Client.js"; -import { ServerFlags } from "../hydration/server.js"; +import type { Client } from "../Client.js"; +import type { ServerFlags } from "../hydration/server.js"; import { File } from "./File.js"; -import { Server } from "./Server.js"; +import type { Server } from "./Server.js"; /** * Public Channel Invite diff --git a/src/classes/Server.ts b/src/classes/Server.ts index 6230bef7..c370d1bb 100644 --- a/src/classes/Server.ts +++ b/src/classes/Server.ts @@ -13,18 +13,18 @@ import type { } from "revolt-api"; import { decodeTime } from "ulid"; -import { ServerCollection } from "../collections/ServerCollection.js"; +import type { ServerCollection } from "../collections/ServerCollection.js"; import { hydrate } from "../hydration/index.js"; -import { ServerFlags } from "../hydration/server.js"; +import type { ServerFlags } from "../hydration/server.js"; import { bitwiseAndEq, calculatePermission, } from "../permissions/calculator.js"; import { Permission } from "../permissions/definitions.js"; -import { Channel } from "./Channel.js"; -import { Emoji } from "./Emoji.js"; -import { File } from "./File.js"; +import type { Channel } from "./Channel.js"; +import type { Emoji } from "./Emoji.js"; +import type { File } from "./File.js"; import { ChannelInvite } from "./Invite.js"; import { ServerBan } from "./ServerBan.js"; import { ServerMember } from "./ServerMember.js"; @@ -587,7 +587,7 @@ export class Server { }); if (existing) return existing; - return this.#collection.client.serverMembers.fetch(this.id, userId); + return await this.#collection.client.serverMembers.fetch(this.id, userId); } #synced: undefined | "partial" | "full"; diff --git a/src/classes/ServerBan.ts b/src/classes/ServerBan.ts index 40fb6c99..807f15a5 100644 --- a/src/classes/ServerBan.ts +++ b/src/classes/ServerBan.ts @@ -1,13 +1,13 @@ -import { +import type { BannedUser as APIBannedUser, ServerBan as APIServerBan, MemberCompositeKey, } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { BannedUser } from "./BannedUser.js"; -import { Server } from "./Server.js"; +import type { Server } from "./Server.js"; /** * Server Ban diff --git a/src/classes/ServerMember.ts b/src/classes/ServerMember.ts index 98bb7086..516e8104 100644 --- a/src/classes/ServerMember.ts +++ b/src/classes/ServerMember.ts @@ -5,17 +5,17 @@ import type { Role, } from "revolt-api"; -import { ServerMemberCollection } from "../collections/ServerMemberCollection.js"; +import type { ServerMemberCollection } from "../collections/ServerMemberCollection.js"; import { bitwiseAndEq, calculatePermission, } from "../permissions/calculator.js"; import { Permission } from "../permissions/definitions.js"; -import { Channel } from "./Channel.js"; -import { File } from "./File.js"; -import { Server } from "./Server.js"; -import { User } from "./User.js"; +import type { Channel } from "./Channel.js"; +import type { File } from "./File.js"; +import type { Server } from "./Server.js"; +import type { User } from "./User.js"; /** * Deterministic conversion of member composite key to string ID @@ -110,7 +110,7 @@ export class ServerMember { /** * Ordered list of roles for this member, from lowest to highest priority. */ - get orderedRoles(): Partial[] { + get orderedRoles(): (Partial & { id: string })[] { const server = this.server!; return ( this.roles @@ -235,14 +235,14 @@ export class ServerMember { * Ban this member from the server * @param options Ban options */ - async ban(options: DataBanCreate): Promise { + ban(options: DataBanCreate): void { this.server?.banUser(this, options); } /** * Kick this member from the server */ - async kick(): Promise { + kick(): void { this.server?.kickUser(this); } } diff --git a/src/classes/Session.ts b/src/classes/Session.ts index 3c7c5e3f..821529e6 100644 --- a/src/classes/Session.ts +++ b/src/classes/Session.ts @@ -1,6 +1,6 @@ import { decodeTime } from "ulid"; -import { SessionCollection } from "../collections/SessionCollection.js"; +import type { SessionCollection } from "../collections/SessionCollection.js"; /** * Session Class diff --git a/src/classes/SystemMessage.ts b/src/classes/SystemMessage.ts index 796c26fa..3dcfbc5e 100644 --- a/src/classes/SystemMessage.ts +++ b/src/classes/SystemMessage.ts @@ -1,8 +1,8 @@ -import { SystemMessage as APISystemMessage } from "revolt-api"; +import type { SystemMessage as APISystemMessage } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; -import { User } from "./User.js"; +import type { User } from "./User.js"; /** * System Message diff --git a/src/classes/User.ts b/src/classes/User.ts index cba46d69..b8439bd3 100644 --- a/src/classes/User.ts +++ b/src/classes/User.ts @@ -1,4 +1,4 @@ -import { +import type { User as APIUser, DataEditUser, Presence, @@ -6,12 +6,12 @@ import { } from "revolt-api"; import { decodeTime } from "ulid"; -import { UserCollection } from "../collections/UserCollection.js"; -import { UserBadges, UserFlags } from "../hydration/user.js"; +import type { UserCollection } from "../collections/UserCollection.js"; +import type { UserBadges, UserFlags } from "../hydration/user.js"; import { U32_MAX, UserPermission } from "../permissions/definitions.js"; -import { Channel } from "./Channel.js"; -import { File } from "./File.js"; +import type { Channel } from "./Channel.js"; +import type { File } from "./File.js"; import { UserProfile } from "./UserProfile.js"; /** diff --git a/src/classes/UserProfile.ts b/src/classes/UserProfile.ts index 4f9fc288..a2a2b7b1 100644 --- a/src/classes/UserProfile.ts +++ b/src/classes/UserProfile.ts @@ -1,6 +1,6 @@ -import { UserProfile as APIUserProfile } from "revolt-api"; +import type { UserProfile as APIUserProfile } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "./File.js"; diff --git a/src/collections/AccountCollection.ts b/src/collections/AccountCollection.ts index 40135dc2..d0029617 100644 --- a/src/collections/AccountCollection.ts +++ b/src/collections/AccountCollection.ts @@ -1,6 +1,6 @@ -import { DataCreateAccount, WebPushSubscription } from "revolt-api"; +import type { DataCreateAccount, WebPushSubscription } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { MFA } from "../classes/MFA.js"; /** diff --git a/src/collections/BotCollection.ts b/src/collections/BotCollection.ts index af1b7342..c0d02f0a 100644 --- a/src/collections/BotCollection.ts +++ b/src/collections/BotCollection.ts @@ -1,8 +1,8 @@ -import { Bot as APIBot, OwnedBotsResponse } from "revolt-api"; +import type { Bot as APIBot, OwnedBotsResponse } from "revolt-api"; import { Bot } from "../classes/Bot.js"; import { PublicBot } from "../classes/PublicBot.js"; -import { HydratedBot } from "../hydration/bot.js"; +import type { HydratedBot } from "../hydration/bot.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/ChannelCollection.ts b/src/collections/ChannelCollection.ts index c5858e13..87faf4ec 100644 --- a/src/collections/ChannelCollection.ts +++ b/src/collections/ChannelCollection.ts @@ -1,8 +1,8 @@ -import { Channel as APIChannel } from "revolt-api"; +import type { Channel as APIChannel } from "revolt-api"; import { Channel } from "../classes/Channel.js"; import { User } from "../classes/User.js"; -import { HydratedChannel } from "../hydration/channel.js"; +import type { HydratedChannel } from "../hydration/channel.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/ChannelUnreadCollection.ts b/src/collections/ChannelUnreadCollection.ts index e09d2b2c..fb13a1a1 100644 --- a/src/collections/ChannelUnreadCollection.ts +++ b/src/collections/ChannelUnreadCollection.ts @@ -1,7 +1,7 @@ -import { ChannelUnread as APIChannelUnread } from "revolt-api"; +import type { ChannelUnread as APIChannelUnread } from "revolt-api"; import { ChannelUnread } from "../classes/ChannelUnread.js"; -import { HydratedChannelUnread } from "../hydration/channelUnread.js"; +import type { HydratedChannelUnread } from "../hydration/channelUnread.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/ChannelWebhookCollection.ts b/src/collections/ChannelWebhookCollection.ts index ac6dfe10..f0da0f51 100644 --- a/src/collections/ChannelWebhookCollection.ts +++ b/src/collections/ChannelWebhookCollection.ts @@ -1,7 +1,7 @@ -import { Webhook } from "revolt-api"; +import type { Webhook } from "revolt-api"; import { ChannelWebhook } from "../classes/ChannelWebhook.js"; -import { HydratedChannelWebhook } from "../hydration/channelWebhook.js"; +import type { HydratedChannelWebhook } from "../hydration/channelWebhook.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/Collection.ts b/src/collections/Collection.ts index 4f9bd205..091fae62 100644 --- a/src/collections/Collection.ts +++ b/src/collections/Collection.ts @@ -1,5 +1,5 @@ -import { Client } from "../Client.js"; -import { Hydrators, hydrate } from "../hydration/index.js"; +import type { Client } from "../Client.js"; +import { type Hydrators, hydrate } from "../hydration/index.js"; /** * Collection backed by a store diff --git a/src/collections/EmojiCollection.ts b/src/collections/EmojiCollection.ts index 7246138e..a661c4f1 100644 --- a/src/collections/EmojiCollection.ts +++ b/src/collections/EmojiCollection.ts @@ -1,7 +1,7 @@ -import { Emoji as APIEmoji } from "revolt-api"; +import type { Emoji as APIEmoji } from "revolt-api"; import { Emoji } from "../classes/Emoji.js"; -import { HydratedEmoji } from "../hydration/emoji.js"; +import type { HydratedEmoji } from "../hydration/emoji.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/MessageCollection.ts b/src/collections/MessageCollection.ts index e3df06f6..08b8d606 100644 --- a/src/collections/MessageCollection.ts +++ b/src/collections/MessageCollection.ts @@ -1,7 +1,7 @@ -import { Message as APIMessage } from "revolt-api"; +import type { Message as APIMessage } from "revolt-api"; import { Message } from "../classes/Message.js"; -import { HydratedMessage } from "../hydration/message.js"; +import type { HydratedMessage } from "../hydration/message.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/ServerCollection.ts b/src/collections/ServerCollection.ts index b794b605..2c9f658b 100644 --- a/src/collections/ServerCollection.ts +++ b/src/collections/ServerCollection.ts @@ -1,7 +1,11 @@ -import { Server as APIServer, Channel, DataCreateServer } from "revolt-api"; +import type { + Server as APIServer, + Channel, + DataCreateServer, +} from "revolt-api"; import { Server } from "../classes/Server.js"; -import { HydratedServer } from "../hydration/server.js"; +import type { HydratedServer } from "../hydration/server.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/ServerMemberCollection.ts b/src/collections/ServerMemberCollection.ts index a5bdb65a..9312b409 100644 --- a/src/collections/ServerMemberCollection.ts +++ b/src/collections/ServerMemberCollection.ts @@ -1,7 +1,7 @@ -import { Member, MemberCompositeKey } from "revolt-api"; +import type { Member, MemberCompositeKey } from "revolt-api"; import { ServerMember } from "../classes/ServerMember.js"; -import { HydratedServerMember } from "../hydration/serverMember.js"; +import type { HydratedServerMember } from "../hydration/serverMember.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/SessionCollection.ts b/src/collections/SessionCollection.ts index 56de5497..0d638ea1 100644 --- a/src/collections/SessionCollection.ts +++ b/src/collections/SessionCollection.ts @@ -1,7 +1,7 @@ -import { SessionInfo } from "revolt-api"; +import type { SessionInfo } from "revolt-api"; import { Session } from "../classes/Session.js"; -import { HydratedSession } from "../hydration/session.js"; +import type { HydratedSession } from "../hydration/session.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/UserCollection.ts b/src/collections/UserCollection.ts index 266cd40d..b721fdce 100644 --- a/src/collections/UserCollection.ts +++ b/src/collections/UserCollection.ts @@ -1,8 +1,8 @@ -import { User as APIUser } from "revolt-api"; +import type { User as APIUser } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { User } from "../classes/User.js"; -import { HydratedUser } from "../hydration/user.js"; +import type { HydratedUser } from "../hydration/user.js"; import { Collection } from "./Collection.js"; diff --git a/src/collections/index.ts b/src/collections/index.ts index b2a79d6c..401f0677 100644 --- a/src/collections/index.ts +++ b/src/collections/index.ts @@ -2,7 +2,7 @@ export { BotCollection } from "./BotCollection.js"; export { ChannelCollection } from "./ChannelCollection.js"; export { ChannelUnreadCollection } from "./ChannelUnreadCollection.js"; export { ChannelWebhookCollection } from "./ChannelWebhookCollection.js"; -export { Collection as ClassCollection } from "./Collection.js"; +export { Collection } from "./Collection.js"; export { EmojiCollection } from "./EmojiCollection.js"; export { MessageCollection } from "./MessageCollection.js"; export { ServerCollection } from "./ServerCollection.js"; diff --git a/src/events/EventClient.ts b/src/events/EventClient.ts index bb3c6d95..07905469 100644 --- a/src/events/EventClient.ts +++ b/src/events/EventClient.ts @@ -1,7 +1,7 @@ import EventEmitter from "eventemitter3"; -import { Error } from "revolt-api"; +import type { Error } from "revolt-api"; -import { ProtocolV1 } from "./v1.js"; +import type { ProtocolV1 } from "./v1.js"; /** * Available protocols to connect with diff --git a/src/events/v1.ts b/src/events/v1.ts index 113ee6b4..ed887bab 100644 --- a/src/events/v1.ts +++ b/src/events/v1.ts @@ -15,7 +15,7 @@ import type { User, } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { MessageEmbed } from "../classes/MessageEmbed.js"; import { hydrate } from "../hydration/index.js"; diff --git a/src/hydration/bot.ts b/src/hydration/bot.ts index 78ac5892..207b97c1 100644 --- a/src/hydration/bot.ts +++ b/src/hydration/bot.ts @@ -1,6 +1,6 @@ -import { Bot } from "revolt-api"; +import type { Bot } from "revolt-api"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedBot = { id: string; diff --git a/src/hydration/channel.ts b/src/hydration/channel.ts index 6f50054f..c4338328 100644 --- a/src/hydration/channel.ts +++ b/src/hydration/channel.ts @@ -1,10 +1,10 @@ -import { Channel, OverrideField } from "revolt-api"; +import type { Channel, OverrideField } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "../classes/File.js"; import type { Merge } from "../lib/merge.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedChannel = { id: string; diff --git a/src/hydration/channelUnread.ts b/src/hydration/channelUnread.ts index 22589071..73a98720 100644 --- a/src/hydration/channelUnread.ts +++ b/src/hydration/channelUnread.ts @@ -1,8 +1,8 @@ -import { ChannelUnread } from "revolt-api"; +import type { ChannelUnread } from "revolt-api"; import type { Merge } from "../lib/merge.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedChannelUnread = { id: string; diff --git a/src/hydration/channelWebhook.ts b/src/hydration/channelWebhook.ts index fb9ab879..ecf3abfb 100644 --- a/src/hydration/channelWebhook.ts +++ b/src/hydration/channelWebhook.ts @@ -1,10 +1,10 @@ -import { Webhook } from "revolt-api"; +import type { Webhook } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "../classes/File.js"; import type { Merge } from "../lib/merge.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedChannelWebhook = { id: string; diff --git a/src/hydration/emoji.ts b/src/hydration/emoji.ts index 20d52695..85257983 100644 --- a/src/hydration/emoji.ts +++ b/src/hydration/emoji.ts @@ -1,8 +1,8 @@ -import { Emoji, EmojiParent } from "revolt-api"; +import type { Emoji, EmojiParent } from "revolt-api"; import type { Merge } from "../lib/merge.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedEmoji = { id: string; diff --git a/src/hydration/message.ts b/src/hydration/message.ts index 254aabd0..c5b76f7b 100644 --- a/src/hydration/message.ts +++ b/src/hydration/message.ts @@ -1,13 +1,13 @@ -import { Interactions, Masquerade, Message } from "revolt-api"; +import type { Interactions, Masquerade, Message } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "../classes/File.js"; import { MessageWebhook } from "../classes/Message.js"; import { MessageEmbed } from "../classes/MessageEmbed.js"; import { SystemMessage } from "../classes/SystemMessage.js"; import type { Merge } from "../lib/merge.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedMessage = { id: string; diff --git a/src/hydration/server.ts b/src/hydration/server.ts index 64e0e391..2fdaa05e 100644 --- a/src/hydration/server.ts +++ b/src/hydration/server.ts @@ -1,9 +1,9 @@ -import { Category, Role, Server, SystemMessageChannels } from "revolt-api"; +import type { Category, Role, Server, SystemMessageChannels } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "../classes/File.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedServer = { id: string; diff --git a/src/hydration/serverMember.ts b/src/hydration/serverMember.ts index e6518b0b..91cb6080 100644 --- a/src/hydration/serverMember.ts +++ b/src/hydration/serverMember.ts @@ -1,10 +1,10 @@ -import { Member, MemberCompositeKey } from "revolt-api"; +import type { Member, MemberCompositeKey } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "../classes/File.js"; import type { Merge } from "../lib/merge.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedServerMember = { id: MemberCompositeKey; diff --git a/src/hydration/session.ts b/src/hydration/session.ts index 4782c459..6c375cbb 100644 --- a/src/hydration/session.ts +++ b/src/hydration/session.ts @@ -1,6 +1,6 @@ -import { SessionInfo } from "revolt-api"; +import type { SessionInfo } from "revolt-api"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedSession = { id: string; diff --git a/src/hydration/user.ts b/src/hydration/user.ts index 7a3c7be7..e7b83db2 100644 --- a/src/hydration/user.ts +++ b/src/hydration/user.ts @@ -1,14 +1,14 @@ -import { +import type { BotInformation, RelationshipStatus, User, UserStatus, } from "revolt-api"; -import { Client } from "../Client.js"; +import type { Client } from "../Client.js"; import { File } from "../classes/File.js"; -import { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.js"; export type HydratedUser = { id: string; diff --git a/src/permissions/calculator.ts b/src/permissions/calculator.ts index ba4cf89b..dde5e10a 100644 --- a/src/permissions/calculator.ts +++ b/src/permissions/calculator.ts @@ -1,7 +1,7 @@ -import { Client } from "../Client.js"; -import { Channel } from "../classes/Channel.js"; +import type { Client } from "../Client.js"; +import type { Channel } from "../classes/Channel.js"; import { Server } from "../classes/Server.js"; -import { ServerMember } from "../classes/ServerMember.js"; +import type { ServerMember } from "../classes/ServerMember.js"; import { ALLOW_IN_TIMEOUT, From 3f4117ece0efcbbcd6c439534ca0f1ef062c203d Mon Sep 17 00:00:00 2001 From: Jersey Date: Thu, 13 Mar 2025 23:10:21 -0400 Subject: [PATCH 5/9] chore: replace `eventemitter3` with `vladfrangu/async_event_emitter` --- package.json | 8 ++-- pnpm-lock.yaml | 17 ++++---- src/Client.ts | 90 ++++++++++++++++++--------------------- src/events/EventClient.ts | 14 +++--- 4 files changed, 62 insertions(+), 67 deletions(-) diff --git a/package.json b/package.json index 08a3f9cc..ca4fc132 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "description": "Library for interacting with the Revolt API.", "packageManager": "pnpm@9.4.0", "dependencies": { - "eventemitter3": "^5.0.1", + "@vladfrangu/async_event_emitter": "^2.4.6", "revolt-api": "0.8.3", "ulid": "^2.3.0" }, @@ -31,11 +31,11 @@ "@mxssfd/typedoc-theme": "^1.1.7", "@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/node": "^22.13.10", - "eslint-plugin-prettier": "^5.2.3", "eslint": "^9.22.0", + "eslint-plugin-prettier": "^5.2.3", "prettier": "^3.5.3", "typedoc": "^0.27.9", - "typescript-eslint": "^8.26.1", - "typescript": "^5.8.2" + "typescript": "^5.8.2", + "typescript-eslint": "^8.26.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 058ede26..6ad0f638 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,9 @@ importers: .: dependencies: - eventemitter3: - specifier: ^5.0.1 - version: 5.0.1 + '@vladfrangu/async_event_emitter': + specifier: ^2.4.6 + version: 2.4.6 revolt-api: specifier: 0.8.3 version: 0.8.3 @@ -269,6 +269,10 @@ packages: resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vladfrangu/async_event_emitter@2.4.6': + resolution: {integrity: sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==} + engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -409,9 +413,6 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1008,6 +1009,8 @@ snapshots: '@typescript-eslint/types': 8.26.1 eslint-visitor-keys: 4.2.0 + '@vladfrangu/async_event_emitter@2.4.6': {} + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 @@ -1160,8 +1163,6 @@ snapshots: esutils@2.0.3: {} - eventemitter3@5.0.1: {} - fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} diff --git a/src/Client.ts b/src/Client.ts index 87900734..168732d1 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,4 +1,4 @@ -import EventEmitter from "eventemitter3"; +import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter"; import type { DataLogin, RevoltConfig } from "revolt-api"; import { API, type Role } from "revolt-api"; @@ -40,55 +40,49 @@ export type Session = { _id: string; token: string; user_id: string } | string; */ export type Events = { // eslint-disable-next-line @typescript-eslint/no-explicit-any - error(error: any): void; - - connected(): void; - connecting(): void; - disconnected(): void; - ready(): void; - logout(): void; - - messageCreate(message: Message): void; - messageUpdate(message: Message, previousMessage: HydratedMessage): void; - messageDelete(message: HydratedMessage): void; - messageDeleteBulk(messages: HydratedMessage[], channel?: Channel): void; - messageReactionAdd(message: Message, userId: string, emoji: string): void; - messageReactionRemove(message: Message, userId: string, emoji: string): void; - messageReactionRemoveEmoji(message: Message, emoji: string): void; - - channelCreate(channel: Channel): void; - channelUpdate(channel: Channel, previousChannel: HydratedChannel): void; - channelDelete(channel: HydratedChannel): void; - channelGroupJoin(channel: Channel, user: User): void; - channelGroupLeave(channel: Channel, user?: User): void; - channelStartTyping(channel: Channel, user?: User): void; - channelStopTyping(channel: Channel, user?: User): void; - channelAcknowledged(channel: Channel, messageId: string): void; - - serverCreate(server: Server): void; - serverUpdate(server: Server, previousServer: HydratedServer): void; - serverDelete(server: HydratedServer): void; - serverLeave(server: HydratedServer): void; - serverRoleUpdate(server: Server, roleId: string, previousRole: Role): void; - serverRoleDelete(server: Server, roleId: string, role: Role): void; - - serverMemberUpdate( - member: ServerMember, - previousMember: HydratedServerMember, - ): void; - serverMemberJoin(member: ServerMember): void; - serverMemberLeave(member: HydratedServerMember): void; - - userUpdate(user: User, previousUser: HydratedUser): void; + error: [any]; + + connected: []; + connecting: []; + disconnected: []; + ready: []; + logout: []; + + messageCreate: [Message]; + messageUpdate: [Message, HydratedMessage]; + messageDelete: [HydratedMessage]; + messageDeleteBulk: [HydratedMessage[], Channel?]; + messageReactionAdd: [Message, string, string]; + messageReactionRemove: [Message, string, string]; + messageReactionRemoveEmoji: [Message, string]; + + channelCreate: [Channel]; + channelUpdate: [Channel, HydratedChannel]; + channelDelete: [HydratedChannel]; + channelGroupJoin: [Channel, User]; + channelGroupLeave: [Channel, User?]; + channelStartTyping: [Channel, User?]; + channelStopTyping: [Channel, User?]; + channelAcknowledged: [Channel, string]; + + serverCreate: [Server]; + serverUpdate: [Server, HydratedServer]; + serverDelete: [HydratedServer]; + serverLeave: [HydratedServer]; + serverRoleUpdate: [Server, string, Role]; + serverRoleDelete: [Server, string, Role]; + + serverMemberUpdate: [ServerMember, HydratedServerMember]; + serverMemberJoin: [ServerMember]; + serverMemberLeave: [HydratedServerMember]; + + userUpdate: [User, HydratedUser]; // ^ userRelationshipChanged(user: User, previousRelationship: RelationshipStatus): void; // ^ userPresenceChanged(user: User, previousPresence: boolean): void; - userSettingsUpdate( - id: string, - update: Record, - ): void; + userSettingsUpdate: [string, Record]; - emojiCreate(emoji: Emoji): void; - emojiDelete(emoji: HydratedEmoji): void; + emojiCreate: [Emoji]; + emojiDelete: [HydratedEmoji]; }; /** @@ -151,7 +145,7 @@ export type ClientOptions = Partial & { /** * Revolt.js Clients */ -export class Client extends EventEmitter { +export class Client extends AsyncEventEmitter { readonly account = new AccountCollection(this); readonly bots = new BotCollection(this); readonly channels = new ChannelCollection(this); diff --git a/src/events/EventClient.ts b/src/events/EventClient.ts index 07905469..c037e719 100644 --- a/src/events/EventClient.ts +++ b/src/events/EventClient.ts @@ -1,4 +1,4 @@ -import EventEmitter from "eventemitter3"; +import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter"; import type { Error } from "revolt-api"; import type { ProtocolV1 } from "./v1.js"; @@ -63,17 +63,17 @@ export interface EventClientOptions { * Events provided by the client. */ type Events> = { - error: (error: Error) => void; - event: (event: P["server"]) => void; - state: (state: ConnectionState) => void; + error: [Error]; + event: [P["server"]]; + state: [ConnectionState]; }; /** * Simple wrapper around the Revolt websocket service. */ -export class EventClient extends EventEmitter< - Events> -> { +export class EventClient< + T extends AvailableProtocols, +> extends AsyncEventEmitter>> { readonly options: EventClientOptions; #protocolVersion: T; From c682f71125b2c118e5cdd188f07197a2beea6997 Mon Sep 17 00:00:00 2001 From: Jersey Date: Fri, 14 Mar 2025 00:30:45 -0400 Subject: [PATCH 6/9] BREAKING CHANGE: use Deno tooling --- .github/workflows/docs.yml | 18 +- .github/workflows/lint.yml | 25 +- .github/workflows/npmPublish.ts | 64 + .github/workflows/publish.yml | 31 + .gitignore | 19 +- .prettierrc | 8 - .vscode/extensions.json | 2 +- .vscode/settings.json | 4 +- README.md | 3 - deno.json | 28 + eslint.config.js | 21 - package.json | 41 - pnpm-lock.yaml | 1444 ------------------- src/Client.ts | 169 ++- src/classes/BannedUser.ts | 4 +- src/classes/Bot.ts | 6 +- src/classes/Channel.ts | 77 +- src/classes/ChannelUnread.ts | 2 +- src/classes/ChannelWebhook.ts | 8 +- src/classes/Emoji.ts | 4 +- src/classes/File.ts | 2 +- src/classes/Invite.ts | 8 +- src/classes/MFA.ts | 8 +- src/classes/Message.ts | 72 +- src/classes/MessageEmbed.ts | 14 +- src/classes/PublicBot.ts | 14 +- src/classes/PublicInvite.ts | 8 +- src/classes/Server.ts | 72 +- src/classes/ServerBan.ts | 8 +- src/classes/ServerMember.ts | 14 +- src/classes/Session.ts | 2 +- src/classes/SystemMessage.ts | 4 +- src/classes/User.ts | 18 +- src/classes/UserProfile.ts | 4 +- src/classes/index.ts | 40 +- src/collections/AccountCollection.ts | 8 +- src/collections/BotCollection.ts | 8 +- src/collections/ChannelCollection.ts | 8 +- src/collections/ChannelUnreadCollection.ts | 6 +- src/collections/ChannelWebhookCollection.ts | 6 +- src/collections/Collection.ts | 10 +- src/collections/EmojiCollection.ts | 6 +- src/collections/MessageCollection.ts | 6 +- src/collections/ServerCollection.ts | 8 +- src/collections/ServerMemberCollection.ts | 6 +- src/collections/SessionCollection.ts | 6 +- src/collections/UserCollection.ts | 8 +- src/collections/index.ts | 22 +- src/events/EventClient.ts | 10 +- src/events/v1.ts | 179 +-- src/hydration/bot.ts | 3 +- src/hydration/channel.ts | 8 +- src/hydration/channelUnread.ts | 4 +- src/hydration/channelWebhook.ts | 8 +- src/hydration/emoji.ts | 4 +- src/hydration/index.ts | 24 +- src/hydration/message.ts | 14 +- src/hydration/server.ts | 6 +- src/hydration/serverMember.ts | 8 +- src/hydration/session.ts | 2 +- src/hydration/user.ts | 6 +- src/index.ts | 18 +- src/lib/merge.ts | 24 +- src/permissions/calculator.ts | 13 +- src/permissions/definitions.ts | 18 +- test.mjs | 12 - tsconfig.json | 2 + 67 files changed, 658 insertions(+), 2079 deletions(-) create mode 100644 .github/workflows/npmPublish.ts create mode 100644 .github/workflows/publish.yml delete mode 100644 .prettierrc create mode 100644 deno.json delete mode 100644 eslint.config.js delete mode 100644 package.json delete mode 100644 pnpm-lock.yaml delete mode 100755 test.mjs diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0fdcdc16..1cfa2cdc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,22 +8,14 @@ jobs: docs: runs-on: ubuntu-latest steps: - - name: Checkout repository and submodules + - name: Checkout repository uses: actions/checkout@v3 + - name: Setup Deno 2.x + uses: denoland/setup-deno@v2 with: - submodules: recursive - - uses: pnpm/action-setup@v4.0.0 - - name: Use Node.js 18 - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: "pnpm" - - name: Install packages - run: pnpm install - + deno-version: 2.x - name: Build - run: pnpm run docs - + run: deno task docs - name: Deploy uses: JamesIves/github-pages-deploy-action@4.1.5 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index edd89fad..5253ade5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,27 +9,16 @@ on: jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x, 20.x] - steps: - - name: Checkout repository and submodules + - name: Checkout repository uses: actions/checkout@v3 + - name: Setup Deno 2.x + uses: denoland/setup-deno@v2 with: - submodules: recursive - - uses: pnpm/action-setup@v4.0.0 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: "pnpm" - - name: Install packages - run: pnpm install - + deno-version: 2.x - name: Typecheck - run: pnpm typecheck + run: deno check src/ - name: Code Formatting - run: pnpm fmt:check + run: deno fmt --check - name: Lint - run: pnpm lint + run: deno lint diff --git a/.github/workflows/npmPublish.ts b/.github/workflows/npmPublish.ts new file mode 100644 index 00000000..b02b0d41 --- /dev/null +++ b/.github/workflows/npmPublish.ts @@ -0,0 +1,64 @@ +import { build, emptyDir } from "jsr:@deno/dnt"; +import pkg from "../../deno.json" with { type: "json" }; +import tsc from "../../tsconfig.json" with { type: "json" }; + +await emptyDir("npm"); + +await build({ + entryPoints: ["src/index.ts"], + esModule: true, + outDir: "npm", + scriptModule: false, + shims: {}, + skipNpmInstall: true, + skipSourceOutput: true, + test: false, + package: { + name: "revolt.js", + version: pkg.version, + type: "module", + module: "lib/index.js", + types: "lib/index.d.ts", + repository: { + type: "git", + url: "git+https://github.com/revoltchat/revolt.js.git", + }, + author: "Paul Makles ", + license: "MIT", + description: "Library for interacting with the Revolt API.", + dependencies: Object.fromEntries( + Object.values(pkg.imports).map((dep) => { + dep = dep.replace("npm:", ""); + + const lastAtIndex = dep.lastIndexOf("@"); + return [dep.slice(0, lastAtIndex), dep.slice(lastAtIndex + 1)]; + }), + ), + engines: { + node: ">=22.0.0", + }, + }, + compilerOptions: { + ...tsc.compilerOptions, + lib: ["ES2022", "DOM"], + target: "ES2022", + }, + postBuild() { + Deno.renameSync("npm/esm", "npm/lib"); + Deno.removeSync("npm/.npmignore"); + Deno.copyFileSync("README.md", "npm/README.md"); + Deno.copyFileSync("LICENSE", "npm/LICENSE"); + + const messageEmbedCode = Deno.readTextFileSync( + "npm/lib/classes/MessageEmbed.js", + ).replace( + 'import * as dntShim from "../_dnt.shims.js";\n', + "", + ).replace("dntShim.dntGlobalThis", "globalThis"); + + Deno.writeTextFileSync("npm/lib/classes/MessageEmbed.js", messageEmbedCode); + + Deno.removeSync("npm/lib/_dnt.shims.js"); + Deno.removeSync("npm/lib/_dnt.shims.d.ts"); + }, +}); diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..43e93a46 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,31 @@ +# publish to jsr and npm on release +name: Publish + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup Deno 2.x + uses: denoland/setup-deno@v2 + with: + deno-version: 2.x + - name: Setup Node 22.x + uses: actions/setup-node@v2 + with: + node-version: 22.x + - name: Publish to jsr + run: deno publish + - name: Build for npm + run: deno task npm + - name: Publish to npm + run: npm publish diff --git a/.gitignore b/.gitignore index 0f5ad0f5..41f0a0d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,4 @@ -# build -node_modules -.env -docs -todo -/lib - -# yarn -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/sdks -!.yarn/versions +/node_modules +/.env +/docs +/npm diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index fc1b2b28..00000000 --- a/.prettierrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "tabWidth": 2, - "useTabs": false, - "plugins": ["@trivago/prettier-plugin-sort-imports"], - "importOrder": ["", "^\\.\\.", "^[./]"], - "importOrderSeparation": true, - "importOrderSortSpecifiers": true -} diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d7df89c9..74baffcc 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,3 +1,3 @@ { - "recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"] + "recommendations": ["denoland.vscode-deno"] } diff --git a/.vscode/settings.json b/.vscode/settings.json index c4aecfc3..3e5dc4c1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { - "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.defaultFormatter": "denoland.vscode-deno", "editor.formatOnSave": true, - "[typescript]": { + "[github-actions-workflow]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/README.md b/README.md index 72863ef1..70edb204 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,7 @@ API. ## Example Usage ```javascript -// esm / typescript import { Client } from "revolt.js"; -// ...or commonjs -const { Client } = require("revolt.js"); let client = new Client(); diff --git a/deno.json b/deno.json new file mode 100644 index 00000000..6ae3d8a4 --- /dev/null +++ b/deno.json @@ -0,0 +1,28 @@ +{ + "name": "@revolt/revoltjs", + "version": "7.0.5", + "exports": "./src/index.ts", + "imports": { + "@vladfrangu/async_event_emitter": "npm:@vladfrangu/async_event_emitter@^2.4.6", + "revolt-api": "npm:revolt-api@0.8.3", + "ulid": "npm:ulid@^2.3.0" + }, + "tasks": { + "docs": "deno run -A npm:typedoc --name revolt.js --readme README.md src/", + "npm": "deno run -A .github/workflows/npmPublish.ts" + }, + "fmt": { + "indentWidth": 2, + "useTabs": false + }, + "lint": { + "rules": { + "tags": ["recommended", "jsr"] + } + }, + "publish": { + "exclude": [".github", ".vscode"] + }, + "nodeModulesDir": "auto", + "lock": false +} diff --git a/eslint.config.js b/eslint.config.js deleted file mode 100644 index f82ab7dc..00000000 --- a/eslint.config.js +++ /dev/null @@ -1,21 +0,0 @@ -import eslint from "@eslint/js"; -import prettier from "eslint-plugin-prettier/recommended"; -import { defineConfig } from "eslint/config"; -import tseslint from "typescript-eslint"; - -export default defineConfig([ - eslint.configs.recommended, - tseslint.configs.recommended, - { - rules: { - "@typescript-eslint/no-unused-vars": [ - "warn", - { - caughtErrors: "all", - varsIgnorePattern: "^_", - }, - ], - }, - }, - prettier, -]); diff --git a/package.json b/package.json deleted file mode 100644 index ca4fc132..00000000 --- a/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "revolt.js", - "version": "7.0.5", - "type": "module", - "module": "lib/index.js", - "types": "lib/index.d.ts", - "repository": "https://github.com/revoltchat/revolt.js", - "author": "Paul Makles ", - "license": "MIT", - "scripts": { - "build": "tsc", - "lint": "eslint --ext .ts,.tsx src/", - "lint:fix": "eslint --fix --ext .ts,.tsx src/", - "typecheck": "tsc --noEmit", - "docs": "typedoc --plugin @mxssfd/typedoc-theme --theme my-theme --readme README.md src/", - "fmt": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'", - "fmt:check": "prettier --check 'src/**/*.{js,jsx,ts,tsx}'" - }, - "files": [ - "README.md", - "lib" - ], - "description": "Library for interacting with the Revolt API.", - "packageManager": "pnpm@9.4.0", - "dependencies": { - "@vladfrangu/async_event_emitter": "^2.4.6", - "revolt-api": "0.8.3", - "ulid": "^2.3.0" - }, - "devDependencies": { - "@mxssfd/typedoc-theme": "^1.1.7", - "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/node": "^22.13.10", - "eslint": "^9.22.0", - "eslint-plugin-prettier": "^5.2.3", - "prettier": "^3.5.3", - "typedoc": "^0.27.9", - "typescript": "^5.8.2", - "typescript-eslint": "^8.26.1" - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 6ad0f638..00000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,1444 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@vladfrangu/async_event_emitter': - specifier: ^2.4.6 - version: 2.4.6 - revolt-api: - specifier: 0.8.3 - version: 0.8.3 - ulid: - specifier: ^2.3.0 - version: 2.3.0 - devDependencies: - '@mxssfd/typedoc-theme': - specifier: ^1.1.7 - version: 1.1.7(typedoc@0.27.9(typescript@5.8.2)) - '@trivago/prettier-plugin-sort-imports': - specifier: ^5.2.2 - version: 5.2.2(prettier@3.5.3) - '@types/node': - specifier: ^22.13.10 - version: 22.13.10 - eslint: - specifier: ^9.22.0 - version: 9.22.0 - eslint-plugin-prettier: - specifier: ^5.2.3 - version: 5.2.3(eslint-config-prettier@8.10.0(eslint@9.22.0))(eslint@9.22.0)(prettier@3.5.3) - prettier: - specifier: ^3.5.3 - version: 3.5.3 - typedoc: - specifier: ^0.27.9 - version: 0.27.9(typescript@5.8.2) - typescript: - specifier: ^5.8.2 - version: 5.8.2 - typescript-eslint: - specifier: ^8.26.1 - version: 8.26.1(eslint@9.22.0)(typescript@5.8.2) - -packages: - - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.26.10': - resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.26.10': - resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/template@7.26.9': - resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.26.10': - resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.26.10': - resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} - engines: {node: '>=6.9.0'} - - '@eslint-community/eslint-utils@4.5.1': - resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.19.2': - resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.1.0': - resolution: {integrity: sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.12.0': - resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.0': - resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.22.0': - resolution: {integrity: sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/plugin-kit@0.2.7': - resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@gerrit0/mini-shiki@1.27.2': - resolution: {integrity: sha512-GeWyHz8ao2gBiUW4OJnQDxXQnFgZQwwQk05t/CVVgNBN7/rK8XZ7xY6YhLVv9tH3VppWWmr9DCl3MwemB/i+Og==} - - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - - '@humanwhocodes/retry@0.4.2': - resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} - engines: {node: '>=18.18'} - - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@mxssfd/typedoc-theme@1.1.7': - resolution: {integrity: sha512-dj4p0TjIoudD8j1u+Kf+KzcEc+je3IB/B1oohWcVJmMRfbw5uZYX6qOGHzfUzAPiU1pYe2u5Vo1IPqgLo58taA==} - engines: {node: '>= 14'} - peerDependencies: - typedoc: ^0.26.7 - - '@nodelib/fs.scandir@2.1.5': - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - - '@shikijs/engine-oniguruma@1.29.2': - resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} - - '@shikijs/types@1.29.2': - resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} - - '@shikijs/vscode-textmate@10.0.2': - resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - - '@trivago/prettier-plugin-sort-imports@5.2.2': - resolution: {integrity: sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==} - engines: {node: '>18.12'} - peerDependencies: - '@vue/compiler-sfc': 3.x - prettier: 2.x - 3.x - prettier-plugin-svelte: 3.x - svelte: 4.x || 5.x - peerDependenciesMeta: - '@vue/compiler-sfc': - optional: true - prettier-plugin-svelte: - optional: true - svelte: - optional: true - - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - - '@types/hast@3.0.4': - resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - - '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - - '@types/node@22.13.10': - resolution: {integrity: sha512-I6LPUvlRH+O6VRUqYOcMudhaIdUVWfsjnZavnsraHvpBwaEyMN29ry+0UVJhImYL16xsscu0aske3yA+uPOWfw==} - - '@types/unist@3.0.3': - resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - - '@typescript-eslint/eslint-plugin@8.26.1': - resolution: {integrity: sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/parser@8.26.1': - resolution: {integrity: sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/scope-manager@8.26.1': - resolution: {integrity: sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/type-utils@8.26.1': - resolution: {integrity: sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/types@8.26.1': - resolution: {integrity: sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.26.1': - resolution: {integrity: sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/utils@8.26.1': - resolution: {integrity: sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - '@typescript-eslint/visitor-keys@8.26.1': - resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@vladfrangu/async_event_emitter@2.4.6': - resolution: {integrity: sha512-RaI5qZo6D2CVS6sTHFKg1v5Ohq/+Bo2LZ5gzUEwZ/WkHhwtGTCB/sVLw8ijOkAUxasZ+WshN/Rzj4ywsABJ5ZA==} - engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} - engines: {node: '>=0.4.0'} - hasBin: true - - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - axios@0.26.1: - resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} - - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-config-prettier@8.10.0: - resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-plugin-prettier@5.2.3: - resolution: {integrity: sha512-qJ+y0FfCp/mQYQ/vWQ3s7eUlFEL4PyKfAJxsnYTJ4YT73nsJBWqmEpFryxV9OeUiqmsTsYJ5Y+KDNaeP31wrRw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '*' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.22.0: - resolution: {integrity: sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.19.1: - resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} - - import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - javascript-natural-sort@0.7.1: - resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash.defaultsdeep@4.6.1: - resolution: {integrity: sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - lunr@2.3.9: - resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} - - markdown-it@14.1.0: - resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} - hasBin: true - - mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} - engines: {node: '>=14'} - hasBin: true - - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - revolt-api@0.8.3: - resolution: {integrity: sha512-4dOe6sbiWFGF5PlAuYtH9vWHXdFOge/L6/EKr6oLgslN+QBn2DKfSOIhl6Ni2n0B0cBurhA1KuBy0mWfE68fIQ==} - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} - engines: {node: '>=10'} - hasBin: true - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - synckit@0.9.2: - resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} - engines: {node: ^14.18.0 || >=16.0.0} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - ts-api-utils@2.0.1: - resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - typedoc@0.27.9: - resolution: {integrity: sha512-/z585740YHURLl9DN2jCWe6OW7zKYm6VoQ93H0sxZ1cwHQEQrUn5BJrEnkWhfzUdyO+BLGjnKUZ9iz9hKloFDw==} - engines: {node: '>= 18'} - hasBin: true - peerDependencies: - typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x - - typescript-eslint@8.26.1: - resolution: {integrity: sha512-t/oIs9mYyrwZGRpDv3g+3K6nZ5uhKEMt2oNmAPwaY4/ye0+EH4nXIPYNtkYFS6QHm+1DFg34DbglYBz5P9Xysg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} - engines: {node: '>=14.17'} - hasBin: true - - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - - ulid@2.3.0: - resolution: {integrity: sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==} - hasBin: true - - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - yaml@2.7.0: - resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} - engines: {node: '>= 14'} - hasBin: true - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - -snapshots: - - '@babel/code-frame@7.26.2': - dependencies: - '@babel/helper-validator-identifier': 7.25.9 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/generator@7.26.10': - dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.1.0 - - '@babel/helper-string-parser@7.25.9': {} - - '@babel/helper-validator-identifier@7.25.9': {} - - '@babel/parser@7.26.10': - dependencies: - '@babel/types': 7.26.10 - - '@babel/template@7.26.9': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - - '@babel/traverse@7.26.10': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/template': 7.26.9 - '@babel/types': 7.26.10 - debug: 4.4.0 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.26.10': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - - '@eslint-community/eslint-utils@4.5.1(eslint@9.22.0)': - dependencies: - eslint: 9.22.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} - - '@eslint/config-array@0.19.2': - dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.0 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/config-helpers@0.1.0': {} - - '@eslint/core@0.12.0': - dependencies: - '@types/json-schema': 7.0.15 - - '@eslint/eslintrc@3.3.0': - dependencies: - ajv: 6.12.6 - debug: 4.4.0 - espree: 10.3.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.22.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.2.7': - dependencies: - '@eslint/core': 0.12.0 - levn: 0.4.1 - - '@gerrit0/mini-shiki@1.27.2': - dependencies: - '@shikijs/engine-oniguruma': 1.29.2 - '@shikijs/types': 1.29.2 - '@shikijs/vscode-textmate': 10.0.2 - - '@humanfs/core@0.19.1': {} - - '@humanfs/node@0.16.6': - dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.1': {} - - '@humanwhocodes/retry@0.4.2': {} - - '@jridgewell/gen-mapping@0.3.8': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@mxssfd/typedoc-theme@1.1.7(typedoc@0.27.9(typescript@5.8.2))': - dependencies: - typedoc: 0.27.9(typescript@5.8.2) - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.19.1 - - '@pkgr/core@0.1.1': {} - - '@shikijs/engine-oniguruma@1.29.2': - dependencies: - '@shikijs/types': 1.29.2 - '@shikijs/vscode-textmate': 10.0.2 - - '@shikijs/types@1.29.2': - dependencies: - '@shikijs/vscode-textmate': 10.0.2 - '@types/hast': 3.0.4 - - '@shikijs/vscode-textmate@10.0.2': {} - - '@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.5.3)': - dependencies: - '@babel/generator': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 - javascript-natural-sort: 0.7.1 - lodash: 4.17.21 - prettier: 3.5.3 - transitivePeerDependencies: - - supports-color - - '@types/estree@1.0.6': {} - - '@types/hast@3.0.4': - dependencies: - '@types/unist': 3.0.3 - - '@types/json-schema@7.0.15': {} - - '@types/node@22.13.10': - dependencies: - undici-types: 6.20.0 - - '@types/unist@3.0.3': {} - - '@typescript-eslint/eslint-plugin@8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2)': - dependencies: - '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/type-utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.26.1 - eslint: 9.22.0 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2)': - dependencies: - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 - eslint: 9.22.0 - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.26.1': - dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 - - '@typescript-eslint/type-utils@8.26.1(eslint@9.22.0)(typescript@5.8.2)': - dependencies: - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - debug: 4.4.0 - eslint: 9.22.0 - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.26.1': {} - - '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.2)': - dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.26.1(eslint@9.22.0)(typescript@5.8.2)': - dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.22.0) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - eslint: 9.22.0 - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.26.1': - dependencies: - '@typescript-eslint/types': 8.26.1 - eslint-visitor-keys: 4.2.0 - - '@vladfrangu/async_event_emitter@2.4.6': {} - - acorn-jsx@5.3.2(acorn@8.14.1): - dependencies: - acorn: 8.14.1 - - acorn@8.14.1: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - argparse@2.0.1: {} - - axios@0.26.1: - dependencies: - follow-redirects: 1.15.9 - transitivePeerDependencies: - - debug - - balanced-match@1.0.2: {} - - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - callsites@3.1.0: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.4: {} - - concat-map@0.0.1: {} - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - debug@4.4.0: - dependencies: - ms: 2.1.3 - - deep-is@0.1.4: {} - - entities@4.5.0: {} - - escape-string-regexp@4.0.0: {} - - eslint-config-prettier@8.10.0(eslint@9.22.0): - dependencies: - eslint: 9.22.0 - optional: true - - eslint-plugin-prettier@5.2.3(eslint-config-prettier@8.10.0(eslint@9.22.0))(eslint@9.22.0)(prettier@3.5.3): - dependencies: - eslint: 9.22.0 - prettier: 3.5.3 - prettier-linter-helpers: 1.0.0 - synckit: 0.9.2 - optionalDependencies: - eslint-config-prettier: 8.10.0(eslint@9.22.0) - - eslint-scope@8.3.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.0: {} - - eslint@9.22.0: - dependencies: - '@eslint-community/eslint-utils': 4.5.1(eslint@9.22.0) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.2 - '@eslint/config-helpers': 0.1.0 - '@eslint/core': 0.12.0 - '@eslint/eslintrc': 3.3.0 - '@eslint/js': 9.22.0 - '@eslint/plugin-kit': 0.2.7 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.2 - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.0 - escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - transitivePeerDependencies: - - supports-color - - espree@10.3.0: - dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) - eslint-visitor-keys: 4.2.0 - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - fast-deep-equal@3.1.3: {} - - fast-diff@1.3.0: {} - - fast-glob@3.3.3: - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - file-entry-cache@8.0.0: - dependencies: - flat-cache: 4.0.1 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - flat-cache@4.0.1: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - - flatted@3.3.3: {} - - follow-redirects@1.15.9: {} - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - globals@11.12.0: {} - - globals@14.0.0: {} - - graphemer@1.4.0: {} - - has-flag@4.0.0: {} - - ignore@5.3.2: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - is-extglob@2.1.1: {} - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-number@7.0.0: {} - - isexe@2.0.0: {} - - javascript-natural-sort@0.7.1: {} - - js-tokens@4.0.0: {} - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-schema-traverse@0.4.1: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - linkify-it@5.0.0: - dependencies: - uc.micro: 2.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.defaultsdeep@4.6.1: {} - - lodash.merge@4.6.2: {} - - lodash@4.17.21: {} - - lunr@2.3.9: {} - - markdown-it@14.1.0: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - - mdurl@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.1 - - ms@2.1.3: {} - - natural-compare@1.4.0: {} - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - path-exists@4.0.0: {} - - path-key@3.1.1: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - prelude-ls@1.2.1: {} - - prettier-linter-helpers@1.0.0: - dependencies: - fast-diff: 1.3.0 - - prettier@3.5.3: {} - - punycode.js@2.3.1: {} - - punycode@2.3.1: {} - - queue-microtask@1.2.3: {} - - resolve-from@4.0.0: {} - - reusify@1.1.0: {} - - revolt-api@0.8.3: - dependencies: - axios: 0.26.1 - lodash.defaultsdeep: 4.6.1 - transitivePeerDependencies: - - debug - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - semver@7.7.1: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - strip-json-comments@3.1.1: {} - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - synckit@0.9.2: - dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.8.1 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - ts-api-utils@2.0.1(typescript@5.8.2): - dependencies: - typescript: 5.8.2 - - tslib@2.8.1: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - typedoc@0.27.9(typescript@5.8.2): - dependencies: - '@gerrit0/mini-shiki': 1.27.2 - lunr: 2.3.9 - markdown-it: 14.1.0 - minimatch: 9.0.5 - typescript: 5.8.2 - yaml: 2.7.0 - - typescript-eslint@8.26.1(eslint@9.22.0)(typescript@5.8.2): - dependencies: - '@typescript-eslint/eslint-plugin': 8.26.1(@typescript-eslint/parser@8.26.1(eslint@9.22.0)(typescript@5.8.2))(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/parser': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - eslint: 9.22.0 - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - typescript@5.8.2: {} - - uc.micro@2.1.0: {} - - ulid@2.3.0: {} - - undici-types@6.20.0: {} - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - word-wrap@1.2.5: {} - - yaml@2.7.0: {} - - yocto-queue@0.1.0: {} diff --git a/src/Client.ts b/src/Client.ts index 168732d1..f8d34361 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -2,36 +2,36 @@ import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter"; import type { DataLogin, RevoltConfig } from "revolt-api"; import { API, type Role } from "revolt-api"; -import type { Channel } from "./classes/Channel.js"; -import type { Emoji } from "./classes/Emoji.js"; -import type { Message } from "./classes/Message.js"; -import type { Server } from "./classes/Server.js"; -import type { ServerMember } from "./classes/ServerMember.js"; -import type { User } from "./classes/User.js"; -import { AccountCollection } from "./collections/AccountCollection.js"; -import { BotCollection } from "./collections/BotCollection.js"; -import { ChannelCollection } from "./collections/ChannelCollection.js"; -import { ChannelUnreadCollection } from "./collections/ChannelUnreadCollection.js"; -import { ChannelWebhookCollection } from "./collections/ChannelWebhookCollection.js"; -import { EmojiCollection } from "./collections/EmojiCollection.js"; -import { MessageCollection } from "./collections/MessageCollection.js"; -import { ServerCollection } from "./collections/ServerCollection.js"; -import { ServerMemberCollection } from "./collections/ServerMemberCollection.js"; -import { SessionCollection } from "./collections/SessionCollection.js"; -import { UserCollection } from "./collections/UserCollection.js"; +import type { Channel } from "./classes/Channel.ts"; +import type { Emoji } from "./classes/Emoji.ts"; +import type { Message } from "./classes/Message.ts"; +import type { Server } from "./classes/Server.ts"; +import type { ServerMember } from "./classes/ServerMember.ts"; +import type { User } from "./classes/User.ts"; +import { AccountCollection } from "./collections/AccountCollection.ts"; +import { BotCollection } from "./collections/BotCollection.ts"; +import { ChannelCollection } from "./collections/ChannelCollection.ts"; +import { ChannelUnreadCollection } from "./collections/ChannelUnreadCollection.ts"; +import { ChannelWebhookCollection } from "./collections/ChannelWebhookCollection.ts"; +import { EmojiCollection } from "./collections/EmojiCollection.ts"; +import { MessageCollection } from "./collections/MessageCollection.ts"; +import { ServerCollection } from "./collections/ServerCollection.ts"; +import { ServerMemberCollection } from "./collections/ServerMemberCollection.ts"; +import { SessionCollection } from "./collections/SessionCollection.ts"; +import { UserCollection } from "./collections/UserCollection.ts"; import { ConnectionState, EventClient, type EventClientOptions, -} from "./events/EventClient.js"; -import { handleEvent } from "./events/v1.js"; -import type { HydratedChannel } from "./hydration/channel.js"; -import type { HydratedEmoji } from "./hydration/emoji.js"; -import type { HydratedMessage } from "./hydration/message.js"; -import type { HydratedServer } from "./hydration/server.js"; -import type { HydratedServerMember } from "./hydration/serverMember.js"; -import type { HydratedUser } from "./hydration/user.js"; -import { RE_CHANNELS, RE_MENTIONS, RE_SPOILER } from "./lib/regex.js"; +} from "./events/EventClient.ts"; +import { handleEvent } from "./events/v1.ts"; +import type { HydratedChannel } from "./hydration/channel.ts"; +import type { HydratedEmoji } from "./hydration/emoji.ts"; +import type { HydratedMessage } from "./hydration/message.ts"; +import type { HydratedServer } from "./hydration/server.ts"; +import type { HydratedServerMember } from "./hydration/serverMember.ts"; +import type { HydratedUser } from "./hydration/user.ts"; +import { RE_CHANNELS, RE_MENTIONS, RE_SPOILER } from "./lib/regex.ts"; export type Session = { _id: string; token: string; user_id: string } | string; @@ -39,7 +39,7 @@ export type Session = { _id: string; token: string; user_id: string } | string; * Events provided by the client */ export type Events = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // deno-lint-ignore no-explicit-any error: [any]; connected: []; @@ -48,41 +48,45 @@ export type Events = { ready: []; logout: []; - messageCreate: [Message]; - messageUpdate: [Message, HydratedMessage]; - messageDelete: [HydratedMessage]; - messageDeleteBulk: [HydratedMessage[], Channel?]; - messageReactionAdd: [Message, string, string]; - messageReactionRemove: [Message, string, string]; - messageReactionRemoveEmoji: [Message, string]; - - channelCreate: [Channel]; - channelUpdate: [Channel, HydratedChannel]; - channelDelete: [HydratedChannel]; - channelGroupJoin: [Channel, User]; - channelGroupLeave: [Channel, User?]; - channelStartTyping: [Channel, User?]; - channelStopTyping: [Channel, User?]; - channelAcknowledged: [Channel, string]; - - serverCreate: [Server]; - serverUpdate: [Server, HydratedServer]; - serverDelete: [HydratedServer]; - serverLeave: [HydratedServer]; - serverRoleUpdate: [Server, string, Role]; - serverRoleDelete: [Server, string, Role]; - - serverMemberUpdate: [ServerMember, HydratedServerMember]; - serverMemberJoin: [ServerMember]; - serverMemberLeave: [HydratedServerMember]; - - userUpdate: [User, HydratedUser]; - // ^ userRelationshipChanged(user: User, previousRelationship: RelationshipStatus): void; - // ^ userPresenceChanged(user: User, previousPresence: boolean): void; - userSettingsUpdate: [string, Record]; - - emojiCreate: [Emoji]; - emojiDelete: [HydratedEmoji]; + messageCreate: [message: Message]; + messageUpdate: [message: Message, previousMessage: HydratedMessage]; + messageDelete: [message: HydratedMessage]; + messageDeleteBulk: [messages: HydratedMessage[], channel?: Channel]; + messageReactionAdd: [message: Message, userId: string, emoji: string]; + messageReactionRemove: [message: Message, userId: string, emoji: string]; + messageReactionRemoveEmoji: [message: Message, emoji: string]; + + channelCreate: [channel: Channel]; + channelUpdate: [channel: Channel, previousChannel: HydratedChannel]; + channelDelete: [channel: HydratedChannel]; + channelGroupJoin: [channel: Channel, user: User]; + channelGroupLeave: [channel: Channel, user?: User]; + channelStartTyping: [channel: Channel, user?: User]; + channelStopTyping: [channel: Channel, user?: User]; + channelAcknowledged: [channel: Channel, messageId: string]; + + serverCreate: [server: Server]; + serverUpdate: [server: Server, previousServer: HydratedServer]; + serverDelete: [server: HydratedServer]; + serverLeave: [server: HydratedServer]; + serverRoleUpdate: [server: Server, roleId: string, previousRole: Role]; + serverRoleDelete: [server: Server, roleId: string, role: Role]; + + serverMemberUpdate: [ + member: ServerMember, + previousMember: HydratedServerMember, + ]; + serverMemberJoin: [member: ServerMember]; + serverMemberLeave: [member: HydratedServerMember]; + + userUpdate: [user: User, previousUser: HydratedUser]; + userSettingsUpdate: [ + userId: string, + settings: Record, + ]; + + emojiCreate: [emoji: Emoji]; + emojiDelete: [emoji: HydratedEmoji]; }; /** @@ -146,17 +150,21 @@ export type ClientOptions = Partial & { * Revolt.js Clients */ export class Client extends AsyncEventEmitter { - readonly account = new AccountCollection(this); - readonly bots = new BotCollection(this); - readonly channels = new ChannelCollection(this); - readonly channelUnreads = new ChannelUnreadCollection(this); - readonly channelWebhooks = new ChannelWebhookCollection(this); - readonly emojis = new EmojiCollection(this); - readonly messages = new MessageCollection(this); - readonly servers = new ServerCollection(this); - readonly serverMembers = new ServerMemberCollection(this); - readonly sessions = new SessionCollection(this); - readonly users = new UserCollection(this); + readonly account: AccountCollection = new AccountCollection(this); + readonly bots: BotCollection = new BotCollection(this); + readonly channels: ChannelCollection = new ChannelCollection(this); + readonly channelUnreads: ChannelUnreadCollection = + new ChannelUnreadCollection(this); + readonly channelWebhooks: ChannelWebhookCollection = + new ChannelWebhookCollection(this); + readonly emojis: EmojiCollection = new EmojiCollection(this); + readonly messages: MessageCollection = new MessageCollection(this); + readonly servers: ServerCollection = new ServerCollection(this); + readonly serverMembers: ServerMemberCollection = new ServerMemberCollection( + this, + ); + readonly sessions: SessionCollection = new SessionCollection(this); + readonly users: UserCollection = new UserCollection(this); readonly api: API; readonly options: ClientOptions; @@ -236,8 +244,9 @@ export class Client extends AsyncEventEmitter { } }); - this.events.on("event", (event) => - handleEvent(this, event, this.#setReady.bind(this)), + this.events.on( + "event", + (event) => handleEvent(this, event, this.#setReady.bind(this)), ); } @@ -324,7 +333,7 @@ export class Client extends AsyncEventEmitter { /** * Use an existing session */ - async useExistingSession(session: Session): Promise { + useExistingSession(session: Session): void { this.#session = session; this.#updateHeaders(); } @@ -375,9 +384,11 @@ export class Client extends AsyncEventEmitter { */ proxyFile(url: string): string | undefined { if (this.configuration?.features.january.enabled) { - return `${this.configuration.features.january.url}/proxy?url=${encodeURIComponent( - url, - )}`; + return `${this.configuration.features.january.url}/proxy?url=${ + encodeURIComponent( + url, + ) + }`; } else { return url; } diff --git a/src/classes/BannedUser.ts b/src/classes/BannedUser.ts index 4283cc71..f13defbc 100644 --- a/src/classes/BannedUser.ts +++ b/src/classes/BannedUser.ts @@ -1,8 +1,8 @@ import type { BannedUser as APIBannedUser } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; -import { File } from "./File.js"; +import { File } from "./File.ts"; /** * Banned User diff --git a/src/classes/Bot.ts b/src/classes/Bot.ts index d28140e4..fbe94894 100644 --- a/src/classes/Bot.ts +++ b/src/classes/Bot.ts @@ -1,10 +1,10 @@ import type { DataEditBot } from "revolt-api"; import { decodeTime } from "ulid"; -import type { BotCollection } from "../collections/BotCollection.js"; -import type { BotFlags } from "../hydration/bot.js"; +import type { BotCollection } from "../collections/BotCollection.ts"; +import type { BotFlags } from "../hydration/bot.ts"; -import type { User } from "./User.js"; +import type { User } from "./User.ts"; /** * Bot Class diff --git a/src/classes/Channel.ts b/src/classes/Channel.ts index 90d220a5..31e6d315 100644 --- a/src/classes/Channel.ts +++ b/src/classes/Channel.ts @@ -1,29 +1,29 @@ import type { Channel as APIChannel, - Member as APIMember, - Message as APIMessage, - User as APIUser, DataEditChannel, DataMessageSearch, DataMessageSend, + Member as APIMember, + Message as APIMessage, Override, + User as APIUser, } from "revolt-api"; import type { APIRoutes } from "revolt-api/dist/routes"; import { decodeTime, ulid } from "ulid"; -import type { ChannelCollection } from "../collections/ChannelCollection.js"; +import type { ChannelCollection } from "../collections/ChannelCollection.ts"; import { bitwiseAndEq, calculatePermission, -} from "../permissions/calculator.js"; -import { Permission } from "../permissions/definitions.js"; +} from "../permissions/calculator.ts"; +import { Permission } from "../permissions/definitions.ts"; -import type { ChannelWebhook } from "./ChannelWebhook.js"; -import type { File } from "./File.js"; -import type { Message } from "./Message.js"; -import type { Server } from "./Server.js"; -import type { ServerMember } from "./ServerMember.js"; -import type { User } from "./User.js"; +import type { ChannelWebhook } from "./ChannelWebhook.ts"; +import type { File } from "./File.ts"; +import type { Message } from "./Message.ts"; +import type { Server } from "./Server.ts"; +import type { ServerMember } from "./ServerMember.ts"; +import type { User } from "./User.ts"; /** * Channel Class @@ -103,8 +103,8 @@ export class Channel { return this.type === "SavedMessages" ? this.user?.username : this.type === "DirectMessage" - ? this.recipient?.username - : this.name; + ? this.recipient?.username + : this.name; } /** @@ -166,8 +166,8 @@ export class Channel { get recipient(): User | undefined { return this.type === "DirectMessage" ? this.recipients?.find( - (user) => user?.id !== this.#collection.client.user!.id, - ) + (user) => user?.id !== this.#collection.client.user!.id, + ) : undefined; } @@ -293,7 +293,7 @@ export class Channel { return ( ( this.#collection.client.channelUnreads.get(this.id)?.lastMessageId ?? - "0" + "0" ).localeCompare(this.lastMessageId) === -1 ); } @@ -373,7 +373,7 @@ export class Channel { orPermission(...permission: (keyof typeof Permission)[]): boolean { return ( permission.findIndex((x) => - bitwiseAndEq(this.permission, Permission[x]), + bitwiseAndEq(this.permission, Permission[x]) ) !== -1 ); } @@ -389,7 +389,7 @@ export class Channel { ); return members.map((user) => - this.#collection.client.users.getOrCreate(user._id, user), + this.#collection.client.users.getOrCreate(user._id, user) ); } @@ -404,7 +404,7 @@ export class Channel { ); return webhooks.map((webhook) => - this.#collection.client.channelWebhooks.getOrCreate(webhook.id, webhook), + this.#collection.client.channelWebhooks.getOrCreate(webhook.id, webhook) ); } @@ -466,8 +466,9 @@ export class Channel { data: string | DataMessageSend, idempotencyKey: string = ulid(), ): Promise { - const msg: DataMessageSend = - typeof data === "string" ? { content: data } : data; + const msg: DataMessageSend = typeof data === "string" + ? { content: data } + : data; // Mark as silent message if (msg.content?.startsWith("@silent ")) { @@ -528,7 +529,7 @@ export class Channel { )) as APIMessage[]; return messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message), + this.#collection.client.messages.getOrCreate(message._id, message) ); } @@ -558,13 +559,13 @@ export class Channel { return { messages: data.messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message), + this.#collection.client.messages.getOrCreate(message._id, message) ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user), + this.#collection.client.users.getOrCreate(user._id, user) ), members: data.members?.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member), + this.#collection.client.serverMembers.getOrCreate(member._id, member) ), }; } @@ -584,7 +585,7 @@ export class Channel { )) as APIMessage[]; return messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message), + this.#collection.client.messages.getOrCreate(message._id, message) ); } @@ -611,13 +612,13 @@ export class Channel { return { messages: data.messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message), + this.#collection.client.messages.getOrCreate(message._id, message) ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user), + this.#collection.client.users.getOrCreate(user._id, user) ), members: data.members?.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member), + this.#collection.client.serverMembers.getOrCreate(member._id, member) ), }; } @@ -643,12 +644,12 @@ export class Channel { */ async createInvite(): Promise< | { - type: "Server"; - _id: string; - server: string; - creator: string; - channel: string; - } + type: "Server"; + _id: string; + server: string; + creator: string; + channel: string; + } | { type: "Group"; _id: string; creator: string; channel: string } > { return await this.#collection.client.api.post( @@ -684,8 +685,8 @@ export class Channel { const lastMessageId = (typeof message === "string" ? message : message?.id) ?? - this.lastMessageId ?? - ulid(); + this.lastMessageId ?? + ulid(); const unreads = this.#collection.client.channelUnreads; const channelUnread = unreads.get(this.id); diff --git a/src/classes/ChannelUnread.ts b/src/classes/ChannelUnread.ts index 2d89e65f..59ca9917 100644 --- a/src/classes/ChannelUnread.ts +++ b/src/classes/ChannelUnread.ts @@ -1,4 +1,4 @@ -import type { ChannelUnreadCollection } from "../collections/ChannelUnreadCollection.js"; +import type { ChannelUnreadCollection } from "../collections/ChannelUnreadCollection.ts"; /** * Channel Unread Class diff --git a/src/classes/ChannelWebhook.ts b/src/classes/ChannelWebhook.ts index f4243ae6..e45c87dd 100644 --- a/src/classes/ChannelWebhook.ts +++ b/src/classes/ChannelWebhook.ts @@ -1,8 +1,8 @@ -import type { ChannelWebhookCollection } from "../collections/ChannelWebhookCollection.js"; -import { hydrate } from "../hydration/index.js"; +import type { ChannelWebhookCollection } from "../collections/ChannelWebhookCollection.ts"; +import { hydrate } from "../hydration/index.ts"; -import type { Channel } from "./Channel.js"; -import type { File } from "./File.js"; +import type { Channel } from "./Channel.ts"; +import type { File } from "./File.ts"; /** * Channel Webhook Class diff --git a/src/classes/Emoji.ts b/src/classes/Emoji.ts index 7b157fee..68619b2c 100644 --- a/src/classes/Emoji.ts +++ b/src/classes/Emoji.ts @@ -1,9 +1,9 @@ import type { EmojiParent } from "revolt-api"; import { decodeTime } from "ulid"; -import type { EmojiCollection } from "../collections/EmojiCollection.js"; +import type { EmojiCollection } from "../collections/EmojiCollection.ts"; -import type { User } from "./User.js"; +import type { User } from "./User.ts"; /** * Emoji Class diff --git a/src/classes/File.ts b/src/classes/File.ts index 9907f43b..989f9aca 100644 --- a/src/classes/File.ts +++ b/src/classes/File.ts @@ -1,6 +1,6 @@ import type { File as APIFile, Metadata } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; /** * Uploaded File diff --git a/src/classes/Invite.ts b/src/classes/Invite.ts index df197bc1..23bc7353 100644 --- a/src/classes/Invite.ts +++ b/src/classes/Invite.ts @@ -1,10 +1,10 @@ import type { Invite } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; -import type { Channel } from "./Channel.js"; -import type { Server } from "./Server.js"; -import type { User } from "./User.js"; +import type { Channel } from "./Channel.ts"; +import type { Server } from "./Server.ts"; +import type { User } from "./User.ts"; /** * Channel Invite diff --git a/src/classes/MFA.ts b/src/classes/MFA.ts index f2c55ba0..f6760f21 100644 --- a/src/classes/MFA.ts +++ b/src/classes/MFA.ts @@ -1,11 +1,11 @@ import type { MFAMethod, MFAResponse, - MultiFactorStatus, MFATicket as TicketType, + MultiFactorStatus, } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; /** * Multi-Factor Authentication @@ -52,9 +52,7 @@ export class MFA { */ get availableMethods(): MFAMethod[] { return this.authenticatorEnabled - ? this.recoveryEnabled - ? ["Totp", "Recovery"] - : ["Totp"] + ? this.recoveryEnabled ? ["Totp", "Recovery"] : ["Totp"] : ["Password"]; } diff --git a/src/classes/Message.ts b/src/classes/Message.ts index 073206f4..d4f6addf 100644 --- a/src/classes/Message.ts +++ b/src/classes/Message.ts @@ -1,21 +1,21 @@ import type { - Message as APIMessage, - MessageWebhook as APIMessageWebhook, DataEditMessage, DataMessageSend, + Message as APIMessage, + MessageWebhook as APIMessageWebhook, } from "revolt-api"; import { decodeTime } from "ulid"; -import type { Client } from "../Client.js"; -import type { MessageCollection } from "../collections/MessageCollection.js"; +import type { Client } from "../Client.ts"; +import type { MessageCollection } from "../collections/MessageCollection.ts"; -import type { Channel } from "./Channel.js"; -import { File } from "./File.js"; -import type { MessageEmbed } from "./MessageEmbed.js"; -import type { Server } from "./Server.js"; -import type { ServerMember } from "./ServerMember.js"; -import type { SystemMessage } from "./SystemMessage.js"; -import type { User } from "./User.js"; +import type { Channel } from "./Channel.ts"; +import { File } from "./File.ts"; +import type { MessageEmbed } from "./MessageEmbed.ts"; +import type { Server } from "./Server.ts"; +import type { ServerMember } from "./ServerMember.ts"; +import type { SystemMessage } from "./SystemMessage.ts"; +import type { User } from "./User.ts"; /** * Message Class @@ -217,9 +217,9 @@ export class Message { return ( this.masquerade?.name ?? - (webhook - ? webhook.name - : (this.member?.nickname ?? this.author?.username)) + (webhook + ? webhook.name + : (this.member?.nickname ?? this.author?.username)) ); } @@ -238,9 +238,9 @@ export class Message { return ( this.masqueradeAvatarURL ?? - (webhook - ? webhook.avatarURL - : (this.member?.avatarURL ?? this.author?.avatarURL)) + (webhook + ? webhook.avatarURL + : (this.member?.avatarURL ?? this.author?.avatarURL)) ); } @@ -252,9 +252,9 @@ export class Message { return ( this.masqueradeAvatarURL ?? - (webhook - ? webhook.avatarURL - : this.member + (webhook + ? webhook.avatarURL + : this.member ? this.member?.animatedAvatarURL : this.author?.animatedAvatarURL) ); @@ -309,8 +309,8 @@ export class Message { data: | string | (Omit & { - nonce?: string; - }), + nonce?: string; + }), mention = true, ): Promise | undefined { const obj = typeof data === "string" ? { content: data } : data; @@ -335,9 +335,8 @@ export class Message { */ async react(emoji: string): Promise { return await this.#collection.client.api.put( - `/channels/${this.channelId as ""}/messages/${ - this.id as "" - }/reactions/${emoji as ""}`, + `/channels/${this.channelId as ""}/messages/${this + .id as ""}/reactions/${emoji as ""}`, ); } @@ -347,9 +346,8 @@ export class Message { */ async unreact(emoji: string): Promise { return await this.#collection.client.api.delete( - `/channels/${this.channelId as ""}/messages/${ - this.id as "" - }/reactions/${emoji as ""}`, + `/channels/${this.channelId as ""}/messages/${this + .id as ""}/reactions/${emoji as ""}`, ); } } @@ -375,14 +373,14 @@ export class MessageWebhook { this.name = webhook.name; this.avatar = webhook.avatar ? new File(client, { - _id: webhook.avatar, - tag: "avatars", - metadata: { - type: "Image", - width: 256, - height: 256, - }, - }) + _id: webhook.avatar, + tag: "avatars", + metadata: { + type: "Image", + width: 256, + height: 256, + }, + }) : undefined; } @@ -392,7 +390,7 @@ export class MessageWebhook { get avatarURL(): string | undefined { return ( this.avatar?.createFileURL() ?? - `${this.#client.options.baseURL}/users/${this.id}/default_avatar` + `${this.#client.options.baseURL}/users/${this.id}/default_avatar` ); } } diff --git a/src/classes/MessageEmbed.ts b/src/classes/MessageEmbed.ts index ff31fd70..18ed00d7 100644 --- a/src/classes/MessageEmbed.ts +++ b/src/classes/MessageEmbed.ts @@ -1,8 +1,8 @@ import type { Embed, ImageSize, Special } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; -import { File } from "./File.js"; +import { File } from "./File.ts"; /** * Message Embed @@ -169,16 +169,18 @@ export class WebsiteEmbed extends MessageEmbed { } case "Twitch": return `https://player.twitch.tv/?${this.specialContent.content_type.toLowerCase()}=${this.specialContent.id}&parent=${ - (window ?? {})?.location?.hostname + (globalThis ?? {})?.location?.hostname }&autoplay=false`; case "Lightspeed": return `https://new.lightspeed.tv/embed/${this.specialContent.id}/stream`; case "Spotify": return `https://open.spotify.com/embed/${this.specialContent.content_type}/${this.specialContent.id}`; case "Soundcloud": - return `https://w.soundcloud.com/player/?url=${encodeURIComponent( - this.url!, - )}&color=%23FF7F50&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true`; + return `https://w.soundcloud.com/player/?url=${ + encodeURIComponent( + this.url!, + ) + }&color=%23FF7F50&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true`; case "Bandcamp": { return `https://bandcamp.com/EmbeddedPlayer/${this.specialContent.content_type.toLowerCase()}=${this.specialContent.id}/size=large/bgcol=181a1b/linkcol=056cc4/tracklist=false/transparent=true/`; } diff --git a/src/classes/PublicBot.ts b/src/classes/PublicBot.ts index 3653d3f9..2a27b23a 100644 --- a/src/classes/PublicBot.ts +++ b/src/classes/PublicBot.ts @@ -1,10 +1,10 @@ import type { File as APIFile, PublicBot as APIPublicBot } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; -import { Channel } from "./Channel.js"; -import { File } from "./File.js"; -import { Server } from "./Server.js"; +import { Channel } from "./Channel.ts"; +import { File } from "./File.ts"; +import { Server } from "./Server.ts"; /** * Public Bot Class @@ -28,9 +28,9 @@ export class PublicBot { this.username = data.username; this.avatar = data.avatar ? new File(client, { - _id: data.avatar, - tag: "avatars", - } as APIFile) + _id: data.avatar, + tag: "avatars", + } as APIFile) : undefined; this.description = data.description!; } diff --git a/src/classes/PublicInvite.ts b/src/classes/PublicInvite.ts index c09782c8..6c579135 100644 --- a/src/classes/PublicInvite.ts +++ b/src/classes/PublicInvite.ts @@ -1,10 +1,10 @@ import type { Invite, InviteResponse } from "revolt-api"; -import type { Client } from "../Client.js"; -import type { ServerFlags } from "../hydration/server.js"; +import type { Client } from "../Client.ts"; +import type { ServerFlags } from "../hydration/server.ts"; -import { File } from "./File.js"; -import type { Server } from "./Server.js"; +import { File } from "./File.ts"; +import type { Server } from "./Server.ts"; /** * Public Channel Invite diff --git a/src/classes/Server.ts b/src/classes/Server.ts index c370d1bb..c012a818 100644 --- a/src/classes/Server.ts +++ b/src/classes/Server.ts @@ -1,5 +1,4 @@ import type { - Server as APIServer, AllMemberResponse, BannedUser, Category, @@ -10,25 +9,26 @@ import type { DataEditServer, Override, Role, + Server as APIServer, } from "revolt-api"; import { decodeTime } from "ulid"; -import type { ServerCollection } from "../collections/ServerCollection.js"; -import { hydrate } from "../hydration/index.js"; -import type { ServerFlags } from "../hydration/server.js"; +import type { ServerCollection } from "../collections/ServerCollection.ts"; +import { hydrate } from "../hydration/index.ts"; +import type { ServerFlags } from "../hydration/server.ts"; import { bitwiseAndEq, calculatePermission, -} from "../permissions/calculator.js"; -import { Permission } from "../permissions/definitions.js"; +} from "../permissions/calculator.ts"; +import { Permission } from "../permissions/definitions.ts"; -import type { Channel } from "./Channel.js"; -import type { Emoji } from "./Emoji.js"; -import type { File } from "./File.js"; -import { ChannelInvite } from "./Invite.js"; -import { ServerBan } from "./ServerBan.js"; -import { ServerMember } from "./ServerMember.js"; -import { User } from "./User.js"; +import type { Channel } from "./Channel.ts"; +import type { Emoji } from "./Emoji.ts"; +import type { File } from "./File.ts"; +import { ChannelInvite } from "./Invite.ts"; +import { ServerBan } from "./ServerBan.ts"; +import { ServerMember } from "./ServerMember.ts"; +import { User } from "./User.ts"; /** * Server Class @@ -260,8 +260,8 @@ export class Server { const roles = this.roles; return roles ? [...roles.entries()] - .map(([id, role]) => ({ id, ...role })) - .sort((a, b) => (a.rank || 0) - (b.rank || 0)) + .map(([id, role]) => ({ id, ...role })) + .sort((a, b) => (a.rank || 0) - (b.rank || 0)) : []; } @@ -279,7 +279,7 @@ export class Server { */ get mentions(): string[] { const arr = this.channels.map((channel) => - Array.from(channel.mentions?.values() ?? []), + Array.from(channel.mentions?.values() ?? []) ); return ([] as string[]).concat(...arr); @@ -343,7 +343,7 @@ export class Server { orPermission(...permission: (keyof typeof Permission)[]): boolean { return ( permission.findIndex((x) => - bitwiseAndEq(this.permission, Permission[x]), + bitwiseAndEq(this.permission, Permission[x]) ) !== -1 ); } @@ -448,12 +448,11 @@ export class Server { user: string | User | ServerMember, options: DataBanCreate = {}, ): Promise { - const userId = - user instanceof User - ? user.id - : user instanceof ServerMember - ? user.id.user - : user; + const userId = user instanceof User + ? user.id + : user instanceof ServerMember + ? user.id.user + : user; const ban = await this.#collection.client.api.put( `/servers/${this.id as ""}/bans/${userId as ""}`, @@ -473,8 +472,8 @@ export class Server { typeof user === "string" ? user : user instanceof User - ? user.id - : user.id.user + ? user.id + : user.id.user }`, ); } @@ -500,7 +499,7 @@ export class Server { ); return invites.map((invite) => - ChannelInvite.from(this.#collection.client, invite), + ChannelInvite.from(this.#collection.client, invite) ); } @@ -648,10 +647,10 @@ export class Server { return { members: data.members.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member), + this.#collection.client.serverMembers.getOrCreate(member._id, member) ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user), + this.#collection.client.users.getOrCreate(user._id, user) ), }; } @@ -665,19 +664,20 @@ export class Server { query: string, ): Promise<{ members: ServerMember[]; users: User[] }> { const data = (await this.#collection.client.api.get( - `/servers/${ - this.id as "" - }/members_experimental_query?experimental_api=true&query=${encodeURIComponent( - query, - )}` as never, + `/servers/${this + .id as ""}/members_experimental_query?experimental_api=true&query=${ + encodeURIComponent( + query, + ) + }` as never, )) as AllMemberResponse; return { members: data.members.map((member) => - this.#collection.client.serverMembers.getOrCreate(member._id, member), + this.#collection.client.serverMembers.getOrCreate(member._id, member) ), users: data.users.map((user) => - this.#collection.client.users.getOrCreate(user._id, user), + this.#collection.client.users.getOrCreate(user._id, user) ), }; } @@ -715,7 +715,7 @@ export class Server { ); return emojis.map((emoji) => - this.#collection.client.emojis.getOrCreate(emoji._id, emoji), + this.#collection.client.emojis.getOrCreate(emoji._id, emoji) ); } diff --git a/src/classes/ServerBan.ts b/src/classes/ServerBan.ts index 807f15a5..298787e6 100644 --- a/src/classes/ServerBan.ts +++ b/src/classes/ServerBan.ts @@ -1,13 +1,13 @@ import type { BannedUser as APIBannedUser, - ServerBan as APIServerBan, MemberCompositeKey, + ServerBan as APIServerBan, } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; -import { BannedUser } from "./BannedUser.js"; -import type { Server } from "./Server.js"; +import { BannedUser } from "./BannedUser.ts"; +import type { Server } from "./Server.ts"; /** * Server Ban diff --git a/src/classes/ServerMember.ts b/src/classes/ServerMember.ts index 516e8104..c016fb68 100644 --- a/src/classes/ServerMember.ts +++ b/src/classes/ServerMember.ts @@ -5,17 +5,17 @@ import type { Role, } from "revolt-api"; -import type { ServerMemberCollection } from "../collections/ServerMemberCollection.js"; +import type { ServerMemberCollection } from "../collections/ServerMemberCollection.ts"; import { bitwiseAndEq, calculatePermission, -} from "../permissions/calculator.js"; -import { Permission } from "../permissions/definitions.js"; +} from "../permissions/calculator.ts"; +import { Permission } from "../permissions/definitions.ts"; -import type { Channel } from "./Channel.js"; -import type { File } from "./File.js"; -import type { Server } from "./Server.js"; -import type { User } from "./User.js"; +import type { Channel } from "./Channel.ts"; +import type { File } from "./File.ts"; +import type { Server } from "./Server.ts"; +import type { User } from "./User.ts"; /** * Deterministic conversion of member composite key to string ID diff --git a/src/classes/Session.ts b/src/classes/Session.ts index 821529e6..86edcdf0 100644 --- a/src/classes/Session.ts +++ b/src/classes/Session.ts @@ -1,6 +1,6 @@ import { decodeTime } from "ulid"; -import type { SessionCollection } from "../collections/SessionCollection.js"; +import type { SessionCollection } from "../collections/SessionCollection.ts"; /** * Session Class diff --git a/src/classes/SystemMessage.ts b/src/classes/SystemMessage.ts index 3dcfbc5e..2b84937f 100644 --- a/src/classes/SystemMessage.ts +++ b/src/classes/SystemMessage.ts @@ -1,8 +1,8 @@ import type { SystemMessage as APISystemMessage } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; -import type { User } from "./User.js"; +import type { User } from "./User.ts"; /** * System Message diff --git a/src/classes/User.ts b/src/classes/User.ts index b8439bd3..2daadedb 100644 --- a/src/classes/User.ts +++ b/src/classes/User.ts @@ -1,18 +1,18 @@ import type { - User as APIUser, DataEditUser, Presence, RelationshipStatus, + User as APIUser, } from "revolt-api"; import { decodeTime } from "ulid"; -import type { UserCollection } from "../collections/UserCollection.js"; -import type { UserBadges, UserFlags } from "../hydration/user.js"; -import { U32_MAX, UserPermission } from "../permissions/definitions.js"; +import type { UserCollection } from "../collections/UserCollection.ts"; +import type { UserBadges, UserFlags } from "../hydration/user.ts"; +import { U32_MAX, UserPermission } from "../permissions/definitions.ts"; -import type { Channel } from "./Channel.js"; -import type { File } from "./File.js"; -import { UserProfile } from "./UserProfile.js"; +import type { Channel } from "./Channel.ts"; +import type { File } from "./File.ts"; +import { UserProfile } from "./UserProfile.ts"; /** * User Class @@ -73,7 +73,7 @@ export class User { get displayName(): string { return ( this.#collection.getUnderlyingObject(this.id).displayName ?? - this.#collection.getUnderlyingObject(this.id).username + this.#collection.getUnderlyingObject(this.id).username ); } @@ -184,7 +184,7 @@ export class User { ): string | undefined { return this.online ? (this.status?.text ?? - (this.presence === "Focus" ? translate("Focus") : undefined)) + (this.presence === "Focus" ? translate("Focus") : undefined)) : undefined; } diff --git a/src/classes/UserProfile.ts b/src/classes/UserProfile.ts index a2a2b7b1..592f4c62 100644 --- a/src/classes/UserProfile.ts +++ b/src/classes/UserProfile.ts @@ -1,8 +1,8 @@ import type { UserProfile as APIUserProfile } from "revolt-api"; -import type { Client } from "../Client.js"; +import type { Client } from "../Client.ts"; -import { File } from "./File.js"; +import { File } from "./File.ts"; /** * User Profile Class diff --git a/src/classes/index.ts b/src/classes/index.ts index c34f5cd1..c2c215ea 100644 --- a/src/classes/index.ts +++ b/src/classes/index.ts @@ -1,20 +1,20 @@ -export * from "./BannedUser.js"; -export * from "./Bot.js"; -export * from "./Channel.js"; -export * from "./ChannelUnread.js"; -export * from "./ChannelWebhook.js"; -export * from "./Emoji.js"; -export * from "./File.js"; -export * from "./Invite.js"; -export * from "./Message.js"; -export * from "./MessageEmbed.js"; -export * from "./PublicBot.js"; -export * from "./PublicInvite.js"; -export * from "./Server.js"; -export * from "./ServerBan.js"; -export * from "./ServerMember.js"; -export * from "./Session.js"; -export * from "./SystemMessage.js"; -export * from "./User.js"; -export * from "./MFA.js"; -export * from "./UserProfile.js"; +export * from "./BannedUser.ts"; +export * from "./Bot.ts"; +export * from "./Channel.ts"; +export * from "./ChannelUnread.ts"; +export * from "./ChannelWebhook.ts"; +export * from "./Emoji.ts"; +export * from "./File.ts"; +export * from "./Invite.ts"; +export * from "./Message.ts"; +export * from "./MessageEmbed.ts"; +export * from "./PublicBot.ts"; +export * from "./PublicInvite.ts"; +export * from "./Server.ts"; +export * from "./ServerBan.ts"; +export * from "./ServerMember.ts"; +export * from "./Session.ts"; +export * from "./SystemMessage.ts"; +export * from "./User.ts"; +export * from "./MFA.ts"; +export * from "./UserProfile.ts"; diff --git a/src/collections/AccountCollection.ts b/src/collections/AccountCollection.ts index d0029617..d33f84e7 100644 --- a/src/collections/AccountCollection.ts +++ b/src/collections/AccountCollection.ts @@ -1,7 +1,7 @@ import type { DataCreateAccount, WebPushSubscription } from "revolt-api"; -import type { Client } from "../Client.js"; -import { MFA } from "../classes/MFA.js"; +import type { Client } from "../Client.ts"; +import { MFA } from "../classes/MFA.ts"; /** * Utility functions for working with accounts @@ -137,15 +137,15 @@ export class AccountCollection { return await this.client.api.post("/sync/settings/fetch", { keys }); } - /* eslint-disable @typescript-eslint/no-explicit-any */ /** * Set settings * @param settings Settings * @param timestamp Timestamp */ async setSettings( + // deno-lint-ignore no-explicit-any settings: Record, - timestamp = new Date().getTime(), + timestamp: number = new Date().getTime(), ): Promise { return await this.client.api.post("/sync/settings/set", { ...settings, diff --git a/src/collections/BotCollection.ts b/src/collections/BotCollection.ts index c0d02f0a..e3223927 100644 --- a/src/collections/BotCollection.ts +++ b/src/collections/BotCollection.ts @@ -1,10 +1,10 @@ import type { Bot as APIBot, OwnedBotsResponse } from "revolt-api"; -import { Bot } from "../classes/Bot.js"; -import { PublicBot } from "../classes/PublicBot.js"; -import type { HydratedBot } from "../hydration/bot.js"; +import { Bot } from "../classes/Bot.ts"; +import { PublicBot } from "../classes/PublicBot.ts"; +import type { HydratedBot } from "../hydration/bot.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Bots diff --git a/src/collections/ChannelCollection.ts b/src/collections/ChannelCollection.ts index 87faf4ec..39ba551c 100644 --- a/src/collections/ChannelCollection.ts +++ b/src/collections/ChannelCollection.ts @@ -1,10 +1,10 @@ import type { Channel as APIChannel } from "revolt-api"; -import { Channel } from "../classes/Channel.js"; -import { User } from "../classes/User.js"; -import type { HydratedChannel } from "../hydration/channel.js"; +import { Channel } from "../classes/Channel.ts"; +import { User } from "../classes/User.ts"; +import type { HydratedChannel } from "../hydration/channel.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Channels diff --git a/src/collections/ChannelUnreadCollection.ts b/src/collections/ChannelUnreadCollection.ts index fb13a1a1..ce1b7571 100644 --- a/src/collections/ChannelUnreadCollection.ts +++ b/src/collections/ChannelUnreadCollection.ts @@ -1,9 +1,9 @@ import type { ChannelUnread as APIChannelUnread } from "revolt-api"; -import { ChannelUnread } from "../classes/ChannelUnread.js"; -import type { HydratedChannelUnread } from "../hydration/channelUnread.js"; +import { ChannelUnread } from "../classes/ChannelUnread.ts"; +import type { HydratedChannelUnread } from "../hydration/channelUnread.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Channel Unreads diff --git a/src/collections/ChannelWebhookCollection.ts b/src/collections/ChannelWebhookCollection.ts index f0da0f51..38dd93c7 100644 --- a/src/collections/ChannelWebhookCollection.ts +++ b/src/collections/ChannelWebhookCollection.ts @@ -1,9 +1,9 @@ import type { Webhook } from "revolt-api"; -import { ChannelWebhook } from "../classes/ChannelWebhook.js"; -import type { HydratedChannelWebhook } from "../hydration/channelWebhook.js"; +import { ChannelWebhook } from "../classes/ChannelWebhook.ts"; +import type { HydratedChannelWebhook } from "../hydration/channelWebhook.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Channel Webhooks diff --git a/src/collections/Collection.ts b/src/collections/Collection.ts index 091fae62..993da8da 100644 --- a/src/collections/Collection.ts +++ b/src/collections/Collection.ts @@ -1,5 +1,5 @@ -import type { Client } from "../Client.js"; -import { type Hydrators, hydrate } from "../hydration/index.js"; +import type { Client } from "../Client.ts"; +import { hydrate, type Hydrators } from "../hydration/index.ts"; /** * Collection backed by a store @@ -119,7 +119,7 @@ export class Collection { * Iterable of keys in the map * @returns Iterable */ - keys(): MapIterator { + keys(): IterableIterator { return this.#objects.keys(); } @@ -127,7 +127,7 @@ export class Collection { * Iterable of values in the map * @returns Iterable */ - values(): MapIterator { + values(): IterableIterator { return this.#objects.values(); } @@ -135,7 +135,7 @@ export class Collection { * Iterable of key, value pairs in the map * @returns Iterable */ - entries(): MapIterator<[string, T]> { + entries(): IterableIterator<[string, T]> { return this.#objects.entries(); } diff --git a/src/collections/EmojiCollection.ts b/src/collections/EmojiCollection.ts index a661c4f1..d6ec598f 100644 --- a/src/collections/EmojiCollection.ts +++ b/src/collections/EmojiCollection.ts @@ -1,9 +1,9 @@ import type { Emoji as APIEmoji } from "revolt-api"; -import { Emoji } from "../classes/Emoji.js"; -import type { HydratedEmoji } from "../hydration/emoji.js"; +import { Emoji } from "../classes/Emoji.ts"; +import type { HydratedEmoji } from "../hydration/emoji.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Emoji diff --git a/src/collections/MessageCollection.ts b/src/collections/MessageCollection.ts index 08b8d606..bd658750 100644 --- a/src/collections/MessageCollection.ts +++ b/src/collections/MessageCollection.ts @@ -1,9 +1,9 @@ import type { Message as APIMessage } from "revolt-api"; -import { Message } from "../classes/Message.js"; -import type { HydratedMessage } from "../hydration/message.js"; +import { Message } from "../classes/Message.ts"; +import type { HydratedMessage } from "../hydration/message.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Messages diff --git a/src/collections/ServerCollection.ts b/src/collections/ServerCollection.ts index 2c9f658b..6f90460f 100644 --- a/src/collections/ServerCollection.ts +++ b/src/collections/ServerCollection.ts @@ -1,13 +1,13 @@ import type { - Server as APIServer, Channel, DataCreateServer, + Server as APIServer, } from "revolt-api"; -import { Server } from "../classes/Server.js"; -import type { HydratedServer } from "../hydration/server.js"; +import { Server } from "../classes/Server.ts"; +import type { HydratedServer } from "../hydration/server.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Servers diff --git a/src/collections/ServerMemberCollection.ts b/src/collections/ServerMemberCollection.ts index 9312b409..c472bc77 100644 --- a/src/collections/ServerMemberCollection.ts +++ b/src/collections/ServerMemberCollection.ts @@ -1,9 +1,9 @@ import type { Member, MemberCompositeKey } from "revolt-api"; -import { ServerMember } from "../classes/ServerMember.js"; -import type { HydratedServerMember } from "../hydration/serverMember.js"; +import { ServerMember } from "../classes/ServerMember.ts"; +import type { HydratedServerMember } from "../hydration/serverMember.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Server Members diff --git a/src/collections/SessionCollection.ts b/src/collections/SessionCollection.ts index 0d638ea1..e2c8d5a3 100644 --- a/src/collections/SessionCollection.ts +++ b/src/collections/SessionCollection.ts @@ -1,9 +1,9 @@ import type { SessionInfo } from "revolt-api"; -import { Session } from "../classes/Session.js"; -import type { HydratedSession } from "../hydration/session.js"; +import { Session } from "../classes/Session.ts"; +import type { HydratedSession } from "../hydration/session.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Sessions diff --git a/src/collections/UserCollection.ts b/src/collections/UserCollection.ts index b721fdce..4c036108 100644 --- a/src/collections/UserCollection.ts +++ b/src/collections/UserCollection.ts @@ -1,10 +1,10 @@ import type { User as APIUser } from "revolt-api"; -import type { Client } from "../Client.js"; -import { User } from "../classes/User.js"; -import type { HydratedUser } from "../hydration/user.js"; +import type { Client } from "../Client.ts"; +import { User } from "../classes/User.ts"; +import type { HydratedUser } from "../hydration/user.ts"; -import { Collection } from "./Collection.js"; +import { Collection } from "./Collection.ts"; /** * Collection of Users diff --git a/src/collections/index.ts b/src/collections/index.ts index 401f0677..4c4be57a 100644 --- a/src/collections/index.ts +++ b/src/collections/index.ts @@ -1,11 +1,11 @@ -export { BotCollection } from "./BotCollection.js"; -export { ChannelCollection } from "./ChannelCollection.js"; -export { ChannelUnreadCollection } from "./ChannelUnreadCollection.js"; -export { ChannelWebhookCollection } from "./ChannelWebhookCollection.js"; -export { Collection } from "./Collection.js"; -export { EmojiCollection } from "./EmojiCollection.js"; -export { MessageCollection } from "./MessageCollection.js"; -export { ServerCollection } from "./ServerCollection.js"; -export { ServerMemberCollection } from "./ServerMemberCollection.js"; -export { SessionCollection } from "./SessionCollection.js"; -export { UserCollection } from "./UserCollection.js"; +export { BotCollection } from "./BotCollection.ts"; +export { ChannelCollection } from "./ChannelCollection.ts"; +export { ChannelUnreadCollection } from "./ChannelUnreadCollection.ts"; +export { ChannelWebhookCollection } from "./ChannelWebhookCollection.ts"; +export { Collection } from "./Collection.ts"; +export { EmojiCollection } from "./EmojiCollection.ts"; +export { MessageCollection } from "./MessageCollection.ts"; +export { ServerCollection } from "./ServerCollection.ts"; +export { ServerMemberCollection } from "./ServerMemberCollection.ts"; +export { SessionCollection } from "./SessionCollection.ts"; +export { UserCollection } from "./UserCollection.ts"; diff --git a/src/events/EventClient.ts b/src/events/EventClient.ts index c037e719..b17c038a 100644 --- a/src/events/EventClient.ts +++ b/src/events/EventClient.ts @@ -1,7 +1,7 @@ import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter"; import type { Error } from "revolt-api"; -import type { ProtocolV1 } from "./v1.js"; +import type { ProtocolV1 } from "./v1.ts"; /** * Available protocols to connect with @@ -63,9 +63,9 @@ export interface EventClientOptions { * Events provided by the client. */ type Events> = { - error: [Error]; - event: [P["server"]]; - state: [ConnectionState]; + error: [error: Error]; + event: [event: P["server"]]; + state: [state: ConnectionState]; }; /** @@ -87,7 +87,7 @@ export class EventClient< #pongTimeoutReference: number | undefined; #connectTimeoutReference: number | undefined; - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // deno-lint-ignore no-explicit-any #lastError?: { type: "socket"; data: any } | { type: "revolt"; data: Error }; /** diff --git a/src/events/v1.ts b/src/events/v1.ts index ed887bab..0b7953fb 100644 --- a/src/events/v1.ts +++ b/src/events/v1.ts @@ -15,9 +15,9 @@ import type { User, } from "revolt-api"; -import type { Client } from "../Client.js"; -import { MessageEmbed } from "../classes/MessageEmbed.js"; -import { hydrate } from "../hydration/index.js"; +import type { Client } from "../Client.ts"; +import { MessageEmbed } from "../classes/MessageEmbed.ts"; +import { hydrate } from "../hydration/index.ts"; /** * Version 1 of the events protocol @@ -33,21 +33,21 @@ export type ProtocolV1 = { type ClientMessage = | { type: "Authenticate"; token: string } | { - type: "BeginTyping"; - channel: string; - } + type: "BeginTyping"; + channel: string; + } | { - type: "EndTyping"; - channel: string; - } + type: "EndTyping"; + channel: string; + } | { - type: "Ping"; - data: number; - } + type: "Ping"; + data: number; + } | { - type: "Pong"; - data: number; - }; + type: "Pong"; + data: number; + }; /** * Messages sent from the server @@ -61,46 +61,46 @@ type ServerMessage = | { type: "Pong"; data: number } | ({ type: "Message" } & Message) | { - type: "MessageUpdate"; - id: string; - channel: string; - data: Partial; - } + type: "MessageUpdate"; + id: string; + channel: string; + data: Partial; + } | { - type: "MessageAppend"; - id: string; - channel: string; - append: Pick, "embeds">; - } + type: "MessageAppend"; + id: string; + channel: string; + append: Pick, "embeds">; + } | { type: "MessageDelete"; id: string; channel: string } | { - type: "MessageReact"; - id: string; - channel_id: string; - user_id: string; - emoji_id: string; - } + type: "MessageReact"; + id: string; + channel_id: string; + user_id: string; + emoji_id: string; + } | { - type: "MessageUnreact"; - id: string; - channel_id: string; - user_id: string; - emoji_id: string; - } + type: "MessageUnreact"; + id: string; + channel_id: string; + user_id: string; + emoji_id: string; + } | { - type: "MessageRemoveReaction"; - id: string; - channel_id: string; - emoji_id: string; - } + type: "MessageRemoveReaction"; + id: string; + channel_id: string; + emoji_id: string; + } | { type: "BulkMessageDelete"; channel: string; ids: string[] } | ({ type: "ChannelCreate" } & Channel) | { - type: "ChannelUpdate"; - id: string; - data: Partial; - clear?: FieldsChannel[]; - } + type: "ChannelUpdate"; + id: string; + data: Partial; + clear?: FieldsChannel[]; + } | { type: "ChannelDelete"; id: string } | { type: "ChannelGroupJoin"; id: string; user: string } | { type: "ChannelGroupLeave"; id: string; user: string } @@ -108,63 +108,66 @@ type ServerMessage = | { type: "ChannelStopTyping"; id: string; user: string } | { type: "ChannelAck"; id: string; user: string; message_id: string } | { - type: "ServerCreate"; - id: string; - server: Server; - channels: Channel[]; - } + type: "ServerCreate"; + id: string; + server: Server; + channels: Channel[]; + } | { - type: "ServerUpdate"; - id: string; - data: Partial; - clear?: FieldsServer[]; - } + type: "ServerUpdate"; + id: string; + data: Partial; + clear?: FieldsServer[]; + } | { type: "ServerDelete"; id: string } | { - type: "ServerMemberUpdate"; - id: MemberCompositeKey; - data: Partial; - clear?: FieldsMember[]; - } + type: "ServerMemberUpdate"; + id: MemberCompositeKey; + data: Partial; + clear?: FieldsMember[]; + } | { type: "ServerMemberJoin"; id: string; user: string } | { type: "ServerMemberLeave"; id: string; user: string } | { - type: "ServerRoleUpdate"; - id: string; - role_id: string; - data: Partial; - } + type: "ServerRoleUpdate"; + id: string; + role_id: string; + data: Partial; + } | { type: "ServerRoleDelete"; id: string; role_id: string } | { - type: "UserUpdate"; - id: string; - data: Partial; - clear?: FieldsUser[]; - } + type: "UserUpdate"; + id: string; + data: Partial; + clear?: FieldsUser[]; + } | { type: "UserRelationship"; user: User; status: RelationshipStatus } | { type: "UserPresence"; id: string; online: boolean } | { - type: "UserSettingsUpdate"; - id: string; - update: { [key: string]: [number, string] }; - } + type: "UserSettingsUpdate"; + id: string; + update: { [key: string]: [number, string] }; + } | { type: "UserPlatformWipe"; user_id: string; flags: number } | ({ type: "EmojiCreate" } & Emoji) | { type: "EmojiDelete"; id: string } - | ({ + | ( + & { type: "Auth"; - } & ( + } + & ( | { - event_type: "DeleteSession"; - user_id: string; - session_id: string; - } + event_type: "DeleteSession"; + user_id: string; + session_id: string; + } | { - event_type: "DeleteAllSessions"; - user_id: string; - exclude_session_id: string; - } - )); + event_type: "DeleteAllSessions"; + user_id: string; + exclude_session_id: string; + } + ) + ); /** * Initial synchronisation packet @@ -288,7 +291,7 @@ export async function handleEvent( client.messages.setUnderlyingKey(event.id, "embeds", [ ...(previousMessage.embeds ?? []), ...(event.append.embeds?.map((embed) => - MessageEmbed.from(client, embed), + MessageEmbed.from(client, embed) ) ?? []), ]); diff --git a/src/hydration/bot.ts b/src/hydration/bot.ts index 207b97c1..bed9ffdc 100644 --- a/src/hydration/bot.ts +++ b/src/hydration/bot.ts @@ -1,6 +1,6 @@ import type { Bot } from "revolt-api"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedBot = { id: string; @@ -41,4 +41,5 @@ export const botHydration: Hydrate = { /** * Flags attributed to users */ +// deno-lint-ignore no-empty-enum export enum BotFlags {} diff --git a/src/hydration/channel.ts b/src/hydration/channel.ts index c4338328..da917598 100644 --- a/src/hydration/channel.ts +++ b/src/hydration/channel.ts @@ -1,10 +1,10 @@ import type { Channel, OverrideField } from "revolt-api"; -import type { Client } from "../Client.js"; -import { File } from "../classes/File.js"; -import type { Merge } from "../lib/merge.js"; +import type { Client } from "../Client.ts"; +import { File } from "../classes/File.ts"; +import type { Merge } from "../lib/merge.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedChannel = { id: string; diff --git a/src/hydration/channelUnread.ts b/src/hydration/channelUnread.ts index 73a98720..d9010428 100644 --- a/src/hydration/channelUnread.ts +++ b/src/hydration/channelUnread.ts @@ -1,8 +1,8 @@ import type { ChannelUnread } from "revolt-api"; -import type { Merge } from "../lib/merge.js"; +import type { Merge } from "../lib/merge.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedChannelUnread = { id: string; diff --git a/src/hydration/channelWebhook.ts b/src/hydration/channelWebhook.ts index ecf3abfb..6188d615 100644 --- a/src/hydration/channelWebhook.ts +++ b/src/hydration/channelWebhook.ts @@ -1,10 +1,10 @@ import type { Webhook } from "revolt-api"; -import type { Client } from "../Client.js"; -import { File } from "../classes/File.js"; -import type { Merge } from "../lib/merge.js"; +import type { Client } from "../Client.ts"; +import { File } from "../classes/File.ts"; +import type { Merge } from "../lib/merge.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedChannelWebhook = { id: string; diff --git a/src/hydration/emoji.ts b/src/hydration/emoji.ts index 85257983..df91fbea 100644 --- a/src/hydration/emoji.ts +++ b/src/hydration/emoji.ts @@ -1,8 +1,8 @@ import type { Emoji, EmojiParent } from "revolt-api"; -import type { Merge } from "../lib/merge.js"; +import type { Merge } from "../lib/merge.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedEmoji = { id: string; diff --git a/src/hydration/index.ts b/src/hydration/index.ts index 92d24a6a..6eb9dd25 100644 --- a/src/hydration/index.ts +++ b/src/hydration/index.ts @@ -1,13 +1,13 @@ -import { botHydration } from "./bot.js"; -import { channelHydration } from "./channel.js"; -import { channelUnreadHydration } from "./channelUnread.js"; -import { channelWebhookHydration } from "./channelWebhook.js"; -import { emojiHydration } from "./emoji.js"; -import { messageHydration } from "./message.js"; -import { serverHydration } from "./server.js"; -import { serverMemberHydration } from "./serverMember.js"; -import { sessionHydration } from "./session.js"; -import { userHydration } from "./user.js"; +import { botHydration } from "./bot.ts"; +import { channelHydration } from "./channel.ts"; +import { channelUnreadHydration } from "./channelUnread.ts"; +import { channelWebhookHydration } from "./channelWebhook.ts"; +import { emojiHydration } from "./emoji.ts"; +import { messageHydration } from "./message.ts"; +import { serverHydration } from "./server.ts"; +import { serverMemberHydration } from "./serverMember.ts"; +import { sessionHydration } from "./session.ts"; +import { userHydration } from "./user.ts"; /** * Functions to map from one object to another @@ -81,10 +81,10 @@ const hydrators = { export type Hydrators = typeof hydrators; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// deno-lint-ignore no-explicit-any type ExtractInput = T extends Hydrate ? I : never; -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// deno-lint-ignore no-explicit-any type ExtractOutput = T extends Hydrate ? O : never; /** diff --git a/src/hydration/message.ts b/src/hydration/message.ts index c5b76f7b..435e84d5 100644 --- a/src/hydration/message.ts +++ b/src/hydration/message.ts @@ -1,13 +1,13 @@ import type { Interactions, Masquerade, Message } from "revolt-api"; -import type { Client } from "../Client.js"; -import { File } from "../classes/File.js"; -import { MessageWebhook } from "../classes/Message.js"; -import { MessageEmbed } from "../classes/MessageEmbed.js"; -import { SystemMessage } from "../classes/SystemMessage.js"; -import type { Merge } from "../lib/merge.js"; +import type { Client } from "../Client.ts"; +import { File } from "../classes/File.ts"; +import { MessageWebhook } from "../classes/Message.ts"; +import { MessageEmbed } from "../classes/MessageEmbed.ts"; +import { SystemMessage } from "../classes/SystemMessage.ts"; +import type { Merge } from "../lib/merge.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedMessage = { id: string; diff --git a/src/hydration/server.ts b/src/hydration/server.ts index 2fdaa05e..cde73f14 100644 --- a/src/hydration/server.ts +++ b/src/hydration/server.ts @@ -1,9 +1,9 @@ import type { Category, Role, Server, SystemMessageChannels } from "revolt-api"; -import type { Client } from "../Client.js"; -import { File } from "../classes/File.js"; +import type { Client } from "../Client.ts"; +import { File } from "../classes/File.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedServer = { id: string; diff --git a/src/hydration/serverMember.ts b/src/hydration/serverMember.ts index 91cb6080..54feb44f 100644 --- a/src/hydration/serverMember.ts +++ b/src/hydration/serverMember.ts @@ -1,10 +1,10 @@ import type { Member, MemberCompositeKey } from "revolt-api"; -import type { Client } from "../Client.js"; -import { File } from "../classes/File.js"; -import type { Merge } from "../lib/merge.js"; +import type { Client } from "../Client.ts"; +import { File } from "../classes/File.ts"; +import type { Merge } from "../lib/merge.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedServerMember = { id: MemberCompositeKey; diff --git a/src/hydration/session.ts b/src/hydration/session.ts index 6c375cbb..7f37f873 100644 --- a/src/hydration/session.ts +++ b/src/hydration/session.ts @@ -1,6 +1,6 @@ import type { SessionInfo } from "revolt-api"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedSession = { id: string; diff --git a/src/hydration/user.ts b/src/hydration/user.ts index e7b83db2..e0240315 100644 --- a/src/hydration/user.ts +++ b/src/hydration/user.ts @@ -5,10 +5,10 @@ import type { UserStatus, } from "revolt-api"; -import type { Client } from "../Client.js"; -import { File } from "../classes/File.js"; +import type { Client } from "../Client.ts"; +import { File } from "../classes/File.ts"; -import type { Hydrate } from "./index.js"; +import type { Hydrate } from "./index.ts"; export type HydratedUser = { id: string; diff --git a/src/index.ts b/src/index.ts index 7c037626..7d64bd5c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,9 @@ -export { Client } from "./Client.js"; -export type { ClientOptions, Session as PrivateSession } from "./Client.js"; -export * from "./classes/index.js"; -export * from "./collections/index.js"; -export { ConnectionState, EventClient } from "./events/EventClient.js"; -export { BotFlags } from "./hydration/bot.js"; -export { ServerFlags } from "./hydration/server.js"; -export { UserBadges, UserFlags } from "./hydration/user.js"; -export * from "./lib/regex.js"; +export { Client } from "./Client.ts"; +export type { ClientOptions, Session as PrivateSession } from "./Client.ts"; +export * from "./classes/index.ts"; +export * from "./collections/index.ts"; +export { ConnectionState, EventClient } from "./events/EventClient.ts"; +export { BotFlags } from "./hydration/bot.ts"; +export { ServerFlags } from "./hydration/server.ts"; +export { UserBadges, UserFlags } from "./hydration/user.ts"; +export * from "./lib/regex.ts"; diff --git a/src/lib/merge.ts b/src/lib/merge.ts index 99324d55..510a206b 100644 --- a/src/lib/merge.ts +++ b/src/lib/merge.ts @@ -1,21 +1,23 @@ // Merge type provided by https://dev.to/lucianbc/union-type-merging-in-typescript-9al -export type Merge = { - [k in CommonKeys]: PickTypeOf; -} & { - [k in NonCommonKeys]?: PickTypeOf; -}; +export type Merge = + & { + [k in CommonKeys]: PickTypeOf; + } + & { + [k in NonCommonKeys]?: PickTypeOf; + }; -type PickTypeOf = - K extends AllKeys ? PickType : never; +type PickTypeOf = K extends AllKeys + ? PickType + : never; -// eslint-disable-next-line -type PickType> = T extends { [k in K]?: any } - ? T[K] +// deno-lint-ignore no-explicit-any +type PickType> = T extends { [k in K]?: any } ? T[K] : undefined; type Subtract = A extends C ? never : A; type NonCommonKeys = Subtract, CommonKeys>; -// eslint-disable-next-line +// deno-lint-ignore no-explicit-any type AllKeys = T extends any ? keyof T : never; type CommonKeys = keyof T; diff --git a/src/permissions/calculator.ts b/src/permissions/calculator.ts index dde5e10a..d47b3864 100644 --- a/src/permissions/calculator.ts +++ b/src/permissions/calculator.ts @@ -1,7 +1,7 @@ -import type { Client } from "../Client.js"; -import type { Channel } from "../classes/Channel.js"; -import { Server } from "../classes/Server.js"; -import type { ServerMember } from "../classes/ServerMember.js"; +import type { Client } from "../Client.ts"; +import type { Channel } from "../classes/Channel.ts"; +import { Server } from "../classes/Server.ts"; +import type { ServerMember } from "../classes/ServerMember.ts"; import { ALLOW_IN_TIMEOUT, @@ -9,7 +9,7 @@ import { DEFAULT_PERMISSION_VIEW_ONLY, Permission, UserPermission, -} from "./definitions.js"; +} from "./definitions.ts"; /** * Check whether `b` is present in `a` @@ -126,8 +126,7 @@ export function calculatePermission( // 6. Apply default allows and denies for channel. if (target.defaultPermissions) { - perm = - (perm | BigInt(target.defaultPermissions.a)) & + perm = (perm | BigInt(target.defaultPermissions.a)) & ~BigInt(target.defaultPermissions.d); } diff --git a/src/permissions/definitions.ts b/src/permissions/definitions.ts index f711adf3..abe05f25 100644 --- a/src/permissions/definitions.ts +++ b/src/permissions/definitions.ts @@ -99,20 +99,19 @@ export const U32_MAX = 2 ** 32 - 1; // 4294967295 /** * Permissions allowed for a user while in timeout */ -export const ALLOW_IN_TIMEOUT = - Permission.ViewChannel + Permission.ReadMessageHistory; +export const ALLOW_IN_TIMEOUT = Permission.ViewChannel + + Permission.ReadMessageHistory; /** * Default permissions if we can only view */ -export const DEFAULT_PERMISSION_VIEW_ONLY = - Permission.ViewChannel + Permission.ReadMessageHistory; +export const DEFAULT_PERMISSION_VIEW_ONLY = Permission.ViewChannel + + Permission.ReadMessageHistory; /** * Default base permissions for channels */ -export const DEFAULT_PERMISSION = - DEFAULT_PERMISSION_VIEW_ONLY + +export const DEFAULT_PERMISSION = DEFAULT_PERMISSION_VIEW_ONLY + Permission.SendMessage + Permission.InviteOthers + Permission.SendEmbeds + @@ -128,14 +127,13 @@ export const DEFAULT_PERMISSION_SAVED_MESSAGES = Permission.GrantAllSafe; /** * Permissions in direct message channels / default permissions for group DMs */ -export const DEFAULT_PERMISSION_DIRECT_MESSAGE = - DEFAULT_PERMISSION + Permission.React + Permission.ManageChannel; +export const DEFAULT_PERMISSION_DIRECT_MESSAGE = DEFAULT_PERMISSION + + Permission.React + Permission.ManageChannel; /** * Permissions in server text / voice channel */ -export const DEFAULT_PERMISSION_SERVER = - DEFAULT_PERMISSION + +export const DEFAULT_PERMISSION_SERVER = DEFAULT_PERMISSION + Permission.React + Permission.ChangeNickname + Permission.ChangeAvatar; diff --git a/test.mjs b/test.mjs deleted file mode 100755 index 1f48b108..00000000 --- a/test.mjs +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env -S node --env-file test.mjs -/* eslint-disable no-undef */ -import { Client } from "./lib/index.js"; - -const client = new Client({ debug: true }); - -client.on("ready", () => console.info(`Logged in as ${client.user.username}!`)); -client.on("disconnected", () => console.info("Disconnected.")); - -client.on("messageCreate", (message) => console.info(message.content)); - -client.loginBot(process.env.TOKEN); diff --git a/tsconfig.json b/tsconfig.json index a39ec41d..a320659e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,13 @@ { "compilerOptions": { + "allowImportingTsExtensions": true, "target": "ES2022", "module": "ES6", "moduleResolution": "node", "rootDir": "./src", "declaration": true, "declarationMap": true, + "lib": ["ES2022", "DOM"], "outDir": "./lib", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, From 02a541339d22c836adf7ed27a51d000817dfc149 Mon Sep 17 00:00:00 2001 From: Jersey Date: Fri, 14 Mar 2025 16:35:57 -0400 Subject: [PATCH 7/9] BREAKING CHANGE: remove solid.js dependency and redo collection interface --- .eslintrc.json | 3 +- .vscode/settings.json | 5 +- package.json | 5 +- src/Client.ts | 41 ++-- src/classes/Channel.ts | 33 ++- src/classes/ChannelWebhook.ts | 2 +- src/classes/MFA.ts | 30 ++- src/classes/PublicInvite.ts | 22 +- src/classes/Server.ts | 92 ++++---- src/classes/Session.ts | 2 +- src/classes/User.ts | 2 +- src/collections/BotCollection.ts | 14 +- src/collections/ChannelCollection.ts | 7 +- src/collections/ChannelUnreadCollection.ts | 20 +- src/collections/ChannelWebhookCollection.ts | 4 +- src/collections/Collection.ts | 225 ++++++++------------ src/collections/EmojiCollection.ts | 4 +- src/collections/MessageCollection.ts | 7 +- src/collections/ServerCollection.ts | 28 +-- src/collections/ServerMemberCollection.ts | 4 +- src/collections/SessionCollection.ts | 13 +- src/collections/UserCollection.ts | 4 +- src/events/EventClient.ts | 29 +-- src/events/v1.ts | 189 ++++++++-------- src/hydration/channel.ts | 13 +- src/hydration/channelUnread.ts | 8 +- src/hydration/message.ts | 11 +- src/hydration/server.ts | 16 +- src/storage/ObjectStorage.ts | 44 ---- 29 files changed, 348 insertions(+), 529 deletions(-) delete mode 100644 src/storage/ObjectStorage.ts diff --git a/.eslintrc.json b/.eslintrc.json index 589d74e4..77ffa33a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,10 +1,9 @@ { "root": true, "parser": "@typescript-eslint/parser", - "plugins": ["solid", "spellcheck"], + "plugins": ["spellcheck"], "extends": [ "eslint:recommended", - "plugin:solid/typescript", "plugin:@typescript-eslint/recommended", "prettier" ], diff --git a/.vscode/settings.json b/.vscode/settings.json index 9bf4d12b..c4aecfc3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true + "editor.formatOnSave": true, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } } diff --git a/package.json b/package.json index 1bb75f60..8b692830 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,6 @@ "description": "Library for interacting with the Revolt API.", "packageManager": "pnpm@9.4.0", "dependencies": { - "@solid-primitives/map": "^0.4.11", - "@solid-primitives/set": "^0.4.11", "eventemitter3": "^5.0.1", "isomorphic-ws": "^5.0.0", "long": "^5.2.3", @@ -46,7 +44,6 @@ "dotenv": "^16.4.5", "eslint": "^8.57.0", "eslint-config-prettier": "^8.10.0", - "eslint-plugin-solid": "^0.12.1", "eslint-plugin-spellcheck": "^0.0.20", "prettier": "^2.8.8", "tsc-watch": "^6.0.4", @@ -54,4 +51,4 @@ "typedoc": "^0.25.1", "typescript": "^5.4.2" } -} \ No newline at end of file +} diff --git a/src/Client.ts b/src/Client.ts index 994bdad1..b5d050b9 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,7 +1,5 @@ -import { Accessor, Setter, batch, createSignal } from "solid-js"; - import EventEmitter from "eventemitter3"; -import type { DataLogin, Error, RevoltConfig } from "revolt-api"; +import type { DataLogin, RevoltConfig } from "revolt-api"; import { API, Role } from "revolt-api"; import { @@ -180,11 +178,9 @@ export class Client extends EventEmitter { #session: Session | undefined; user: User | undefined; - readonly ready: Accessor; - #setReady: Setter; + ready = false; + connectionFailureCount = 0; - readonly connectionFailureCount: Accessor; - #setConnectionFailureCount: Setter; #reconnectTimeout: number | undefined; /** @@ -225,14 +221,6 @@ export class Client extends EventEmitter { baseURL: this.options.baseURL, }); - const [ready, setReady] = createSignal(false); - this.ready = ready; - this.#setReady = setReady; - - const [connectionFailureCount, setConnectionFailureCount] = createSignal(0); - this.connectionFailureCount = connectionFailureCount; - this.#setConnectionFailureCount = setConnectionFailureCount; - this.account = new AccountCollection(this); this.bots = new BotCollection(this); this.channels = new ChannelCollection(this); @@ -250,11 +238,9 @@ export class Client extends EventEmitter { this.events.on("state", (state) => { switch (state) { case ConnectionState.Connected: - batch(() => { - this.servers.forEach((server) => server.resetSyncStatus()); - this.#setConnectionFailureCount(0); - this.emit("connected"); - }); + this.servers.forEach((server) => server.resetSyncStatus()); + this.connectionFailureCount = 0; + this.emit("connected"); break; case ConnectionState.Connecting: this.emit("connecting"); @@ -264,18 +250,23 @@ export class Client extends EventEmitter { if (this.options.autoReconnect) { this.#reconnectTimeout = setTimeout( () => this.connect(), - this.options.retryDelayFunction(this.connectionFailureCount()) * - 1e3 + this.options.retryDelayFunction(this.connectionFailureCount) * 1e3 ) as never; - this.#setConnectionFailureCount((count) => count + 1); + this.connectionFailureCount += 1; } break; } }); this.events.on("event", (event) => - handleEventV1(this, event, this.#setReady) + handleEventV1( + this, + event, + ((value: boolean) => { + this.ready = value; + }).bind(this) + ) ); } @@ -301,7 +292,7 @@ export class Client extends EventEmitter { connect() { clearTimeout(this.#reconnectTimeout); this.events.disconnect(); - this.#setReady(false); + this.ready = false; this.events.connect( this.configuration?.ws ?? "wss://ws.revolt.chat", typeof this.#session === "string" ? this.#session : this.#session!.token diff --git a/src/classes/Channel.ts b/src/classes/Channel.ts index 02220ccc..2ddd8769 100644 --- a/src/classes/Channel.ts +++ b/src/classes/Channel.ts @@ -1,5 +1,3 @@ -import { batch } from "solid-js"; - import type { Member as ApiMember, Message as ApiMessage, @@ -381,10 +379,8 @@ export class Channel { `/channels/${this.id as ""}/members` ); - return batch(() => - members.map((user) => - this.#collection.client.users.getOrCreate(user._id, user) - ) + return members.map((user) => + this.#collection.client.users.getOrCreate(user._id, user) ); } @@ -398,10 +394,8 @@ export class Channel { `/channels/${this.id as ""}/webhooks` ); - return batch(() => - webhooks.map((webhook) => - this.#collection.client.channelWebhooks.getOrCreate(webhook.id, webhook) - ) + return webhooks.map((webhook) => + this.#collection.client.channelWebhooks.getOrCreate(webhook.id, webhook) ); } @@ -424,7 +418,7 @@ export class Channel { }); if (this.type === "DirectMessage") { - this.#collection.updateUnderlyingObject(this.id, "active", false); + this.#collection.setUnderlyingKey(this.id, "active", false); return; } @@ -549,7 +543,7 @@ export class Channel { { ...params, include_users: true } )) as { messages: ApiMessage[]; users: ApiUser[]; members?: ApiMember[] }; - return batch(() => ({ + return { messages: data.messages.map((message) => this.#collection.client.messages.getOrCreate(message._id, message) ), @@ -559,7 +553,7 @@ export class Channel { members: data.members?.map((member) => this.#collection.client.serverMembers.getOrCreate(member._id, member) ), - })); + }; } /** @@ -574,10 +568,8 @@ export class Channel { params )) as ApiMessage[]; - return batch(() => - messages.map((message) => - this.#collection.client.messages.getOrCreate(message._id, message) - ) + return messages.map((message) => + this.#collection.client.messages.getOrCreate(message._id, message) ); } @@ -596,7 +588,7 @@ export class Channel { } )) as { messages: ApiMessage[]; users: ApiUser[]; members?: ApiMember[] }; - return batch(() => ({ + return { messages: data.messages.map((message) => this.#collection.client.messages.getOrCreate(message._id, message) ), @@ -606,7 +598,7 @@ export class Channel { members: data.members?.map((member) => this.#collection.client.serverMembers.getOrCreate(member._id, member) ), - })); + }; } /** @@ -669,7 +661,8 @@ export class Channel { const unreads = this.#collection.client.channelUnreads; const channelUnread = unreads.get(this.id); if (channelUnread) { - unreads.updateUnderlyingObject(this.id, { + unreads.setUnderlyingObject(this.id, { + ...unreads.getUnderlyingObject(this.id), lastMessageId, }); diff --git a/src/classes/ChannelWebhook.ts b/src/classes/ChannelWebhook.ts index aa73fcf9..07b35a77 100644 --- a/src/classes/ChannelWebhook.ts +++ b/src/classes/ChannelWebhook.ts @@ -82,7 +82,7 @@ export class ChannelWebhook { data ); - this.#collection.updateUnderlyingObject( + this.#collection.setUnderlyingObject( this.id, // @ts-expect-error not in prod hydrate("channelWebhook", webhook, this.#collection.client) diff --git a/src/classes/MFA.ts b/src/classes/MFA.ts index 739c1e86..577e75c1 100644 --- a/src/classes/MFA.ts +++ b/src/classes/MFA.ts @@ -1,5 +1,3 @@ -import { SetStoreFunction, createStore } from "solid-js/store"; - import { MFAMethod, MFAResponse, @@ -14,7 +12,7 @@ import { Client } from "../index.js"; */ export class MFA { #client: Client; - #store: [MultiFactorStatus, SetStoreFunction]; + #store: MultiFactorStatus; /** * Construct MFA helper @@ -23,21 +21,30 @@ export class MFA { */ constructor(client: Client, state: MultiFactorStatus) { this.#client = client; - this.#store = createStore(state); + this.#store = state; + } + + /** + * Mutate the store + * @param key Key + * @param value Value + */ + #mutateStore(key: keyof MultiFactorStatus, value: boolean) { + this.#store[key] = value; } /** * Whether authenticator app is enabled */ get authenticatorEnabled() { - return this.#store[0].totp_mfa; + return this.#store.totp_mfa; } /** * Whether recovery codes are enabled */ get recoveryEnabled() { - return this.#store[0].recovery_active; + return this.#store.recovery_active; } /** @@ -59,7 +66,10 @@ export class MFA { createTicket(params: MFAResponse) { return this.#client.api .put("/auth/mfa/ticket", params) - .then((ticket) => new MFATicket(this.#client, ticket, this.#store[1])); + .then( + (ticket) => + new MFATicket(this.#client, ticket, this.#mutateStore.bind(this)) + ); } /** @@ -68,7 +78,7 @@ export class MFA { */ async enableAuthenticator(token: string) { await this.#client.api.put("/auth/mfa/totp", { totp_code: token }); - this.#store[1]("totp_mfa", true); + this.#mutateStore("totp_mfa", true); } } @@ -78,7 +88,7 @@ export class MFA { export class MFATicket { #client: Client; #ticket: TicketType; - #mutate: SetStoreFunction; + #mutate: (key: keyof MultiFactorStatus, value: boolean) => void; #used = false; /** @@ -90,7 +100,7 @@ export class MFATicket { constructor( client: Client, ticket: TicketType, - mutate: SetStoreFunction + mutate: (key: keyof MultiFactorStatus, value: boolean) => void ) { this.#client = client; this.#ticket = ticket; diff --git a/src/classes/PublicInvite.ts b/src/classes/PublicInvite.ts index 68444d87..cfbda196 100644 --- a/src/classes/PublicInvite.ts +++ b/src/classes/PublicInvite.ts @@ -1,5 +1,3 @@ -import { batch } from "solid-js"; - import { ServerFlags } from "../hydration/server.js"; import { API, Client, File } from "../index.js"; @@ -100,17 +98,15 @@ export class ServerPublicInvite extends PublicChannelInvite { const invite = await this.client!.api.post(`/invites/${this.code as ""}`); if (invite.type === "Server") { - return batch(() => { - for (const channel of invite.channels) { - this.client!.channels.getOrCreate(channel._id, channel); - } - - return this.client!.servers.getOrCreate( - invite.server._id, - invite.server, - true - ); - }); + for (const channel of invite.channels) { + this.client!.channels.getOrCreate(channel._id, channel); + } + + return this.client!.servers.getOrCreate( + invite.server._id, + invite.server, + true + ); } else { throw "unreachable"; } diff --git a/src/classes/Server.ts b/src/classes/Server.ts index 38f58a81..a17f6568 100644 --- a/src/classes/Server.ts +++ b/src/classes/Server.ts @@ -1,5 +1,3 @@ -import { batch } from "solid-js"; - import type { AllMemberResponse, BannedUser, @@ -375,7 +373,7 @@ export class Server { * @param data Changes */ async edit(data: DataEditServer) { - this.#collection.updateUnderlyingObject( + this.#collection.setUnderlyingObject( this.id, hydrate( "server", @@ -394,26 +392,22 @@ export class Server { * @param leaveEvent Whether we are leaving */ $delete(leaveEvent?: boolean) { - batch(() => { - const server = this.#collection.client.servers.getUnderlyingObject( - this.id - ); - - // Avoid race conditions - if (server.id) { - this.#collection.client.emit( - leaveEvent ? "serverLeave" : "serverDelete", - server - ); + const server = this.#collection.client.servers.getUnderlyingObject(this.id); - for (const channel of this.channelIds) { - this.#collection.client.channels.delete(channel); - } + // Avoid race conditions + if (server.id) { + this.#collection.client.emit( + leaveEvent ? "serverLeave" : "serverDelete", + server + ); - this.#collection.delete(this.id); + for (const channel of this.channelIds) { + this.#collection.client.channels.delete(channel); } - // TODO: delete members, emoji, etc - }); + + this.#collection.delete(this.id); + } + // TODO: delete members, emoji, etc } /** @@ -432,11 +426,9 @@ export class Server { * Mark a server as read */ async ack() { - batch(() => { - for (const channel of this.channels) { - channel.ack(undefined, false, true); - } - }); + for (const channel of this.channels) { + channel.ack(undefined, false, true); + } await this.#collection.client.api.put(`/servers/${this.id}/ack`); } @@ -603,31 +595,29 @@ export class Server { { exclude_offline: excludeOffline } ); - batch(() => { - if (excludeOffline) { - for (let i = 0; i < data.users.length; i++) { - const user = data.users[i]; - if (user.online) { - this.#collection.client.users.getOrCreate(user._id, user); - this.#collection.client.serverMembers.getOrCreate( - data.members[i]._id, - data.members[i] - ); - } - } - } else { - for (let i = 0; i < data.users.length; i++) { - this.#collection.client.users.getOrCreate( - data.users[i]._id, - data.users[i] - ); + if (excludeOffline) { + for (let i = 0; i < data.users.length; i++) { + const user = data.users[i]; + if (user.online) { + this.#collection.client.users.getOrCreate(user._id, user); this.#collection.client.serverMembers.getOrCreate( data.members[i]._id, data.members[i] ); } } - }); + } else { + for (let i = 0; i < data.users.length; i++) { + this.#collection.client.users.getOrCreate( + data.users[i]._id, + data.users[i] + ); + this.#collection.client.serverMembers.getOrCreate( + data.members[i]._id, + data.members[i] + ); + } + } } /** @@ -647,14 +637,14 @@ export class Server { `/servers/${this.id as ""}/members` )) as AllMemberResponse; - return batch(() => ({ + return { members: data.members.map((member) => this.#collection.client.serverMembers.getOrCreate(member._id, member) ), users: data.users.map((user) => this.#collection.client.users.getOrCreate(user._id, user) ), - })); + }; } /** @@ -671,14 +661,14 @@ export class Server { )}` as never )) as AllMemberResponse; - return batch(() => ({ + return { members: data.members.map((member) => this.#collection.client.serverMembers.getOrCreate(member._id, member) ), users: data.users.map((user) => this.#collection.client.users.getOrCreate(user._id, user) ), - })); + }; } /** @@ -713,10 +703,8 @@ export class Server { `/servers/${this.id as ""}/emojis` ); - return batch(() => - emojis.map((emoji) => - this.#collection.client.emojis.getOrCreate(emoji._id, emoji) - ) + return emojis.map((emoji) => + this.#collection.client.emojis.getOrCreate(emoji._id, emoji) ); } diff --git a/src/classes/Session.ts b/src/classes/Session.ts index d0952ba1..6640fbe1 100644 --- a/src/classes/Session.ts +++ b/src/classes/Session.ts @@ -64,7 +64,7 @@ export class Session { friendly_name: name, }); - this.#collection.updateUnderlyingObject(this.id, "name", name); + this.#collection.setUnderlyingKey(this.id, "name", name); } /** diff --git a/src/classes/User.ts b/src/classes/User.ts index b664c910..6b17d3ca 100644 --- a/src/classes/User.ts +++ b/src/classes/User.ts @@ -249,7 +249,7 @@ export class User { if (dm) { if (!dm.active) { - this.#collection.client.channels.updateUnderlyingObject( + this.#collection.client.channels.setUnderlyingKey( dm.id, "active", true diff --git a/src/collections/BotCollection.ts b/src/collections/BotCollection.ts index 03296b18..b4eb4f2e 100644 --- a/src/collections/BotCollection.ts +++ b/src/collections/BotCollection.ts @@ -1,16 +1,14 @@ -import { batch } from "solid-js"; - import { OwnedBotsResponse } from "revolt-api"; import { HydratedBot } from "../hydration/bot.js"; import { API, Bot, PublicBot } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Bots */ -export class BotCollection extends ClassCollection { +export class BotCollection extends Collection { /** * Fetch bot by ID * @param id Id @@ -30,12 +28,8 @@ export class BotCollection extends ClassCollection { */ async fetchOwned(): Promise { const data = (await this.client.api.get("/bots/@me")) as OwnedBotsResponse; - return batch(() => { - data.users.forEach((user) => - this.client.users.getOrCreate(user._id, user) - ); - return data.bots.map((bot) => this.getOrCreate(bot._id, bot)); - }); + data.users.forEach((user) => this.client.users.getOrCreate(user._id, user)); + return data.bots.map((bot) => this.getOrCreate(bot._id, bot)); } /** diff --git a/src/collections/ChannelCollection.ts b/src/collections/ChannelCollection.ts index 9d4c6d57..ad0dc9dd 100644 --- a/src/collections/ChannelCollection.ts +++ b/src/collections/ChannelCollection.ts @@ -1,15 +1,12 @@ import { HydratedChannel } from "../hydration/index.js"; import { API, Channel, User } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Channels */ -export class ChannelCollection extends ClassCollection< - Channel, - HydratedChannel -> { +export class ChannelCollection extends Collection { /** * Delete an object * @param id Id diff --git a/src/collections/ChannelUnreadCollection.ts b/src/collections/ChannelUnreadCollection.ts index 7615b65d..5a9b4664 100644 --- a/src/collections/ChannelUnreadCollection.ts +++ b/src/collections/ChannelUnreadCollection.ts @@ -1,15 +1,13 @@ -import { batch } from "solid-js"; - import { ChannelUnread } from "../classes/ChannelUnread.js"; import { HydratedChannelUnread } from "../hydration/index.js"; import { API } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Channel Unreads */ -export class ChannelUnreadCollection extends ClassCollection< +export class ChannelUnreadCollection extends Collection< ChannelUnread, HydratedChannelUnread > { @@ -18,19 +16,19 @@ export class ChannelUnreadCollection extends ClassCollection< */ async sync() { const unreads = await this.client.api.get("/sync/unreads"); - batch(() => { - this.reset(); - for (const unread of unreads) { - this.getOrCreate(unread._id.channel, unread); - } - }); + this.reset(); + for (const unread of unreads) { + this.getOrCreate(unread._id.channel, unread); + } } /** * Clear all unread data */ reset() { - this.updateUnderlyingObject({}); + for (const key of this.keys()) { + this.setUnderlyingObject(key, {} as never); + } } /** diff --git a/src/collections/ChannelWebhookCollection.ts b/src/collections/ChannelWebhookCollection.ts index 2c49ee7f..112bd75b 100644 --- a/src/collections/ChannelWebhookCollection.ts +++ b/src/collections/ChannelWebhookCollection.ts @@ -2,12 +2,12 @@ import { ChannelWebhook } from "../classes/ChannelWebhook.js"; import { HydratedChannelWebhook } from "../hydration/channelWebhook.js"; import { API } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Channel Webhooks */ -export class ChannelWebhookCollection extends ClassCollection< +export class ChannelWebhookCollection extends Collection< ChannelWebhook, HydratedChannelWebhook > { diff --git a/src/collections/Collection.ts b/src/collections/Collection.ts index 83808f4e..2e60cd06 100644 --- a/src/collections/Collection.ts +++ b/src/collections/Collection.ts @@ -1,150 +1,66 @@ -import { SetStoreFunction } from "solid-js/store"; - -import { ReactiveMap } from "@solid-primitives/map"; - -import { Hydrators } from "../hydration/index.js"; -import { Client } from "../index.js"; -import { ObjectStorage } from "../storage/ObjectStorage.js"; +import { Client } from "../Client.js"; +import { Hydrators, hydrate } from "../hydration/index.js"; /** - * Abstract Collection type + * Collection backed by a store */ -export abstract class Collection { - /** - * Get an existing object - * @param id Id - * @returns Object - */ - abstract get(id: string): T | undefined; +export class Collection { + #storage = new Map(); + #objects = new Map(); /** - * Check whether an id exists in the Collection - * @param id Id - * @returns Whether it exists + * Construct store backed collection */ - abstract has(id: string): boolean; + constructor(public readonly client: Client) {} /** - * Delete an object + * Get an existing object * @param id Id */ - abstract delete(id: string): void; - - /** - * Number of stored objects - * @returns Size - */ - abstract size(): number; - - /** - * Iterable of keys in the map - * @returns Iterable - */ - abstract keys(): IterableIterator; - - /** - * Iterable of values in the map - * @returns Iterable - */ - abstract values(): IterableIterator; - - /** - * Iterable of key, value pairs in the map - * @returns Iterable - */ - abstract entries(): IterableIterator<[string, T]>; - - /** - * Execute a provided function over each key, value pair in the map - * @param cb Callback for each pair - */ - abstract forEach( - cb: (value: T, key: string, map: ReactiveMap) => void - ): void; - - /** - * List of values in the map - * @returns List - */ - toList() { - return [...this.values()]; + get(id: string): T | undefined { + return this.#objects.get(id); } /** - * Filter the collection by a given predicate - * @param predicate Predicate to satisfy + * Get an underlying object */ - filter(predicate: (value: T, key: string) => boolean): T[] { - const list: T[] = []; - for (const [key, value] of this.entries()) { - if (predicate(value, key)) { - list.push(value); - } - } - - return list; + getUnderlyingObject(id: string): V { + return this.#storage.get(id) ?? ({} as V); } /** - * Map the collection using a given callback - * @param cb Callback + * Set a key of an underlying object */ - map(cb: (value: T, key: string) => O): O[] { - const list: O[] = []; - for (const [key, value] of this.entries()) { - list.push(cb(value, key)); - } - - return list; + setUnderlyingKey(id: string, key: K, value: V[K]) { + this.#storage.set(id, { + [key]: value, + ...((this.#storage.get(id) ?? {}) as V), + }); } /** - * Find some value based on a predicate - * @param predicate Predicate to satisfy + * Set an underlying object */ - find(predicate: (value: T, key: string) => boolean): T | undefined { - for (const [key, value] of this.entries()) { - if (predicate(value, key)) { - return value; - } - } + setUnderlyingObject(id: string, value: V) { + this.#storage.set(id, value); } -} - -/** - * Collection backed by a Solid.js Store - */ -export abstract class StoreCollection extends Collection { - #storage = new ObjectStorage(); - #objects = new ReactiveMap(); - readonly getUnderlyingObject: (id: string) => V; - readonly updateUnderlyingObject: SetStoreFunction>; /** - * Construct store backed collection - */ - constructor() { - super(); - this.getUnderlyingObject = (key) => this.#storage.get(key) ?? ({} as V); - this.updateUnderlyingObject = this.#storage.set; - } - - /** - * Get an existing object + * Check whether an id exists in the Collection * @param id Id - * @returns Object + * @returns Whether it exists */ - get(id: string): T | undefined { - return this.#objects.get(id); + has(id: string): boolean { + return this.#objects.has(id); } /** - * Check whether an id exists in the Collection + * Check whether the underlying id exists * @param id Id * @returns Whether it exists */ - has(id: string) { - return this.#objects.has(id); + hasUnderlying(id: string): boolean { + return !!((this.#storage.get(id) as { id: string }) ?? { id: false }).id; } /** @@ -153,7 +69,7 @@ export abstract class StoreCollection extends Collection { */ delete(id: string): void { this.#objects.delete(id); - this.updateUnderlyingObject(id, undefined as never); + this.#storage.delete(id); } /** @@ -170,8 +86,13 @@ export abstract class StoreCollection extends Collection { instance: T, context: unknown, data?: unknown - ) { - this.#storage.hydrate(id, type, context, data); + ): void { + if (data) { + this.#storage.set( + id, + hydrate(type, { partial: false, ...data } as never, context, true) as V + ); + } this.#objects.set(id, instance); } @@ -181,14 +102,16 @@ export abstract class StoreCollection extends Collection { * @returns Whether it is a partial */ isPartial(id: string): boolean { - return !!(this.getUnderlyingObject(id) as { partial: boolean }).partial; + return !!( + (this.#storage.get(id) ?? { partial: true }) as { partial: boolean } + ).partial; } /** * Number of stored objects * @returns Size */ - size() { + size(): number { return this.#objects.size; } @@ -196,7 +119,7 @@ export abstract class StoreCollection extends Collection { * Iterable of keys in the map * @returns Iterable */ - keys() { + keys(): MapIterator { return this.#objects.keys(); } @@ -204,7 +127,7 @@ export abstract class StoreCollection extends Collection { * Iterable of values in the map * @returns Iterable */ - values() { + values(): MapIterator { return this.#objects.values(); } @@ -212,32 +135,64 @@ export abstract class StoreCollection extends Collection { * Iterable of key, value pairs in the map * @returns Iterable */ - entries() { + entries(): MapIterator<[string, T]> { return this.#objects.entries(); } /** * Execute a provided function over each key, value pair in the map * @param cb Callback for each pair - * @returns Iterable */ - forEach(cb: (value: T, key: string, map: ReactiveMap) => void) { + forEach(cb: (value: T, key: string, map: Map) => void): void { return this.#objects.forEach(cb); } -} -/** - * Generic class collection backed by store - */ -export class ClassCollection extends StoreCollection { - readonly client: Client; + /** + * List of values in the map + * @returns List + */ + toList(): T[] { + return [...this.values()]; + } + + /** + * Filter the collection by a given predicate + * @param predicate Predicate to satisfy + */ + filter(predicate: (value: T, key: string) => boolean): T[] { + const list: T[] = []; + for (const [key, value] of this.entries()) { + if (predicate(value, key)) { + list.push(value); + } + } + + return list; + } + + /** + * Map the collection using a given callback + * @param cb Callback + */ + map(cb: (value: T, key: string) => O): O[] { + const list: O[] = []; + for (const [key, value] of this.entries()) { + list.push(cb(value, key)); + } + + return list; + } /** - * Create generic class collection - * @param client Client + * Find some value based on a predicate + * @param predicate Predicate to satisfy */ - constructor(client: Client) { - super(); - this.client = client; + find(predicate: (value: T, key: string) => boolean): T | undefined { + for (const [key, value] of this.entries()) { + if (predicate(value, key)) { + return value; + } + } + return undefined; } } diff --git a/src/collections/EmojiCollection.ts b/src/collections/EmojiCollection.ts index 86f6efbb..b75329a5 100644 --- a/src/collections/EmojiCollection.ts +++ b/src/collections/EmojiCollection.ts @@ -1,12 +1,12 @@ import { HydratedEmoji } from "../hydration/index.js"; import { API, Emoji } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Emoji */ -export class EmojiCollection extends ClassCollection { +export class EmojiCollection extends Collection { /** * Fetch emoji by ID * @param id Id diff --git a/src/collections/MessageCollection.ts b/src/collections/MessageCollection.ts index 7bb9975c..ecab168e 100644 --- a/src/collections/MessageCollection.ts +++ b/src/collections/MessageCollection.ts @@ -1,15 +1,12 @@ import { HydratedMessage } from "../hydration"; import { API, Message } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Messages */ -export class MessageCollection extends ClassCollection< - Message, - HydratedMessage -> { +export class MessageCollection extends Collection { /** * Fetch message by Id * @param channelId Channel Id diff --git a/src/collections/ServerCollection.ts b/src/collections/ServerCollection.ts index 1496902c..52c2d9a8 100644 --- a/src/collections/ServerCollection.ts +++ b/src/collections/ServerCollection.ts @@ -1,16 +1,14 @@ -import { batch } from "solid-js"; - import { DataCreateServer } from "revolt-api"; import { HydratedServer } from "../hydration/index.js"; import { API, Server } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Servers */ -export class ServerCollection extends ClassCollection { +export class ServerCollection extends Collection { /** * Fetch server by ID * @@ -25,15 +23,13 @@ export class ServerCollection extends ClassCollection { include_channels: true, }); - return batch(() => { - for (const channel of data.channels as unknown as API.Channel[]) { - if (typeof channel !== "string") { - this.client.channels.getOrCreate(channel._id, channel); - } + for (const channel of data.channels as unknown as API.Channel[]) { + if (typeof channel !== "string") { + this.client.channels.getOrCreate(channel._id, channel); } + } - return this.getOrCreate(data._id, data); - }); + return this.getOrCreate(data._id, data); } /** @@ -81,12 +77,10 @@ export class ServerCollection extends ClassCollection { data ); - return batch(() => { - for (const channel of channels) { - this.client.channels.getOrCreate(channel._id, channel); - } + for (const channel of channels) { + this.client.channels.getOrCreate(channel._id, channel); + } - return this.getOrCreate(server._id, server, true); - }); + return this.getOrCreate(server._id, server, true); } } diff --git a/src/collections/ServerMemberCollection.ts b/src/collections/ServerMemberCollection.ts index 7461d15e..4db064c1 100644 --- a/src/collections/ServerMemberCollection.ts +++ b/src/collections/ServerMemberCollection.ts @@ -1,12 +1,12 @@ import { HydratedServerMember } from "../hydration/index.js"; import { API, ServerMember } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Server Members */ -export class ServerMemberCollection extends ClassCollection< +export class ServerMemberCollection extends Collection< ServerMember, HydratedServerMember > { diff --git a/src/collections/SessionCollection.ts b/src/collections/SessionCollection.ts index 60e04b91..71a4a327 100644 --- a/src/collections/SessionCollection.ts +++ b/src/collections/SessionCollection.ts @@ -1,27 +1,20 @@ -import { batch } from "solid-js"; - import { Session } from "../classes/index.js"; import { HydratedSession } from "../hydration/session.js"; import { API } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Sessions */ -export class SessionCollection extends ClassCollection< - Session, - HydratedSession -> { +export class SessionCollection extends Collection { /** * Fetch active sessions * @returns List of sessions */ async fetch(): Promise { const data = await this.client.api.get("/auth/session/all"); - return batch(() => - data.map((session) => this.getOrCreate(session._id, session)) - ); + return data.map((session) => this.getOrCreate(session._id, session)); } /** diff --git a/src/collections/UserCollection.ts b/src/collections/UserCollection.ts index a052eab2..1f0e10f6 100644 --- a/src/collections/UserCollection.ts +++ b/src/collections/UserCollection.ts @@ -1,12 +1,12 @@ import { HydratedUser } from "../hydration/index.js"; import { API, Client, User } from "../index.js"; -import { ClassCollection } from "./index.js"; +import { Collection } from "./index.js"; /** * Collection of Users */ -export class UserCollection extends ClassCollection { +export class UserCollection extends Collection { /** * Construct User collection */ diff --git a/src/events/EventClient.ts b/src/events/EventClient.ts index f3cbb887..5bb583c1 100644 --- a/src/events/EventClient.ts +++ b/src/events/EventClient.ts @@ -1,5 +1,3 @@ -import { Accessor, Setter, createSignal } from "solid-js"; - import EventEmitter from "eventemitter3"; import WebSocket from "isomorphic-ws"; import { Error } from "revolt-api"; @@ -65,11 +63,8 @@ export class EventClient extends EventEmitter< #protocolVersion: T; #transportFormat: "json" | "msgpack"; - readonly ping: Accessor; - #setPing: Setter; - - readonly state: Accessor; - #setStateSetter: Setter; + ping = -1; + state = ConnectionState.Idle; #socket: WebSocket | undefined; #heartbeatIntervalReference: number | undefined; @@ -103,14 +98,6 @@ export class EventClient extends EventEmitter< ...options, }; - const [state, setState] = createSignal(ConnectionState.Idle); - this.state = state; - this.#setStateSetter = setState; - - const [ping, setPing] = createSignal(-1); - this.ping = ping; - this.#setPing = setPing; - this.disconnect = this.disconnect.bind(this); } @@ -119,7 +106,7 @@ export class EventClient extends EventEmitter< * @param state state */ private setState(state: ConnectionState) { - this.#setStateSetter(state); + this.state = state; this.emit("state", state); } @@ -217,8 +204,8 @@ export class EventClient extends EventEmitter< return; case "Pong": clearTimeout(this.#pongTimeoutReference); - this.#setPing(+new Date() - event.data); - this.options.debug && console.debug(`[ping] ${this.ping()}ms`); + this.ping = +new Date() - event.data; + this.options.debug && console.debug(`[ping] ${this.ping}ms`); return; case "Error": this.#lastError = { @@ -230,7 +217,7 @@ export class EventClient extends EventEmitter< return; } - switch (this.state()) { + switch (this.state) { case ConnectionState.Connecting: if (event.type === "Authenticated") { // no-op @@ -249,9 +236,7 @@ export class EventClient extends EventEmitter< } break; default: - throw `Unreachable code. Received ${ - event.type - } in state ${this.state()}.`; + throw `Unreachable code. Received ${event.type} in state ${this.state}.`; } } diff --git a/src/events/v1.ts b/src/events/v1.ts index c0eb3e46..17a5925b 100644 --- a/src/events/v1.ts +++ b/src/events/v1.ts @@ -1,6 +1,3 @@ -import { Setter, batch } from "solid-js"; - -import { ReactiveSet } from "@solid-primitives/set"; import type { Channel, Emoji, @@ -188,7 +185,7 @@ type ReadyData = { export async function handleEvent( client: Client, event: ServerMessage, - setReady: Setter + setReady: (value: boolean) => void ) { if (client.options.debug) { console.debug("[S->C]", event); @@ -202,31 +199,29 @@ export async function handleEvent( break; } case "Ready": { - batch(() => { - for (const user of event.users) { - const u = client.users.getOrCreate(user._id, user); + for (const user of event.users) { + const u = client.users.getOrCreate(user._id, user); - if (u.relationship === "User") { - client.user = u; - } + if (u.relationship === "User") { + client.user = u; } + } - for (const server of event.servers) { - client.servers.getOrCreate(server._id, server); - } + for (const server of event.servers) { + client.servers.getOrCreate(server._id, server); + } - for (const member of event.members) { - client.serverMembers.getOrCreate(member._id, member); - } + for (const member of event.members) { + client.serverMembers.getOrCreate(member._id, member); + } - for (const channel of event.channels) { - client.channels.getOrCreate(channel._id, channel); - } + for (const channel of event.channels) { + client.channels.getOrCreate(channel._id, channel); + } - for (const emoji of event.emojis) { - client.emojis.getOrCreate(emoji._id, emoji); - } - }); + for (const emoji of event.emojis) { + client.emojis.getOrCreate(emoji._id, emoji); + } if (client.options.syncUnreads) { await client.channelUnreads.sync(); @@ -239,25 +234,23 @@ export async function handleEvent( } case "Message": { if (!client.messages.has(event._id)) { - batch(() => { - if (event.member) { - client.serverMembers.getOrCreate(event.member._id, event.member); - } + if (event.member) { + client.serverMembers.getOrCreate(event.member._id, event.member); + } - if (event.user) { - client.users.getOrCreate(event.user._id, event.user); - } + if (event.user) { + client.users.getOrCreate(event.user._id, event.user); + } - delete event.member; - delete event.user; + delete event.member; + delete event.user; - client.messages.getOrCreate(event._id, event, true); - client.channels.updateUnderlyingObject( - event.channel, - "lastMessageId", - event._id - ); - }); + client.messages.getOrCreate(event._id, event, true); + client.channels.setUnderlyingKey( + event.channel, + "lastMessageId", + event._id + ); } break; } @@ -269,7 +262,7 @@ export async function handleEvent( channelId: event.channel, }; - client.messages.updateUnderlyingObject(event.id, { + client.messages.setUnderlyingObject(event.id, { ...hydrate( "message", { ...event.data, channel: event.channel }, @@ -291,18 +284,14 @@ export async function handleEvent( channelId: event.channel, }; - client.messages.updateUnderlyingObject(event.id, "embeds", (embeds) => [ - ...(embeds ?? []), + client.messages.setUnderlyingKey(event.id, "embeds", [ + ...(previousMessage.embeds ?? []), ...(event.append.embeds?.map((embed) => MessageEmbed.from(client, embed) ) ?? []), ]); - client.messages.updateUnderlyingObject( - event.id, - "channelId", - event.channel - ); + client.messages.setUnderlyingKey(event.id, "channelId", event.channel); client.emit("messageUpdate", message, previousMessage); } @@ -317,22 +306,20 @@ export async function handleEvent( break; } case "BulkMessageDelete": { - batch(() => - client.emit( - "messageDeleteBulk", - event.ids - .map((id) => { - if (client.messages.has(id)) { - const message = client.messages.getUnderlyingObject(id); - client.messages.delete(id); - return message!; - } - - return undefined!; - }) - .filter((x) => x), - client.channels.get(event.channel) - ) + client.emit( + "messageDeleteBulk", + event.ids + .map((id) => { + if (client.messages.has(id)) { + const message = client.messages.getUnderlyingObject(id); + client.messages.delete(id); + return message!; + } + + return undefined!; + }) + .filter((x) => x), + client.channels.get(event.channel) ); break; } @@ -345,7 +332,7 @@ export async function handleEvent( if (set.has(event.user_id)) return; set.add(event.user_id); } else { - reactions.set(event.emoji_id, new ReactiveSet([event.user_id])); + reactions.set(event.emoji_id, new Set([event.user_id])); } client.emit( @@ -421,7 +408,7 @@ export async function handleEvent( } } - client.channels.updateUnderlyingObject(event.id, changes); + client.channels.setUnderlyingObject(event.id, changes); client.emit("channelUpdate", channel, previousChannel); } break; @@ -511,13 +498,11 @@ export async function handleEvent( } case "ServerCreate": { if (!client.servers.has(event.server._id)) { - batch(() => { - for (const channel of event.channels) { - client.channels.getOrCreate(channel._id, channel); - } + for (const channel of event.channels) { + client.channels.getOrCreate(channel._id, channel); + } - client.servers.getOrCreate(event.server._id, event.server, true); - }); + client.servers.getOrCreate(event.server._id, event.server, true); } break; } @@ -552,7 +537,7 @@ export async function handleEvent( } } - client.servers.updateUnderlyingObject(event.id, changes); + client.servers.setUnderlyingObject(event.id, changes); client.emit("serverUpdate", server, previousServer); } break; @@ -647,7 +632,7 @@ export async function handleEvent( } } - client.serverMembers.updateUnderlyingObject( + client.serverMembers.setUnderlyingObject( event.id.server + event.id.user, changes as never ); @@ -718,7 +703,7 @@ export async function handleEvent( } } - client.users.updateUnderlyingObject(event.id, changes as never); + client.users.setUnderlyingObject(event.id, changes as never); client.emit("userUpdate", user, previousUser); } break; @@ -756,37 +741,35 @@ export async function handleEvent( break; } case "UserPlatformWipe": { - batch(() => { - handleEvent( - client, - { - type: "BulkMessageDelete", - channel: "0", - ids: client.messages - .toList() - .filter((message) => message.authorId === event.user_id) - .map((message) => message.id), - }, - setReady - ); + handleEvent( + client, + { + type: "BulkMessageDelete", + channel: "0", + ids: client.messages + .toList() + .filter((message) => message.authorId === event.user_id) + .map((message) => message.id), + }, + setReady + ); - handleEvent( - client, - { - type: "UserUpdate", - id: event.user_id, - data: { - username: `Deleted User`, - online: false, - flags: event.flags, - badges: 0, - relationship: "None", - }, - clear: ["Avatar", "StatusPresence", "StatusText"], + handleEvent( + client, + { + type: "UserUpdate", + id: event.user_id, + data: { + username: `Deleted User`, + online: false, + flags: event.flags, + badges: 0, + relationship: "None", }, - setReady - ); - }); + clear: ["Avatar", "StatusPresence", "StatusText"], + }, + setReady + ); break; } diff --git a/src/hydration/channel.ts b/src/hydration/channel.ts index aef59c30..9528e324 100644 --- a/src/hydration/channel.ts +++ b/src/hydration/channel.ts @@ -1,4 +1,3 @@ -import { ReactiveSet } from "@solid-primitives/set"; import { Channel as ApiChannel, OverrideField } from "revolt-api"; import { Client, File } from "../index.js"; @@ -15,8 +14,8 @@ export type HydratedChannel = { icon?: File; active: boolean; - typingIds: ReactiveSet; - recipientIds: ReactiveSet; + typingIds: Set; + recipientIds: Set; userId?: string; ownerId?: string; @@ -49,8 +48,8 @@ export const channelHydration: Hydrate, HydratedChannel> = { description: (channel) => channel.description!, icon: (channel, ctx) => new File(ctx as Client, channel.icon!), active: (channel) => channel.active || false, - typingIds: () => new ReactiveSet(), - recipientIds: (channel) => new ReactiveSet(channel.recipients), + typingIds: () => new Set(), + recipientIds: (channel) => new Set(channel.recipients), userId: (channel) => channel.user, ownerId: (channel) => channel.owner, serverId: (channel) => channel.server, @@ -61,7 +60,7 @@ export const channelHydration: Hydrate, HydratedChannel> = { lastMessageId: (channel) => channel.last_message_id!, }, initialHydration: () => ({ - typingIds: new ReactiveSet(), - recipientIds: new ReactiveSet(), + typingIds: new Set(), + recipientIds: new Set(), }), }; diff --git a/src/hydration/channelUnread.ts b/src/hydration/channelUnread.ts index f293327e..1705d9eb 100644 --- a/src/hydration/channelUnread.ts +++ b/src/hydration/channelUnread.ts @@ -1,5 +1,3 @@ -import { ReactiveSet } from "@solid-primitives/set"; - import { API } from "../index.js"; import type { Merge } from "../lib/merge.js"; @@ -8,7 +6,7 @@ import { Hydrate } from "./index.js"; export type HydratedChannelUnread = { id: string; lastMessageId?: string; - messageMentionIds: ReactiveSet; + messageMentionIds: Set; }; export const channelUnreadHydration: Hydrate< @@ -23,9 +21,9 @@ export const channelUnreadHydration: Hydrate< functions: { id: (unread) => unread._id.channel, lastMessageId: (unread) => unread.last_id!, - messageMentionIds: (unread) => new ReactiveSet(unread.mentions!), + messageMentionIds: (unread) => new Set(unread.mentions!), }, initialHydration: () => ({ - messageMentionIds: new ReactiveSet(), + messageMentionIds: new Set(), }), }; diff --git a/src/hydration/message.ts b/src/hydration/message.ts index a75ed487..cb1e8c02 100644 --- a/src/hydration/message.ts +++ b/src/hydration/message.ts @@ -1,6 +1,3 @@ -import { ReactiveMap } from "@solid-primitives/map"; -import { ReactiveSet } from "@solid-primitives/set"; - import { API, Client, @@ -26,7 +23,7 @@ export type HydratedMessage = { embeds?: MessageEmbed[]; mentionIds?: string[]; replyIds?: string[]; - reactions: ReactiveMap>; + reactions: Map>; interactions?: API.Interactions; masquerade?: API.Masquerade; flags?: number; @@ -62,10 +59,10 @@ export const messageHydration: Hydrate, HydratedMessage> = { mentionIds: (message) => message.mentions!, replyIds: (message) => message.replies!, reactions: (message) => { - const map = new ReactiveMap>(); + const map = new Map>(); if (message.reactions) { for (const reaction of Object.keys(message.reactions)) { - map.set(reaction, new ReactiveSet(message.reactions![reaction])); + map.set(reaction, new Set(message.reactions![reaction])); } } return map; @@ -75,6 +72,6 @@ export const messageHydration: Hydrate, HydratedMessage> = { flags: (message) => message.flags!, }, initialHydration: () => ({ - reactions: new ReactiveMap(), + reactions: new Map(), }), }; diff --git a/src/hydration/server.ts b/src/hydration/server.ts index f47e0be9..cdb6f811 100644 --- a/src/hydration/server.ts +++ b/src/hydration/server.ts @@ -1,5 +1,3 @@ -import { ReactiveMap } from "@solid-primitives/map"; -import { ReactiveSet } from "@solid-primitives/set"; import { Server as ApiServer, Category, @@ -21,11 +19,11 @@ export type HydratedServer = { icon?: File; banner?: File; - channelIds: ReactiveSet; + channelIds: Set; categories?: Category[]; systemMessages?: SystemMessageChannels; - roles: ReactiveMap; + roles: Map; defaultPermissions: number; flags: ServerFlags; @@ -47,13 +45,11 @@ export const serverHydration: Hydrate = { ownerId: (server) => server.owner, name: (server) => server.name, description: (server) => server.description!, - channelIds: (server) => new ReactiveSet(server.channels), + channelIds: (server) => new Set(server.channels), categories: (server) => server.categories ?? [], systemMessages: (server) => server.system_messages ?? {}, roles: (server) => - new ReactiveMap( - Object.keys(server.roles!).map((id) => [id, server.roles![id]]) - ), + new Map(Object.keys(server.roles!).map((id) => [id, server.roles![id]])), defaultPermissions: (server) => server.default_permissions, icon: (server, ctx) => new File(ctx as Client, server.icon!), banner: (server, ctx) => new File(ctx as Client, server.banner!), @@ -63,8 +59,8 @@ export const serverHydration: Hydrate = { nsfw: (server) => server.nsfw || false, }, initialHydration: () => ({ - channelIds: new ReactiveSet(), - roles: new ReactiveMap(), + channelIds: new Set(), + roles: new Map(), }), }; diff --git a/src/storage/ObjectStorage.ts b/src/storage/ObjectStorage.ts deleted file mode 100644 index 458b50c3..00000000 --- a/src/storage/ObjectStorage.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { SetStoreFunction, createStore } from "solid-js/store"; - -import { Hydrators, hydrate } from "../hydration/index.js"; - -/** - * Wrapper around Solid.js store - */ -export class ObjectStorage { - private store: Record; - readonly set: SetStoreFunction>; - - /** - * Create new object storage - */ - constructor() { - const [store, setStore] = createStore({}); - this.store = store as never; - this.set = setStore; - this.get = this.get.bind(this); - } - - /** - * Get object by ID - * @param id ID - * @returns Object - */ - get(id: string) { - return this.store[id]; - } - - /** - * Hydrate some data into storage - * @param id ID - * @param type Hydration type - * @param context Context - * @param data Input Data - */ - hydrate(id: string, type: keyof Hydrators, context: unknown, data?: unknown) { - if (data) { - data = { partial: false, ...data }; - this.set(id, hydrate(type, data as never, context, true) as T); - } - } -} From 78e736795e2fb5441db5a7fdaf5c7acb793c8326 Mon Sep 17 00:00:00 2001 From: William Horning Date: Fri, 14 Mar 2025 16:44:14 -0400 Subject: [PATCH 8/9] remove solid.js from package.json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 8b692830..92688fa7 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "isomorphic-ws": "^5.0.0", "long": "^5.2.3", "revolt-api": "0.8.3", - "solid-js": "^1.8.15", "ulid": "^2.3.0", "ws": "^8.16.0" }, From 6738be5d9a95fa5532ce7cf40224c5de4c005ca8 Mon Sep 17 00:00:00 2001 From: Jersey Date: Sun, 23 Mar 2025 16:03:31 -0400 Subject: [PATCH 9/9] fix lockfile --- pnpm-lock.yaml | 137 ------------------------------------------------- 1 file changed, 137 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b56ebcad..6ad0f638 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,21 +8,12 @@ importers: .: dependencies: - '@solid-primitives/map': - specifier: ^0.6.0 - version: 0.6.0(solid-js@1.9.5) - '@solid-primitives/set': - specifier: ^0.6.0 - version: 0.6.0(solid-js@1.9.5) '@vladfrangu/async_event_emitter': specifier: ^2.4.6 version: 2.4.6 revolt-api: specifier: 0.8.3 version: 0.8.3 - solid-js: - specifier: ^1.9.5 - version: 1.9.5 ulid: specifier: ^2.3.0 version: 2.3.0 @@ -42,9 +33,6 @@ importers: eslint-plugin-prettier: specifier: ^5.2.3 version: 5.2.3(eslint-config-prettier@8.10.0(eslint@9.22.0))(eslint@9.22.0)(prettier@3.5.3) - eslint-plugin-solid: - specifier: ^0.14.5 - version: 0.14.5(eslint@9.22.0)(typescript@5.8.2) prettier: specifier: ^3.5.3 version: 3.5.3 @@ -203,26 +191,6 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - '@solid-primitives/map@0.6.0': - resolution: {integrity: sha512-h8uCJNxUTvzNK/aTW9vJCd/PQeBkUL8i7AyLPvTFqMgcMnJ1I5GzAi5JODzxpxQwffxoqJyQtOE1vBqFzDv0Vw==} - peerDependencies: - solid-js: ^1.6.12 - - '@solid-primitives/set@0.6.0': - resolution: {integrity: sha512-P1Tp001m8ib5XCi/LEJHh2QsoS2uPO86HewtbrSxr2axt5te9EGc0UOwNKTPxNvNSLNHteUw5IrzDsEklW4m3g==} - peerDependencies: - solid-js: ^1.6.12 - - '@solid-primitives/trigger@1.2.0': - resolution: {integrity: sha512-sW4/3cDXSjYQampn8CIFZ11BlxgNf2li8r2fXnb3b3YWE6RdZZCl8PhvpPF38Gzl0CnryrbTPJWM7OIkseCDgQ==} - peerDependencies: - solid-js: ^1.6.12 - - '@solid-primitives/utils@6.3.0': - resolution: {integrity: sha512-e7hTlJ1Ywh2+g/Qug+n4L1mpfxsikoIS4/sHE2EK9WatQt8UJqop/vE6bsLnXlU1xuhb/jo94Ah5Y27rd4wP7A==} - peerDependencies: - solid-js: ^1.6.12 - '@trivago/prettier-plugin-sort-imports@5.2.2': resolution: {integrity: sha512-fYDQA9e6yTNmA13TLVSA+WMQRc5Bn/c0EUBditUHNfMMxN7M82c38b1kEggVE3pLpZ0FwkwJkUEKMiOi52JXFA==} engines: {node: '>18.12'} @@ -363,9 +331,6 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -406,13 +371,6 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-solid@0.14.5: - resolution: {integrity: sha512-nfuYK09ah5aJG/oEN6P1qziy1zLgW4PDWe75VNPi4CEFYk1x2AEqwFeQfEPR7gNn0F2jOeqKhx2E+5oNCOBYWQ==} - engines: {node: '>=18.0.0'} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - typescript: '>=4.8.4' - eslint-scope@8.3.0: resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -525,10 +483,6 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} - engines: {node: '>=8'} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -541,9 +495,6 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - inline-style-parser@0.2.4: - resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -552,10 +503,6 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-html@2.0.0: - resolution: {integrity: sha512-S+OpgB5i7wzIue/YSE5hg0e5ZYfG3hhpNh9KGl6ayJ38p7ED6wxQLd1TV91xHpcTvw90KMJ9EwN3F/iNflHBVg==} - engines: {node: '>=8'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -587,15 +534,9 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - kebab-case@1.0.2: - resolution: {integrity: sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q==} - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - known-css-properties@0.30.0: - resolution: {integrity: sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==} - levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -721,16 +662,6 @@ packages: engines: {node: '>=10'} hasBin: true - seroval-plugins@1.2.1: - resolution: {integrity: sha512-H5vs53+39+x4Udwp4J5rNZfgFuA+Lt+uU+09w1gYBVWomtAl98B+E9w7yC05Xc81/HgLvJdlyqJbU0fJCKCmdw==} - engines: {node: '>=10'} - peerDependencies: - seroval: ^1.0 - - seroval@1.2.1: - resolution: {integrity: sha512-yBxFFs3zmkvKNmR0pFSU//rIsYjuX418TnlDmc2weaq5XFDqDIV/NOMPBoLrbxjLH42p4UzRuXHryXh9dYcKcw==} - engines: {node: '>=10'} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -739,16 +670,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - solid-js@1.9.5: - resolution: {integrity: sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==} - strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - style-to-object@1.0.8: - resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -981,25 +906,6 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} - '@solid-primitives/map@0.6.0(solid-js@1.9.5)': - dependencies: - '@solid-primitives/trigger': 1.2.0(solid-js@1.9.5) - solid-js: 1.9.5 - - '@solid-primitives/set@0.6.0(solid-js@1.9.5)': - dependencies: - '@solid-primitives/trigger': 1.2.0(solid-js@1.9.5) - solid-js: 1.9.5 - - '@solid-primitives/trigger@1.2.0(solid-js@1.9.5)': - dependencies: - '@solid-primitives/utils': 6.3.0(solid-js@1.9.5) - solid-js: 1.9.5 - - '@solid-primitives/utils@6.3.0(solid-js@1.9.5)': - dependencies: - solid-js: 1.9.5 - '@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.5.3)': dependencies: '@babel/generator': 7.26.10 @@ -1166,8 +1072,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - csstype@3.1.3: {} - debug@4.4.0: dependencies: ms: 2.1.3 @@ -1192,19 +1096,6 @@ snapshots: optionalDependencies: eslint-config-prettier: 8.10.0(eslint@9.22.0) - eslint-plugin-solid@0.14.5(eslint@9.22.0)(typescript@5.8.2): - dependencies: - '@typescript-eslint/utils': 8.26.1(eslint@9.22.0)(typescript@5.8.2) - eslint: 9.22.0 - estraverse: 5.3.0 - is-html: 2.0.0 - kebab-case: 1.0.2 - known-css-properties: 0.30.0 - style-to-object: 1.0.8 - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - eslint-scope@8.3.0: dependencies: esrecurse: 4.3.0 @@ -1330,8 +1221,6 @@ snapshots: has-flag@4.0.0: {} - html-tags@3.3.1: {} - ignore@5.3.2: {} import-fresh@3.3.1: @@ -1341,18 +1230,12 @@ snapshots: imurmurhash@0.1.4: {} - inline-style-parser@0.2.4: {} - is-extglob@2.1.1: {} is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - is-html@2.0.0: - dependencies: - html-tags: 3.3.1 - is-number@7.0.0: {} isexe@2.0.0: {} @@ -1373,14 +1256,10 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - kebab-case@1.0.2: {} - keyv@4.5.4: dependencies: json-buffer: 3.0.1 - known-css-properties@0.30.0: {} - levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -1492,30 +1371,14 @@ snapshots: semver@7.7.1: {} - seroval-plugins@1.2.1(seroval@1.2.1): - dependencies: - seroval: 1.2.1 - - seroval@1.2.1: {} - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} - solid-js@1.9.5: - dependencies: - csstype: 3.1.3 - seroval: 1.2.1 - seroval-plugins: 1.2.1(seroval@1.2.1) - strip-json-comments@3.1.1: {} - style-to-object@1.0.8: - dependencies: - inline-style-parser: 0.2.4 - supports-color@7.2.0: dependencies: has-flag: 4.0.0