mirror of
https://github.com/JonnyBro/JaBa.git
synced 2025-01-19 17:03:47 +05:00
feat: added TS support
This commit is contained in:
parent
78fca15044
commit
eb78c29c90
48 changed files with 1124 additions and 673 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -13,3 +13,6 @@ Thumbs.db
|
|||
|
||||
# Node
|
||||
node_modules
|
||||
dist
|
||||
|
||||
tsconfig.tsbuildinfo
|
|
@ -6,6 +6,5 @@
|
|||
"semi": true,
|
||||
"tabWidth": 4,
|
||||
"trailingComma": "all",
|
||||
"useTabs": true,
|
||||
"parser": "babel"
|
||||
}
|
||||
"useTabs": true
|
||||
}
|
|
@ -1,21 +1,34 @@
|
|||
import globals from "globals";
|
||||
import pluginJs from "@eslint/js";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
import stylisticJs from "@stylistic/eslint-plugin-js";
|
||||
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
||||
|
||||
/** @type {import("eslint").Linter.Config[]} */
|
||||
export default [
|
||||
pluginJs.configs.recommended,
|
||||
{
|
||||
files: ["**/*.ts"],
|
||||
ignores: ["**/*.d.ts", "dist"],
|
||||
languageOptions: {
|
||||
globals: globals.node,
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
parser: tsParser,
|
||||
},
|
||||
ignores: ["node_modules", "dashboard"],
|
||||
plugins: {
|
||||
"@typescript-eslint": tsPlugin,
|
||||
"@stylistic/js": stylisticJs,
|
||||
},
|
||||
rules: {
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_", // Игнорировать переменные, начинающиеся с _
|
||||
varsIgnorePattern: "^_", // Игнорировать переменные, начинающиеся с _
|
||||
ignoreRestSiblings: true, // Игнорировать неиспользуемые параметры в деструктуризации
|
||||
},
|
||||
],
|
||||
"arrow-body-style": ["error", "as-needed"],
|
||||
camelcase: "error",
|
||||
curly: ["error", "multi-line"],
|
||||
|
|
13
package.json
13
package.json
|
@ -5,7 +5,9 @@
|
|||
"main": "src/index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node src/index.js"
|
||||
"start": "node dist/index.js",
|
||||
"dev": "tsx watch src/index.ts",
|
||||
"build": "tsc"
|
||||
},
|
||||
"author": "https://github.com/JonnyBro",
|
||||
"dependencies": {
|
||||
|
@ -31,9 +33,16 @@
|
|||
"devDependencies": {
|
||||
"@eslint/js": "^9.16.0",
|
||||
"@stylistic/eslint-plugin-js": "^2.11.0",
|
||||
"@types/md5": "^2.3.5",
|
||||
"@types/ms": "^0.7.34",
|
||||
"@types/node": "^22.10.5",
|
||||
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
||||
"@typescript-eslint/parser": "^8.19.1",
|
||||
"eslint": "^9.16.0",
|
||||
"globals": "^15.13.0",
|
||||
"prettier": "^3.4.2",
|
||||
"prettier-eslint": "^16.3.0"
|
||||
"prettier-eslint": "^16.3.0",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
}
|
||||
|
|
510
pnpm-lock.yaml
510
pnpm-lock.yaml
|
@ -46,7 +46,7 @@ importers:
|
|||
version: 5.1.4
|
||||
i18next:
|
||||
specifier: ^24.0.0
|
||||
version: 24.0.0(typescript@5.7.2)
|
||||
version: 24.0.0(typescript@5.7.3)
|
||||
i18next-fs-backend:
|
||||
specifier: ^2.6.0
|
||||
version: 2.6.0
|
||||
|
@ -69,6 +69,21 @@ importers:
|
|||
'@stylistic/eslint-plugin-js':
|
||||
specifier: ^2.11.0
|
||||
version: 2.11.0(eslint@9.16.0)
|
||||
'@types/md5':
|
||||
specifier: ^2.3.5
|
||||
version: 2.3.5
|
||||
'@types/ms':
|
||||
specifier: ^0.7.34
|
||||
version: 0.7.34
|
||||
'@types/node':
|
||||
specifier: ^22.10.5
|
||||
version: 22.10.5
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.19.1
|
||||
version: 8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.16.0)(typescript@5.7.3))(eslint@9.16.0)(typescript@5.7.3)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^8.19.1
|
||||
version: 8.19.1(eslint@9.16.0)(typescript@5.7.3)
|
||||
eslint:
|
||||
specifier: ^9.16.0
|
||||
version: 9.16.0
|
||||
|
@ -81,6 +96,12 @@ importers:
|
|||
prettier-eslint:
|
||||
specifier: ^16.3.0
|
||||
version: 16.3.0
|
||||
tsx:
|
||||
specifier: ^4.19.2
|
||||
version: 4.19.2
|
||||
typescript:
|
||||
specifier: ^5.7.3
|
||||
version: 5.7.3
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -146,6 +167,150 @@ packages:
|
|||
resolution: {integrity: sha512-PZ+vLpxGCRtmr2RMkqh8Zp+BenUaJqlS6xhgWKEZcgC/vfHLEzpHtKkB0sl3nZWpwtcKk6YWy+pU3okL2I97FA==}
|
||||
engines: {node: '>=16.11.0'}
|
||||
|
||||
'@esbuild/aix-ppc64@0.23.1':
|
||||
resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
|
||||
'@esbuild/android-arm64@0.23.1':
|
||||
resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-arm@0.23.1':
|
||||
resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/android-x64@0.23.1':
|
||||
resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
'@esbuild/darwin-arm64@0.23.1':
|
||||
resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/darwin-x64@0.23.1':
|
||||
resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@esbuild/freebsd-arm64@0.23.1':
|
||||
resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/freebsd-x64@0.23.1':
|
||||
resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@esbuild/linux-arm64@0.23.1':
|
||||
resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-arm@0.23.1':
|
||||
resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ia32@0.23.1':
|
||||
resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-loong64@0.23.1':
|
||||
resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-mips64el@0.23.1':
|
||||
resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-ppc64@0.23.1':
|
||||
resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-riscv64@0.23.1':
|
||||
resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-s390x@0.23.1':
|
||||
resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/linux-x64@0.23.1':
|
||||
resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@esbuild/netbsd-x64@0.23.1':
|
||||
resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
|
||||
'@esbuild/openbsd-arm64@0.23.1':
|
||||
resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/openbsd-x64@0.23.1':
|
||||
resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
'@esbuild/sunos-x64@0.23.1':
|
||||
resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
|
||||
'@esbuild/win32-arm64@0.23.1':
|
||||
resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-ia32@0.23.1':
|
||||
resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@esbuild/win32-x64@0.23.1':
|
||||
resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.0':
|
||||
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
@ -348,8 +513,14 @@ packages:
|
|||
'@types/luxon@3.4.2':
|
||||
resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==}
|
||||
|
||||
'@types/node@22.5.5':
|
||||
resolution: {integrity: sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA==}
|
||||
'@types/md5@2.3.5':
|
||||
resolution: {integrity: sha512-/i42wjYNgE6wf0j2bcTX6kuowmdL/6PE4IVitMpm2eYKBUuYCprdcWVK+xEF0gcV6ufMCRhtxmReGfc6hIK7Jw==}
|
||||
|
||||
'@types/ms@0.7.34':
|
||||
resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
|
||||
|
||||
'@types/node@22.10.5':
|
||||
resolution: {integrity: sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==}
|
||||
|
||||
'@types/webidl-conversions@7.0.3':
|
||||
resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==}
|
||||
|
@ -360,6 +531,14 @@ packages:
|
|||
'@types/ws@8.5.12':
|
||||
resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.19.1':
|
||||
resolution: {integrity: sha512-tJzcVyvvb9h/PB96g30MpxACd9IrunT7GF9wfA9/0TJ1LxGOJx1TdPzSbBBnNED7K9Ka8ybJsnEpiXPktolTLg==}
|
||||
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.8.0'
|
||||
|
||||
'@typescript-eslint/parser@6.21.0':
|
||||
resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
|
@ -370,14 +549,36 @@ packages:
|
|||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/parser@8.19.1':
|
||||
resolution: {integrity: sha512-67gbfv8rAwawjYx3fYArwldTQKoYfezNUT4D5ioWetr/xCrxXxvleo3uuiFuKfejipvq+og7mjz3b0G2bVyUCw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.8.0'
|
||||
|
||||
'@typescript-eslint/scope-manager@6.21.0':
|
||||
resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
|
||||
'@typescript-eslint/scope-manager@8.19.1':
|
||||
resolution: {integrity: sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/type-utils@8.19.1':
|
||||
resolution: {integrity: sha512-Rp7k9lhDKBMRJB/nM9Ksp1zs4796wVNyihG9/TU9R6KCJDNkQbc2EOKjrBtLYh3396ZdpXLtr/MkaSEmNMtykw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.8.0'
|
||||
|
||||
'@typescript-eslint/types@6.21.0':
|
||||
resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
|
||||
'@typescript-eslint/types@8.19.1':
|
||||
resolution: {integrity: sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@typescript-eslint/typescript-estree@6.21.0':
|
||||
resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
|
@ -387,10 +588,27 @@ packages:
|
|||
typescript:
|
||||
optional: true
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.19.1':
|
||||
resolution: {integrity: sha512-jk/TZwSMJlxlNnqhy0Eod1PNEvCkpY6MXOXE/WLlblZ6ibb32i2We4uByoKPv1d0OD2xebDv4hbs3fm11SMw8Q==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4 <5.8.0'
|
||||
|
||||
'@typescript-eslint/utils@8.19.1':
|
||||
resolution: {integrity: sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
peerDependencies:
|
||||
eslint: ^8.57.0 || ^9.0.0
|
||||
typescript: '>=4.8.4 <5.8.0'
|
||||
|
||||
'@typescript-eslint/visitor-keys@6.21.0':
|
||||
resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.19.1':
|
||||
resolution: {integrity: sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@ungap/structured-clone@1.2.0':
|
||||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||
|
||||
|
@ -410,11 +628,6 @@ packages:
|
|||
peerDependencies:
|
||||
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||
|
||||
acorn@8.12.1:
|
||||
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
|
||||
acorn@8.14.0:
|
||||
resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
@ -668,6 +881,11 @@ packages:
|
|||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
esbuild@0.23.1:
|
||||
resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
escape-string-regexp@1.0.5:
|
||||
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
@ -802,6 +1020,11 @@ packages:
|
|||
fs.realpath@1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
|
||||
fsevents@2.3.3:
|
||||
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
gamedig@5.1.4:
|
||||
resolution: {integrity: sha512-MgSbNVGh5QMdrmRTrZ3W7W6sC5/Mx+dMgTy2uZCKQ9vns9eFXkQj61Pw2Y2FNHNMMp4DXFSUMYAPJWLcR16Wwg==}
|
||||
engines: {node: '>=16.20.0'}
|
||||
|
@ -823,6 +1046,9 @@ packages:
|
|||
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
get-tsconfig@4.8.1:
|
||||
resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
|
||||
|
||||
glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
|
@ -1073,6 +1299,10 @@ packages:
|
|||
resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
|
@ -1326,6 +1556,9 @@ packages:
|
|||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
|
||||
responselike@3.0.0:
|
||||
resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
@ -1490,12 +1723,23 @@ packages:
|
|||
peerDependencies:
|
||||
typescript: '>=4.2.0'
|
||||
|
||||
ts-api-utils@2.0.0:
|
||||
resolution: {integrity: sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==}
|
||||
engines: {node: '>=18.12'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.8.4'
|
||||
|
||||
ts-mixer@6.0.4:
|
||||
resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==}
|
||||
|
||||
tslib@2.7.0:
|
||||
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
|
||||
|
||||
tsx@4.19.2:
|
||||
resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
hasBin: true
|
||||
|
||||
type-check@0.4.0:
|
||||
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
@ -1504,13 +1748,13 @@ packages:
|
|||
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
typescript@5.7.2:
|
||||
resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==}
|
||||
typescript@5.7.3:
|
||||
resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
undici-types@6.19.8:
|
||||
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
|
||||
undici-types@6.20.0:
|
||||
resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
|
||||
|
||||
undici@5.28.4:
|
||||
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
|
||||
|
@ -1724,6 +1968,78 @@ snapshots:
|
|||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
||||
'@esbuild/aix-ppc64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-arm@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/android-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-arm64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/darwin-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-arm64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/freebsd-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-arm@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ia32@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-loong64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-mips64el@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-ppc64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-riscv64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-s390x@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/linux-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/netbsd-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-arm64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/openbsd-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/sunos-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-arm64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-ia32@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@esbuild/win32-x64@0.23.1':
|
||||
optional: true
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)':
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
|
@ -1907,9 +2223,13 @@ snapshots:
|
|||
|
||||
'@types/luxon@3.4.2': {}
|
||||
|
||||
'@types/node@22.5.5':
|
||||
'@types/md5@2.3.5': {}
|
||||
|
||||
'@types/ms@0.7.34': {}
|
||||
|
||||
'@types/node@22.10.5':
|
||||
dependencies:
|
||||
undici-types: 6.19.8
|
||||
undici-types: 6.20.0
|
||||
|
||||
'@types/webidl-conversions@7.0.3': {}
|
||||
|
||||
|
@ -1919,18 +2239,47 @@ snapshots:
|
|||
|
||||
'@types/ws@8.5.12':
|
||||
dependencies:
|
||||
'@types/node': 22.5.5
|
||||
'@types/node': 22.10.5
|
||||
|
||||
'@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.2)':
|
||||
'@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@9.16.0)(typescript@5.7.3))(eslint@9.16.0)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@typescript-eslint/parser': 8.19.1(eslint@9.16.0)(typescript@5.7.3)
|
||||
'@typescript-eslint/scope-manager': 8.19.1
|
||||
'@typescript-eslint/type-utils': 8.19.1(eslint@9.16.0)(typescript@5.7.3)
|
||||
'@typescript-eslint/utils': 8.19.1(eslint@9.16.0)(typescript@5.7.3)
|
||||
'@typescript-eslint/visitor-keys': 8.19.1
|
||||
eslint: 9.16.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.2
|
||||
natural-compare: 1.4.0
|
||||
ts-api-utils: 2.0.0(typescript@5.7.3)
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 6.21.0
|
||||
'@typescript-eslint/types': 6.21.0
|
||||
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.2)
|
||||
'@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.3)
|
||||
'@typescript-eslint/visitor-keys': 6.21.0
|
||||
debug: 4.3.7
|
||||
eslint: 8.57.1
|
||||
optionalDependencies:
|
||||
typescript: 5.7.2
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/parser@8.19.1(eslint@9.16.0)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 8.19.1
|
||||
'@typescript-eslint/types': 8.19.1
|
||||
'@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3)
|
||||
'@typescript-eslint/visitor-keys': 8.19.1
|
||||
debug: 4.3.7
|
||||
eslint: 9.16.0
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
@ -1939,9 +2288,27 @@ snapshots:
|
|||
'@typescript-eslint/types': 6.21.0
|
||||
'@typescript-eslint/visitor-keys': 6.21.0
|
||||
|
||||
'@typescript-eslint/scope-manager@8.19.1':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.19.1
|
||||
'@typescript-eslint/visitor-keys': 8.19.1
|
||||
|
||||
'@typescript-eslint/type-utils@8.19.1(eslint@9.16.0)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3)
|
||||
'@typescript-eslint/utils': 8.19.1(eslint@9.16.0)(typescript@5.7.3)
|
||||
debug: 4.3.7
|
||||
eslint: 9.16.0
|
||||
ts-api-utils: 2.0.0(typescript@5.7.3)
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/types@6.21.0': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@6.21.0(typescript@5.7.2)':
|
||||
'@typescript-eslint/types@8.19.1': {}
|
||||
|
||||
'@typescript-eslint/typescript-estree@6.21.0(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 6.21.0
|
||||
'@typescript-eslint/visitor-keys': 6.21.0
|
||||
|
@ -1950,9 +2317,34 @@ snapshots:
|
|||
is-glob: 4.0.3
|
||||
minimatch: 9.0.3
|
||||
semver: 7.6.3
|
||||
ts-api-utils: 1.4.3(typescript@5.7.2)
|
||||
ts-api-utils: 1.4.3(typescript@5.7.3)
|
||||
optionalDependencies:
|
||||
typescript: 5.7.2
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/typescript-estree@8.19.1(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.19.1
|
||||
'@typescript-eslint/visitor-keys': 8.19.1
|
||||
debug: 4.3.7
|
||||
fast-glob: 3.3.2
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.5
|
||||
semver: 7.6.3
|
||||
ts-api-utils: 2.0.0(typescript@5.7.3)
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@typescript-eslint/utils@8.19.1(eslint@9.16.0)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@9.16.0)
|
||||
'@typescript-eslint/scope-manager': 8.19.1
|
||||
'@typescript-eslint/types': 8.19.1
|
||||
'@typescript-eslint/typescript-estree': 8.19.1(typescript@5.7.3)
|
||||
eslint: 9.16.0
|
||||
typescript: 5.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
@ -1961,6 +2353,11 @@ snapshots:
|
|||
'@typescript-eslint/types': 6.21.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@typescript-eslint/visitor-keys@8.19.1':
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.19.1
|
||||
eslint-visitor-keys: 4.2.0
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
|
||||
'@vladfrangu/async_event_emitter@2.4.6': {}
|
||||
|
@ -1973,8 +2370,6 @@ snapshots:
|
|||
dependencies:
|
||||
acorn: 8.14.0
|
||||
|
||||
acorn@8.12.1: {}
|
||||
|
||||
acorn@8.14.0: {}
|
||||
|
||||
agent-base@6.0.2:
|
||||
|
@ -2253,6 +2648,33 @@ snapshots:
|
|||
|
||||
entities@4.5.0: {}
|
||||
|
||||
esbuild@0.23.1:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.23.1
|
||||
'@esbuild/android-arm': 0.23.1
|
||||
'@esbuild/android-arm64': 0.23.1
|
||||
'@esbuild/android-x64': 0.23.1
|
||||
'@esbuild/darwin-arm64': 0.23.1
|
||||
'@esbuild/darwin-x64': 0.23.1
|
||||
'@esbuild/freebsd-arm64': 0.23.1
|
||||
'@esbuild/freebsd-x64': 0.23.1
|
||||
'@esbuild/linux-arm': 0.23.1
|
||||
'@esbuild/linux-arm64': 0.23.1
|
||||
'@esbuild/linux-ia32': 0.23.1
|
||||
'@esbuild/linux-loong64': 0.23.1
|
||||
'@esbuild/linux-mips64el': 0.23.1
|
||||
'@esbuild/linux-ppc64': 0.23.1
|
||||
'@esbuild/linux-riscv64': 0.23.1
|
||||
'@esbuild/linux-s390x': 0.23.1
|
||||
'@esbuild/linux-x64': 0.23.1
|
||||
'@esbuild/netbsd-x64': 0.23.1
|
||||
'@esbuild/openbsd-arm64': 0.23.1
|
||||
'@esbuild/openbsd-x64': 0.23.1
|
||||
'@esbuild/sunos-x64': 0.23.1
|
||||
'@esbuild/win32-arm64': 0.23.1
|
||||
'@esbuild/win32-ia32': 0.23.1
|
||||
'@esbuild/win32-x64': 0.23.1
|
||||
|
||||
escape-string-regexp@1.0.5: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
@ -2450,6 +2872,9 @@ snapshots:
|
|||
|
||||
fs.realpath@1.0.0: {}
|
||||
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
gamedig@5.1.4:
|
||||
dependencies:
|
||||
cheerio: 1.0.0-rc.12
|
||||
|
@ -2488,6 +2913,10 @@ snapshots:
|
|||
|
||||
get-stream@6.0.1: {}
|
||||
|
||||
get-tsconfig@4.8.1:
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
|
||||
glob-parent@5.1.2:
|
||||
dependencies:
|
||||
is-glob: 4.0.3
|
||||
|
@ -2573,11 +3002,11 @@ snapshots:
|
|||
|
||||
i18next-fs-backend@2.6.0: {}
|
||||
|
||||
i18next@24.0.0(typescript@5.7.2):
|
||||
i18next@24.0.0(typescript@5.7.3):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.25.6
|
||||
optionalDependencies:
|
||||
typescript: 5.7.2
|
||||
typescript: 5.7.3
|
||||
|
||||
iconv-lite@0.6.3:
|
||||
dependencies:
|
||||
|
@ -2636,7 +3065,7 @@ snapshots:
|
|||
|
||||
jintr@3.0.2:
|
||||
dependencies:
|
||||
acorn: 8.12.1
|
||||
acorn: 8.14.0
|
||||
|
||||
js-yaml@4.1.0:
|
||||
dependencies:
|
||||
|
@ -2724,6 +3153,10 @@ snapshots:
|
|||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
minipass@3.3.6:
|
||||
|
@ -2873,7 +3306,7 @@ snapshots:
|
|||
|
||||
prettier-eslint@16.3.0:
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.7.2)
|
||||
'@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.7.3)
|
||||
common-tags: 1.8.2
|
||||
dlv: 1.1.3
|
||||
eslint: 8.57.1
|
||||
|
@ -2883,7 +3316,7 @@ snapshots:
|
|||
prettier: 3.4.2
|
||||
pretty-format: 29.7.0
|
||||
require-relative: 0.8.7
|
||||
typescript: 5.7.2
|
||||
typescript: 5.7.3
|
||||
vue-eslint-parser: 9.4.3(eslint@8.57.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -2949,6 +3382,8 @@ snapshots:
|
|||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
resolve-pkg-maps@1.0.0: {}
|
||||
|
||||
responselike@3.0.0:
|
||||
dependencies:
|
||||
lowercase-keys: 3.0.0
|
||||
|
@ -3100,23 +3535,34 @@ snapshots:
|
|||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
ts-api-utils@1.4.3(typescript@5.7.2):
|
||||
ts-api-utils@1.4.3(typescript@5.7.3):
|
||||
dependencies:
|
||||
typescript: 5.7.2
|
||||
typescript: 5.7.3
|
||||
|
||||
ts-api-utils@2.0.0(typescript@5.7.3):
|
||||
dependencies:
|
||||
typescript: 5.7.3
|
||||
|
||||
ts-mixer@6.0.4: {}
|
||||
|
||||
tslib@2.7.0: {}
|
||||
|
||||
tsx@4.19.2:
|
||||
dependencies:
|
||||
esbuild: 0.23.1
|
||||
get-tsconfig: 4.8.1
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
type-check@0.4.0:
|
||||
dependencies:
|
||||
prelude-ls: 1.2.1
|
||||
|
||||
type-fest@0.20.2: {}
|
||||
|
||||
typescript@5.7.2: {}
|
||||
typescript@5.7.3: {}
|
||||
|
||||
undici-types@6.19.8: {}
|
||||
undici-types@6.20.0: {}
|
||||
|
||||
undici@5.28.4:
|
||||
dependencies:
|
||||
|
|
9
src/adapters/cache/ICacheAdapter.js
vendored
9
src/adapters/cache/ICacheAdapter.js
vendored
|
@ -1,9 +0,0 @@
|
|||
export default class ICacheAdapter {
|
||||
get() {}
|
||||
|
||||
set() {}
|
||||
|
||||
clear() {}
|
||||
|
||||
delete() {}
|
||||
}
|
9
src/adapters/cache/ICacheAdapter.ts
vendored
Normal file
9
src/adapters/cache/ICacheAdapter.ts
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
export default class ICacheAdapter {
|
||||
get(_key: string) {}
|
||||
|
||||
set<T>(_key: string, _value: T) {}
|
||||
|
||||
clear() {}
|
||||
|
||||
delete(_key: string) {}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
import ICacheAdapter from "./ICacheAdapter.js";
|
||||
|
||||
export default class MapCache extends ICacheAdapter {
|
||||
store = new Map();
|
||||
constructor() {
|
||||
super();
|
||||
this.store = new Map();
|
||||
}
|
||||
|
||||
get(key) {
|
||||
get(key: string) {
|
||||
return this.store.get(key);
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
set<T>(key: string, value: T) {
|
||||
this.store.set(key, value);
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ export default class MapCache extends ICacheAdapter {
|
|||
this.store.clear();
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
delete(key: string) {
|
||||
this.store.delete(key);
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
export default class IDatabaseAdapter {
|
||||
async connect() {
|
||||
throw new Error("Method `connect` not implemented.");
|
||||
}
|
||||
|
||||
async disconnect() {
|
||||
throw new Error("Method `disconnect` not implemented.");
|
||||
}
|
||||
|
||||
async find() {
|
||||
throw new Error("Method \"find\" must be implemented");
|
||||
}
|
||||
|
||||
async findOne() {
|
||||
throw new Error("Method \"findOne\" must be implemented");
|
||||
}
|
||||
|
||||
async updateOne() {
|
||||
throw new Error("Method \"updateOne\" must be implemented");
|
||||
}
|
||||
|
||||
async deleteOne() {
|
||||
throw new Error("Method \"deleteOne\" must be implemented");
|
||||
}
|
||||
}
|
9
src/adapters/database/IDatabaseAdapter.ts
Normal file
9
src/adapters/database/IDatabaseAdapter.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
export default abstract class IDatabaseAdapter<ModelType, QueryType, UpdateType, OptionsType> {
|
||||
abstract connect(): Promise<void>;
|
||||
abstract disconnect(): Promise<void>;
|
||||
abstract find(_model: ModelType, _query?: QueryType, _options?: OptionsType): Promise<unknown[]>;
|
||||
abstract findOne(_model: ModelType, _query?: QueryType, _options?: OptionsType): Promise<unknown | null>;
|
||||
abstract updateOne(_model: ModelType, _filter: QueryType, _update: UpdateType, _options?: OptionsType): Promise<unknown>;
|
||||
abstract deleteOne(_model: ModelType, _filter: QueryType): Promise<unknown>;
|
||||
abstract findOneOrCreate(_model: ModelType, _filter: QueryType): Promise<unknown>;
|
||||
}
|
|
@ -1,24 +1,21 @@
|
|||
import mongoose from "mongoose";
|
||||
import mongoose, { ConnectOptions, Document, Model, FilterQuery, QueryOptions, UpdateQuery } from "mongoose";
|
||||
import IDatabaseAdapter from "./IDatabaseAdapter.js";
|
||||
import logger from "../../helpers/logger.js";
|
||||
import logger from "@/helpers/logger.js";
|
||||
import Cache from "../cache/MapCache.js";
|
||||
|
||||
export default class MongooseAdapter extends IDatabaseAdapter {
|
||||
/**
|
||||
*
|
||||
* @param {string} uri - database url connect
|
||||
* @param {mongoose.ConnectOptions} options - database connect options
|
||||
*/
|
||||
constructor(uri, options = {}) {
|
||||
export default class MongooseAdapter extends IDatabaseAdapter<Model<any>, FilterQuery<any>, UpdateQuery<any>, QueryOptions> {
|
||||
cache = new Cache();
|
||||
options: ConnectOptions;
|
||||
uri: string;
|
||||
|
||||
constructor(uri: string, options: ConnectOptions = {}) {
|
||||
super();
|
||||
|
||||
if (!uri) {
|
||||
throw new Error("MongooseAdapter: URI is required.");
|
||||
}
|
||||
|
||||
this.uri = uri;
|
||||
this.options = options;
|
||||
this.cache = new Cache();
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
async connect() {
|
||||
|
@ -32,11 +29,11 @@ export default class MongooseAdapter extends IDatabaseAdapter {
|
|||
this.cache.clear();
|
||||
}
|
||||
|
||||
#generateCacheKey(modelName, query, options) {
|
||||
#generateCacheKey(modelName: string, query: {}, options: {}) {
|
||||
return `${modelName}:${JSON.stringify(query)}:${JSON.stringify(options)}`;
|
||||
}
|
||||
|
||||
async find(model, query = {}, options = {}) {
|
||||
async find<T extends Document>(model: Model<T>, query: FilterQuery<T>, options = {}): Promise<T[]> {
|
||||
const cacheKey = this.#generateCacheKey(model.modelName, query, options);
|
||||
if (this.cache.get(cacheKey)) {
|
||||
return this.cache.get(cacheKey);
|
||||
|
@ -47,7 +44,7 @@ export default class MongooseAdapter extends IDatabaseAdapter {
|
|||
return result;
|
||||
}
|
||||
|
||||
async findOne(model, query = {}, options = {}) {
|
||||
async findOne<T extends Document>(model: Model<T>, query: FilterQuery<T>, options = {}): Promise<T | null> {
|
||||
const cacheKey = this.#generateCacheKey(model.modelName, query, options);
|
||||
if (this.cache.get(cacheKey)) {
|
||||
return this.cache.get(cacheKey);
|
||||
|
@ -58,15 +55,26 @@ export default class MongooseAdapter extends IDatabaseAdapter {
|
|||
return result;
|
||||
}
|
||||
|
||||
async updateOne(model, filter, update, options = {}) {
|
||||
async updateOne<T extends Document>(model: Model<T>, filter: FilterQuery<T>, update: UpdateQuery<T>, options = {}) {
|
||||
const result = await model.updateOne(filter, update, options).exec();
|
||||
this.cache.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
async deleteOne(model, filter) {
|
||||
async deleteOne<T extends Document>(model: Model<T>, filter: FilterQuery<T>) {
|
||||
const result = await model.deleteOne(filter).exec();
|
||||
this.cache.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
async findOneOrCreate<T extends Document>(model: Model<T>, filter: FilterQuery<T>) {
|
||||
this.cache.clear();
|
||||
const result = await model.findOne(filter).then(result => {
|
||||
if (result) return result;
|
||||
|
||||
return model.create(filter);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import path from "node:path";
|
||||
import { GatewayIntentBits } from "discord.js";
|
||||
import { GatewayIntentBits, MessageMentionOptions } from "discord.js";
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
import { ExtendedClient } from "@/structures/client.js";
|
||||
|
||||
export const PROJECT_ROOT = path.join(import.meta.dirname, "..");
|
||||
export const CONFIG_PATH = path.join(PROJECT_ROOT, "..", "config.json");
|
||||
|
@ -21,6 +22,6 @@ export const CLIENT_INTENTS = [
|
|||
GatewayIntentBits.DirectMessages,
|
||||
GatewayIntentBits.DirectMessageReactions,
|
||||
];
|
||||
export const CLIENT_ALLOWED_MENTIONS = { parse: ["everyone", "roles", "users"] };
|
||||
export const CLIENT_ALLOWED_MENTIONS: MessageMentionOptions = { parse: ["everyone", "roles", "users"] };
|
||||
|
||||
export const SUPER_CONTEXT = new AsyncLocalStorage();
|
||||
export const SUPER_CONTEXT = new AsyncLocalStorage<ExtendedClient>();
|
|
@ -1,18 +1,15 @@
|
|||
import logger from "../helpers/logger.js";
|
||||
import { resolve } from "node:path";
|
||||
import loadCronTasks from "../utils/loadCronTasks.js";
|
||||
import { CronManager } from "../services/cron/index.js";
|
||||
import loadCronTasks from "@/utils/loadCronTasks.js";
|
||||
import { CronManager } from "@/services/cron/index.js";
|
||||
import { ExtendedClient } from "@/structures/client.js";
|
||||
|
||||
export const data = {
|
||||
name: "ready",
|
||||
once: true,
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../structures/client.js").ExtendedClient} client
|
||||
*/
|
||||
export async function run(client) {
|
||||
export async function run(client: ExtendedClient) {
|
||||
logger.ready(client.user.tag + " is online!");
|
||||
|
||||
// Fetching all app emojis, because we need to use them
|
|
@ -1,27 +1,30 @@
|
|||
import logger from "../../../helpers/logger.js";
|
||||
import { ExtendedClient } from "@/structures/client.js";
|
||||
import logger from "@/helpers/logger.js";
|
||||
import differentCommands from "../utils/differentcommands.js";
|
||||
import { CommandFileObject } from "@/types.js";
|
||||
import { ApplicationCommandData, GuildApplicationCommandManager } from "discord.js";
|
||||
|
||||
export default async function registerCommands(props) {
|
||||
type RegisterCommandProps = {
|
||||
client: ExtendedClient;
|
||||
commands: CommandFileObject[];
|
||||
};
|
||||
|
||||
export default async function registerCommands(props: RegisterCommandProps) {
|
||||
props.client.once("ready", () => handleRegistration(props.client, props.commands));
|
||||
}
|
||||
|
||||
const handleRegistration = async (client, commands) => {
|
||||
const handleRegistration = async (client: ExtendedClient, commands: CommandFileObject[]) => {
|
||||
const devOnlyCommands = commands.filter(cmd => cmd.options?.devOnly);
|
||||
const globalCommands = commands.filter(cmd => !cmd.options?.devOnly);
|
||||
|
||||
const devGuildsIds = client.configService.get("devGuildsIds");
|
||||
const devGuildsIds = client.configService.get<string[]>("devGuildsIds");
|
||||
|
||||
await registerGlobalCommands(client, globalCommands);
|
||||
await registerDevCommands(client, devOnlyCommands, devGuildsIds);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../../../structures/client.js").ExtendedClient} client
|
||||
* @param {*} commands
|
||||
*/
|
||||
const registerGlobalCommands = async (client, commands) => {
|
||||
const appCommandsManager = client.application.commands;
|
||||
const registerGlobalCommands = async (client: ExtendedClient, commands: CommandFileObject[]) => {
|
||||
const appCommandsManager = client.application!.commands;
|
||||
await appCommandsManager.fetch();
|
||||
|
||||
await Promise.all(
|
||||
|
@ -29,7 +32,7 @@ const registerGlobalCommands = async (client, commands) => {
|
|||
const targetCommand = appCommandsManager.cache.find(cmd => cmd.name === data.name);
|
||||
|
||||
if (targetCommand && differentCommands(targetCommand, data)) {
|
||||
await targetCommand.edit(data).catch(() => logger.error(`Failed to update command: ${data.name} globally`));
|
||||
await targetCommand.edit(data as Partial<ApplicationCommandData>).catch(() => logger.error(`Failed to update command: ${data.name} globally`));
|
||||
|
||||
logger.log(`Edited command globally: ${data.name}`);
|
||||
} else if (!targetCommand) {
|
||||
|
@ -38,15 +41,10 @@ const registerGlobalCommands = async (client, commands) => {
|
|||
}),
|
||||
);
|
||||
|
||||
logger.log("Registered global commands");
|
||||
logger.log(`Registered ${commands.length} global commands`);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../../../structures/client.js").ExtendedClient} client
|
||||
* @param {*} commands
|
||||
*/
|
||||
const registerDevCommands = async (client, commands, guildsIds) => {
|
||||
const registerDevCommands = async (client: ExtendedClient, commands: CommandFileObject[], guildsIds: string[]) => {
|
||||
const devGuilds = [];
|
||||
|
||||
for (const guildId of guildsIds) {
|
||||
|
@ -60,7 +58,7 @@ const registerDevCommands = async (client, commands, guildsIds) => {
|
|||
devGuilds.push(guild);
|
||||
}
|
||||
|
||||
const guildCommandsManagers = [];
|
||||
const guildCommandsManagers: GuildApplicationCommandManager[] = [];
|
||||
|
||||
for (const guild of devGuilds) {
|
||||
const guildCommandsManager = guild.commands;
|
||||
|
@ -74,7 +72,7 @@ const registerDevCommands = async (client, commands, guildsIds) => {
|
|||
guildCommandsManagers.map(async guildCommands => {
|
||||
const targetCommand = guildCommands.cache.find(cmd => cmd.name === data.name);
|
||||
if (targetCommand && differentCommands(targetCommand, data)) {
|
||||
await targetCommand.edit(data).catch(() => logger.error(`Failed to update command: ${data.name} in ${guildCommands.guild.name} server`));
|
||||
await targetCommand.edit(data as Partial<ApplicationCommandData>).catch(() => logger.error(`Failed to update command: ${data.name} in ${guildCommands.guild.name} server`));
|
||||
|
||||
logger.log(`Edited command globally: ${data.name}`);
|
||||
} else if (!targetCommand) {
|
|
@ -1,16 +1,16 @@
|
|||
import { resolve } from "node:path";
|
||||
import logger from "../../helpers/logger.js";
|
||||
import { getFilePaths } from "../../utils/index.js";
|
||||
import { toFileURL } from "../../utils/resolve-file.js";
|
||||
import logger from "@/helpers/logger.js";
|
||||
import { getFilePaths } from "@/utils/get-path.js";
|
||||
import { toFileURL } from "@/utils/resolve-file.js";
|
||||
import registerCommands from "./functions/registerCommands.js";
|
||||
import { ExtendedClient } from "@/structures/client.js";
|
||||
import { CommandFileObject } from "@//types.js";
|
||||
|
||||
export class CommandHandler {
|
||||
constructor(client) {
|
||||
/**
|
||||
* @type {import("../../structures/client.js").ExtendedClient} client
|
||||
*/
|
||||
client: ExtendedClient;
|
||||
commands: CommandFileObject[] = [];
|
||||
constructor(client: ExtendedClient) {
|
||||
this.client = client;
|
||||
this.commands = [];
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
@ -26,7 +26,7 @@ export class CommandHandler {
|
|||
|
||||
async #buildCommands() {
|
||||
const cmdPath = resolve(this.client.configService.get("paths.commands"));
|
||||
const commandFilePaths = (await getFilePaths(cmdPath, true)).filter(path => path.endsWith(".js"));
|
||||
const commandFilePaths = (await getFilePaths(cmdPath, true)).filter(path => path.endsWith(".js") || path.endsWith(".ts"));
|
||||
|
||||
for (const cmdFilePath of commandFilePaths) {
|
||||
const { data, run } = await import(toFileURL(cmdFilePath));
|
||||
|
@ -58,7 +58,7 @@ export class CommandHandler {
|
|||
// Skip if autocomplete handler is not defined
|
||||
if (isAutocomplete && !targetCommand.autocompleteRun) return;
|
||||
|
||||
const command = targetCommand[isAutocomplete ? "autocompleteRun" : "run"];
|
||||
const command = targetCommand[isAutocomplete ? "autocompleteRun" : "run"]!;
|
||||
|
||||
try {
|
||||
await command({
|
|
@ -1,4 +1,4 @@
|
|||
export default function differentCommands(appCommand, localCommand) {
|
||||
export default function differentCommands(appCommand: any, localCommand: any) {
|
||||
const appOptions = appCommand.options || [];
|
||||
const localOptions = localCommand.options || [];
|
||||
const appDescription = appCommand.description || "";
|
|
@ -1,12 +1,24 @@
|
|||
import { resolve } from "node:path";
|
||||
import logger from "../../helpers/logger.js";
|
||||
import { getFilePaths } from "../../utils/index.js";
|
||||
import { toFileURL } from "../../utils/resolve-file.js";
|
||||
import { useMainPlayer } from "discord-player";
|
||||
import logger from "@/helpers/logger.js";
|
||||
import { getFilePaths } from "@/utils/get-path.js";
|
||||
import { toFileURL } from "@/utils/resolve-file.js";
|
||||
import { GuildQueueEvents, useMainPlayer } from "discord-player";
|
||||
import { ExtendedClient } from "@/structures/client.js";
|
||||
import { ClientEvents } from "discord.js";
|
||||
|
||||
interface EventHandlerEvents {
|
||||
data: {
|
||||
name: keyof ClientEvents;
|
||||
once?: boolean;
|
||||
player?: boolean;
|
||||
};
|
||||
run: Function;
|
||||
}
|
||||
|
||||
export class EventHandler {
|
||||
constructor(client) {
|
||||
this.events = [];
|
||||
events: EventHandlerEvents[] = [];
|
||||
client: ExtendedClient;
|
||||
constructor(client: ExtendedClient) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
@ -18,7 +30,7 @@ export class EventHandler {
|
|||
async #buildEvents() {
|
||||
try {
|
||||
const eventPath = resolve(this.client.configService.get("paths.events"));
|
||||
const eventFilePaths = (await getFilePaths(eventPath, true)).filter(path => path.endsWith(".js"));
|
||||
const eventFilePaths = (await getFilePaths(eventPath, true)).filter(path => path.endsWith(".js") || path.endsWith(".ts"));
|
||||
|
||||
for (const eventFilePath of eventFilePaths) {
|
||||
const { data, run } = await import(toFileURL(eventFilePath));
|
||||
|
@ -42,11 +54,9 @@ export class EventHandler {
|
|||
}
|
||||
|
||||
$registerEvents() {
|
||||
const player = useMainPlayer();
|
||||
for (const { data, run } of this.events) {
|
||||
if (data.player) player.events.on(data.name, run);
|
||||
if (data.once) this.client.once(data.name, run);
|
||||
else this.client.on(data.name, run);
|
||||
if (data.once) this.client.once(data.name, (...args) => run(...args));
|
||||
else this.client.on(data.name, (...args) => run(...args));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,14 +1,16 @@
|
|||
import { ExtendedClient } from "@/structures/client.js";
|
||||
import { CommandHandler } from "./command-handler/index.js";
|
||||
import { EventHandler } from "./event-handler/index.js";
|
||||
|
||||
export class Handlers {
|
||||
constructor(client) {
|
||||
client: ExtendedClient;
|
||||
constructor(client: ExtendedClient) {
|
||||
this.client = client;
|
||||
|
||||
this.#init();
|
||||
this.init();
|
||||
}
|
||||
|
||||
async #init() {
|
||||
private async init() {
|
||||
const eventHandler = new EventHandler(this.client);
|
||||
await eventHandler.init();
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
// Thanks Stackoverflow <3
|
||||
function setDaysTimeout(callback, days) {
|
||||
// 86400 seconds in a day
|
||||
const msInDay = 86400 * 1000;
|
||||
|
||||
let dayCount = 0;
|
||||
const timer = setInterval(function () {
|
||||
dayCount++; // a day has passed
|
||||
|
||||
if (dayCount === days) {
|
||||
clearInterval(timer);
|
||||
callback.apply(this, []);
|
||||
}
|
||||
}, msInDay);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("../base/Client")} client
|
||||
*/
|
||||
export async function init(client) {
|
||||
setDaysTimeout(async () => {
|
||||
const timestamp = Date.now() + 29 * 24 * 60 * 60 * 1000; // 29 days
|
||||
const members = client.membersData.find({ transactions: { $gt: [] } });
|
||||
|
||||
for (const member of members) {
|
||||
const transactions = member.transactions;
|
||||
for await (const transaction of transactions) {
|
||||
if (transaction.date < timestamp) {
|
||||
const index = transactions.indexOf(transaction);
|
||||
transactions.splice(index, 1);
|
||||
|
||||
await member.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 14);
|
||||
|
||||
setDaysTimeout(async () => {
|
||||
client.usersData.find({}, function (err, res) {
|
||||
for (const user of res) {
|
||||
client.users.fetch(user.id).then(async u => {
|
||||
if (u.username.match(/.*Deleted User.* [A-z0-9]+/g)) {
|
||||
await client.databaseCache.users.delete(u.id);
|
||||
await client.usersData.deleteOne({ id: u.id });
|
||||
client.logger.log(`Removed from database deleted user - ID: ${u.id} Username: ${u.username}`);
|
||||
|
||||
await client.usersData.save();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
client.membersData.find({}, function (err, res) {
|
||||
for (const user of res) {
|
||||
client.users.fetch(user.id).then(async u => {
|
||||
if (u.username.match(/.*Deleted User.* [A-z0-9]+/g)) {
|
||||
await client.databaseCache.members.delete(u.id);
|
||||
await client.membersData.deleteOne({ id: u.id });
|
||||
client.logger.log(`Removed from database deleted user - ID: ${u.id} Username: ${u.username}`);
|
||||
|
||||
await client.membersData.save();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 30);
|
||||
}
|
|
@ -1,43 +1,26 @@
|
|||
import { BaseInteraction } from "discord.js";
|
||||
import useClient from "../utils/use-client.js";
|
||||
import { BaseInteraction, User } from "discord.js";
|
||||
import useClient from "@/utils/use-client.js";
|
||||
|
||||
export const getLocale = guildId => {
|
||||
export const getLocale = async (guildId: string) => {
|
||||
const client = useClient();
|
||||
const guild = client.getGuildData(guildId);
|
||||
const guild = await client.getGuildData(guildId);
|
||||
return guild.language;
|
||||
};
|
||||
|
||||
const getAppEmojis = () => {
|
||||
const client = useClient();
|
||||
|
||||
return client.application.emojis.cache;
|
||||
return client.application?.emojis.cache;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('../structures/client.js').ExtendedClient} client
|
||||
* @param {string} prefixEmoji
|
||||
* @param {string} message
|
||||
*/
|
||||
const formatReply = (prefixEmoji, message) => {
|
||||
const emojis = getAppEmojis();
|
||||
const formatReply = (prefixEmoji: string, message: string) => {
|
||||
const emojis = getAppEmojis()!;
|
||||
return prefixEmoji ? `${emojis.find(e => e.name === prefixEmoji).toString()} ${message}` : `${message}`;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("discord.js").User} user
|
||||
* @returns
|
||||
*/
|
||||
export const getUsername = user => (user.discriminator === "0" ? user.username : user.tag);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import("discord.js").Message | import("discord.js").BaseInteraction} context
|
||||
* @param {string} key
|
||||
* @param {unknown[]} args
|
||||
* @param {*} options
|
||||
*/
|
||||
export const getUsername = (user: User) => (user.discriminator === "0" ? user.username : user.tag);
|
||||
|
||||
export const replyTranslated = async (context, key, args, options = {}) => {
|
||||
const client = useClient();
|
||||
const locale = options.locale || client.configService.get("defaultLang");
|
|
@ -1,99 +0,0 @@
|
|||
/**
|
||||
* Asynchronously iterates over a collection and executes a callback function for each item.
|
||||
*
|
||||
* @param {any[]} collection - The collection to iterate over.
|
||||
* @param {(item: any) => Promise<void>} callback - The async callback function to execute for each item in the collection.
|
||||
* @returns {Promise<void>} A promise that resolves when all items in the collection have been processed.
|
||||
*/
|
||||
export async function asyncForEach(collection, callback) {
|
||||
const allPromises = collection.map(async key => {
|
||||
await callback(key);
|
||||
});
|
||||
|
||||
return await Promise.all(allPromises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts an array by the specified key in ascending order.
|
||||
*
|
||||
* @param {any[]} array - The array to sort.
|
||||
* @param {string} key - The key to sort the array by.
|
||||
* @returns {any[]} The sorted array.
|
||||
*/
|
||||
export function sortByKey(array, key) {
|
||||
return array.sort(function (a, b) {
|
||||
const x = a[key];
|
||||
const y = b[key];
|
||||
return x < y ? 1 : x > y ? -1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuffles the elements of the provided array in-place.
|
||||
*
|
||||
* @param {any[]} pArray - The array to shuffle.
|
||||
* @returns {any[]} The shuffled array.
|
||||
*/
|
||||
export function shuffle(pArray) {
|
||||
const array = [];
|
||||
|
||||
pArray.forEach(element => array.push(element));
|
||||
|
||||
let currentIndex = array.length,
|
||||
temporaryValue,
|
||||
randomIndex;
|
||||
|
||||
while (currentIndex !== 0) {
|
||||
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||
currentIndex -= 1;
|
||||
temporaryValue = array[currentIndex];
|
||||
array[currentIndex] = array[randomIndex];
|
||||
array[randomIndex] = temporaryValue;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random integer between the specified minimum and maximum values (inclusive).
|
||||
*
|
||||
* @param {number} [min=0] - The minimum value (inclusive).
|
||||
* @param {number} [max=100] - The maximum value (inclusive).
|
||||
* @returns {number} A random integer between min and max.
|
||||
*/
|
||||
export function randomNum(min = 0, max = 100) {
|
||||
return (Math.random() * (max - min + 1)) << 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a date for the specified client and locale.
|
||||
*
|
||||
* @param {string} date - The date to format.
|
||||
* @param {Intl.LocalesArgument} [locale] - The locale to use for formatting the date.
|
||||
* @returns {string} The formatted date.
|
||||
*/
|
||||
export function printDate(date, locale = "en-US") {
|
||||
return new Intl.DateTimeFormat(locale).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the appropriate noun form based on the given number and noun forms.
|
||||
*
|
||||
* @param {number} number - The number to use for determining the noun form.
|
||||
* @param {Array} wordForms - An array of three elements: [one, two, five].
|
||||
* @returns {string} The appropriate noun form based on the given number.
|
||||
*/
|
||||
export function getNoun(number, wordForms) {
|
||||
if (!Array.isArray(wordForms) || wordForms.length !== 3) {
|
||||
throw new Error("wordForms should be an array with three elements: [one, two, five]");
|
||||
}
|
||||
|
||||
const [one, two, five] = wordForms;
|
||||
let n = Math.abs(number);
|
||||
n %= 100;
|
||||
if (n >= 5 && n <= 20) return five;
|
||||
n %= 10;
|
||||
if (n === 1) return one;
|
||||
if (n >= 2 && n <= 4) return two;
|
||||
return five;
|
||||
}
|
58
src/helpers/functions.ts
Normal file
58
src/helpers/functions.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
export async function asyncForEach<T>(collection: T[], callback: (_item: T) => Promise<void>) {
|
||||
const allPromises = collection.map(async key => {
|
||||
await callback(key);
|
||||
});
|
||||
|
||||
return await Promise.all(allPromises);
|
||||
}
|
||||
|
||||
export function sortByKey<T>(array: T[], key: string) {
|
||||
return array.sort(function (a, b) {
|
||||
const x = a[key];
|
||||
const y = b[key];
|
||||
return x < y ? 1 : x > y ? -1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
export function shuffle<T>(pArray: T[]) {
|
||||
const array: T[] = [];
|
||||
|
||||
pArray.forEach(element => array.push(element));
|
||||
|
||||
let currentIndex = array.length,
|
||||
temporaryValue,
|
||||
randomIndex;
|
||||
|
||||
while (currentIndex !== 0) {
|
||||
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||
currentIndex -= 1;
|
||||
temporaryValue = array[currentIndex];
|
||||
array[currentIndex] = array[randomIndex];
|
||||
array[randomIndex] = temporaryValue;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
export function randomNum(min: number = 0, max: number = 100) {
|
||||
return (Math.random() * (max - min + 1)) << 0;
|
||||
}
|
||||
|
||||
export function printDate(date: Date | number, locale: Intl.LocalesArgument = "en-US") {
|
||||
return new Intl.DateTimeFormat(locale).format(date);
|
||||
}
|
||||
|
||||
export function getNoun(number: number, wordForms: string[]) {
|
||||
if (!Array.isArray(wordForms) || wordForms.length !== 3) {
|
||||
throw new Error("wordForms should be an array with three elements: [one, two, five]");
|
||||
}
|
||||
|
||||
const [one, two, five] = wordForms;
|
||||
let n = Math.abs(number);
|
||||
n %= 100;
|
||||
if (n >= 5 && n <= 20) return five;
|
||||
n %= 10;
|
||||
if (n === 1) return one;
|
||||
if (n >= 2 && n <= 4) return two;
|
||||
return five;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import chalk from "chalk";
|
||||
|
||||
function format(tDate) {
|
||||
function format(tDate: Date | number) {
|
||||
return new Intl.DateTimeFormat("ru-RU", {
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
|
@ -21,27 +21,27 @@ const logLevels = {
|
|||
};
|
||||
|
||||
export default {
|
||||
log(...content) {
|
||||
log(...content: unknown[]) {
|
||||
return console.log(`[${format(Date.now())}]: ${logLevels.LOG} ${content.join(" ")}`);
|
||||
},
|
||||
|
||||
warn(...content) {
|
||||
warn(...content: unknown[]) {
|
||||
return console.log(`[${format(Date.now())}]: ${logLevels.WARN} ${content.join(" ")}`);
|
||||
},
|
||||
|
||||
error(...content) {
|
||||
error(...content: unknown[]) {
|
||||
return console.log(`[${format(Date.now())}]: ${logLevels.ERROR} ${content.join(" ")}`);
|
||||
},
|
||||
|
||||
debug(...content) {
|
||||
debug(...content: unknown[]) {
|
||||
return console.log(`[${format(Date.now())}]: ${logLevels.DEBUG} ${content.join(" ")}`);
|
||||
},
|
||||
|
||||
cmd(...content) {
|
||||
cmd(...content: unknown[]) {
|
||||
return console.log(`[${format(Date.now())}]: ${logLevels.CMD} ${content.join(" ")}`);
|
||||
},
|
||||
|
||||
ready(...content) {
|
||||
ready(...content: unknown[]) {
|
||||
return console.log(`[${format(Date.now())}]: ${logLevels.READY} ${content.join(" ")}`);
|
||||
},
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import useClient from "../../utils/use-client.js";
|
||||
import UserModel from "../../models/UserModel.js";
|
||||
import { createEmbed } from "../../utils/create-embed.js";
|
||||
import useClient from "@/utils/use-client.js";
|
||||
import UserModel from "@/models/UserModel.js";
|
||||
import { createEmbed } from "@/utils/create-embed.js";
|
||||
import logger from "../logger.js";
|
||||
import { getNoun } from "../functions.js";
|
||||
|
||||
|
@ -10,7 +10,9 @@ export const data = {
|
|||
const client = useClient();
|
||||
|
||||
const guilds = client.guilds.cache.values();
|
||||
const users = await client.adapter.find(UserModel, { birthdate: { $gt: 1 } });
|
||||
const users = await client.adapter.find(UserModel, {
|
||||
birthdate: { $ne: null },
|
||||
});
|
||||
|
||||
const currentData = new Date();
|
||||
const currentYear = currentData.getFullYear();
|
||||
|
@ -24,11 +26,15 @@ export const data = {
|
|||
|
||||
if (!channel) return;
|
||||
|
||||
if (!channel.isSendable()) return;
|
||||
|
||||
const userIDs = users.filter(u => guild.members.cache.has(u.id)).map(u => u.id);
|
||||
|
||||
await Promise.all(
|
||||
userIDs.map(async userID => {
|
||||
const user = users.find(u => u.id === userID);
|
||||
if (!user) return;
|
||||
|
||||
const userData = new Date(user.birthdate).getFullYear() <= 1970 ? new Date(user.birthdate * 1000) : new Date(user.birthdate);
|
||||
const userYear = userData.getFullYear();
|
||||
const userMonth = userData.getMonth();
|
||||
|
@ -38,7 +44,9 @@ export const data = {
|
|||
|
||||
if (userDate === currentDate && userMonth === currentMonth) {
|
||||
const embed = createEmbed({
|
||||
author: client.user.username,
|
||||
author: {
|
||||
name: client.user.username,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: client.translate("economy/birthdate:HAPPY_BIRTHDAY", {
|
||||
|
@ -47,11 +55,7 @@ export const data = {
|
|||
value: client.translate("economy/birthdate:HAPPY_BIRTHDAY_MESSAGE", {
|
||||
lng: data.language,
|
||||
user: user.id,
|
||||
age: `**${age}** ${getNoun(age, [
|
||||
client.translate("misc:NOUNS:AGE:1", null, data.language),
|
||||
client.translate("misc:NOUNS:AGE:2", null, data.language),
|
||||
client.translate("misc:NOUNS:AGE:5", null, data.language),
|
||||
])}`,
|
||||
age: `**${age}** ${getNoun(age, [client.translate("misc:NOUNS:AGE:1", data.language), client.translate("misc:NOUNS:AGE:2", data.language), client.translate("misc:NOUNS:AGE:5", data.language)])}`,
|
||||
}),
|
||||
},
|
||||
],
|
|
@ -1,8 +1,9 @@
|
|||
import { createEmbed } from "@/utils/create-embed.js";
|
||||
import UserModel from "../../models/UserModel.js";
|
||||
import useClient from "../../utils/use-client.js";
|
||||
import { createEmbed } from "../../utils/index.js";
|
||||
import { CronTaskData } from "@/types.js";
|
||||
|
||||
export const data = {
|
||||
export const data: CronTaskData = {
|
||||
name: "checkReminds",
|
||||
task: async () => {
|
||||
const client = useClient();
|
||||
|
@ -11,17 +12,19 @@ export const data = {
|
|||
for (const user of users) {
|
||||
if (!client.users.cache.has(user.id)) client.users.fetch(user.id);
|
||||
|
||||
client.cacheReminds.set(user.id, user);
|
||||
client.cacheReminds.set(user.id, {
|
||||
id: user.id,
|
||||
reminds: user.reminds,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
client.cacheReminds.forEach(async user => {
|
||||
const cachedUser = client.users.cache.get(user.id);
|
||||
client.cacheReminds.forEach(async ({ id, reminds }) => {
|
||||
const cachedUser = client.users.cache.get(id);
|
||||
|
||||
if (!cachedUser) return;
|
||||
|
||||
const reminds = user.reminds,
|
||||
mustSent = reminds.filter(r => r.sendAt < Math.floor(Date.now() / 1000));
|
||||
const mustSent = reminds.filter(r => r.sendAt < Math.floor(Date.now() / 1000));
|
||||
|
||||
if (!mustSent.length) return;
|
||||
|
||||
|
@ -53,15 +56,23 @@ export const data = {
|
|||
embeds: [embed],
|
||||
})
|
||||
.then(() => {
|
||||
client.adapter.updateOne(UserModel, { id: user.id }, { $pull: { reminds: { _id: r._id } } });
|
||||
client.adapter.updateOne(
|
||||
UserModel,
|
||||
{ id },
|
||||
{
|
||||
$pull: {
|
||||
reminds: {
|
||||
sendAt: r.sendAt,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
user.reminds = user.reminds.filter(r => r.sendAt >= Math.floor(Date.now() / 1000));
|
||||
reminds = reminds.filter(r => r.sendAt >= Math.floor(Date.now() / 1000));
|
||||
|
||||
await user.save();
|
||||
|
||||
if (!user.reminds.length) client.cacheReminds.delete(user.id);
|
||||
if (!reminds.length) client.cacheReminds.delete(id);
|
||||
});
|
||||
},
|
||||
schedule: "* * * * * *",
|
|
@ -1,59 +0,0 @@
|
|||
import { model, Schema } from "mongoose";
|
||||
import useClient from "../utils/use-client.js";
|
||||
|
||||
const client = useClient();
|
||||
|
||||
export default model(
|
||||
"Guild",
|
||||
new Schema({
|
||||
id: { type: String },
|
||||
|
||||
membersData: { type: Object, default: {} },
|
||||
members: [{ type: Schema.Types.ObjectId, ref: "Member" }],
|
||||
|
||||
language: { type: String, default: client.configService.get("defaultLang") },
|
||||
plugins: {
|
||||
type: Object,
|
||||
default: {
|
||||
welcome: {
|
||||
enabled: false,
|
||||
message: null,
|
||||
channel: null,
|
||||
withImage: null,
|
||||
},
|
||||
goodbye: {
|
||||
enabled: false,
|
||||
message: null,
|
||||
channel: null,
|
||||
withImage: null,
|
||||
},
|
||||
autorole: {
|
||||
enabled: false,
|
||||
role: null,
|
||||
},
|
||||
automod: {
|
||||
enabled: false,
|
||||
ignored: [],
|
||||
},
|
||||
warnsSanctions: {
|
||||
kick: null,
|
||||
ban: null,
|
||||
},
|
||||
monitoring: {
|
||||
messageUpdate: null,
|
||||
messageDelete: null,
|
||||
},
|
||||
tickets: {
|
||||
count: 0,
|
||||
ticketLogs: null,
|
||||
transcriptionLogs: null,
|
||||
ticketsCategory: null,
|
||||
},
|
||||
suggestions: null,
|
||||
reports: null,
|
||||
birthdays: null,
|
||||
modlogs: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
68
src/models/GuildModel.ts
Normal file
68
src/models/GuildModel.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import { model, Schema, Types, Document } from "mongoose";
|
||||
import useClient from "@/utils/use-client.js";
|
||||
|
||||
const client = useClient();
|
||||
|
||||
interface IGuildSchema extends Document {
|
||||
id: string;
|
||||
membersData: {
|
||||
[key: string]: any;
|
||||
};
|
||||
members: Types.ObjectId[];
|
||||
language: string;
|
||||
plugins: any;
|
||||
}
|
||||
|
||||
const GuildSchema = new Schema<IGuildSchema>({
|
||||
id: { type: String },
|
||||
|
||||
membersData: { type: Object, default: {} },
|
||||
members: [{ type: Schema.Types.ObjectId, ref: "Member" }],
|
||||
|
||||
language: { type: String, default: client.configService.get<string>("defaultLang") },
|
||||
plugins: {
|
||||
type: Object,
|
||||
default: {
|
||||
welcome: {
|
||||
enabled: false,
|
||||
message: null,
|
||||
channel: null,
|
||||
withImage: null,
|
||||
},
|
||||
goodbye: {
|
||||
enabled: false,
|
||||
message: null,
|
||||
channel: null,
|
||||
withImage: null,
|
||||
},
|
||||
autorole: {
|
||||
enabled: false,
|
||||
role: null,
|
||||
},
|
||||
automod: {
|
||||
enabled: false,
|
||||
ignored: [],
|
||||
},
|
||||
warnsSanctions: {
|
||||
kick: null,
|
||||
ban: null,
|
||||
},
|
||||
monitoring: {
|
||||
messageUpdate: null,
|
||||
messageDelete: null,
|
||||
},
|
||||
tickets: {
|
||||
count: 0,
|
||||
ticketLogs: null,
|
||||
transcriptionLogs: null,
|
||||
ticketsCategory: null,
|
||||
},
|
||||
suggestions: null,
|
||||
reports: null,
|
||||
birthdays: null,
|
||||
modlogs: null,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default model<IGuildSchema>("Guild", GuildSchema);
|
|
@ -1,36 +0,0 @@
|
|||
import { model, Schema } from "mongoose";
|
||||
|
||||
export default model(
|
||||
"Member",
|
||||
new Schema({
|
||||
id: { type: String },
|
||||
guildID: { type: String },
|
||||
|
||||
money: { type: Number, default: 0 },
|
||||
workStreak: { type: Number, default: 0 },
|
||||
bankSold: { type: Number, default: 0 },
|
||||
exp: { type: Number, default: 0 },
|
||||
level: { type: Number, default: 0 },
|
||||
transactions: { type: Array, default: [] },
|
||||
|
||||
registeredAt: { type: Number, default: Date.now() },
|
||||
|
||||
cooldowns: {
|
||||
type: Object,
|
||||
default: {
|
||||
work: 0,
|
||||
rob: 0,
|
||||
},
|
||||
},
|
||||
|
||||
sanctions: { type: Array, default: [] },
|
||||
mute: {
|
||||
type: Object,
|
||||
default: {
|
||||
muted: false,
|
||||
case: null,
|
||||
endDate: null,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
57
src/models/MemberModel.ts
Normal file
57
src/models/MemberModel.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { Schema, Document, model } from "mongoose";
|
||||
|
||||
interface IMemberSchema extends Document {
|
||||
id: string;
|
||||
guildID: string;
|
||||
money: number;
|
||||
workStreak: number;
|
||||
bankSold: number;
|
||||
exp: number;
|
||||
level: number;
|
||||
transactions: string[];
|
||||
registeredAt: number;
|
||||
cooldowns: {
|
||||
work: number;
|
||||
rob: number;
|
||||
};
|
||||
sanctions: string[];
|
||||
mute: {
|
||||
muted: boolean;
|
||||
case: string | null;
|
||||
endDate: number | null;
|
||||
};
|
||||
}
|
||||
|
||||
const memberSchema = new Schema<IMemberSchema>({
|
||||
id: { type: String },
|
||||
guildID: { type: String, ref: "Guild" },
|
||||
|
||||
money: { type: Number, default: 0 },
|
||||
workStreak: { type: Number, default: 0 },
|
||||
bankSold: { type: Number, default: 0 },
|
||||
exp: { type: Number, default: 0 },
|
||||
level: { type: Number, default: 0 },
|
||||
transactions: [String],
|
||||
|
||||
registeredAt: { type: Number, default: Date.now() },
|
||||
|
||||
cooldowns: {
|
||||
type: Object,
|
||||
default: {
|
||||
work: 0,
|
||||
rob: 0,
|
||||
},
|
||||
},
|
||||
|
||||
sanctions: [String],
|
||||
mute: {
|
||||
type: Object,
|
||||
default: {
|
||||
muted: false,
|
||||
case: null,
|
||||
endDate: null,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default model<IMemberSchema>("Member", memberSchema);
|
|
@ -1,6 +1,37 @@
|
|||
import { Schema, model } from "mongoose";
|
||||
import { Schema, model, Document } from "mongoose";
|
||||
import { createCanvas, loadImage } from "@napi-rs/canvas";
|
||||
|
||||
export type UserReminds = {
|
||||
message: string;
|
||||
createdAt: number;
|
||||
sendAt: number;
|
||||
};
|
||||
|
||||
interface IUserSchema extends Document {
|
||||
id: string;
|
||||
rep: number;
|
||||
bio: string;
|
||||
birthdate: number;
|
||||
lover: string;
|
||||
registeredAt: number;
|
||||
achievements: {
|
||||
[key: string]: {
|
||||
achieved: boolean;
|
||||
progress: {
|
||||
now: number;
|
||||
total: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
cooldowns: {
|
||||
rep: number;
|
||||
};
|
||||
afk: string;
|
||||
reminds: UserReminds[];
|
||||
logged: boolean;
|
||||
apiToken: string;
|
||||
}
|
||||
|
||||
const genToken = () => {
|
||||
let token = "";
|
||||
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwzy0123456789.-_";
|
||||
|
@ -9,7 +40,7 @@ const genToken = () => {
|
|||
return token;
|
||||
};
|
||||
|
||||
const userSchema = new Schema({
|
||||
const userSchema = new Schema<IUserSchema>({
|
||||
id: { type: String },
|
||||
|
||||
rep: { type: Number, default: 0 },
|
||||
|
@ -82,7 +113,16 @@ const userSchema = new Schema({
|
|||
},
|
||||
|
||||
afk: { type: String, default: null },
|
||||
reminds: { type: Array, default: [] },
|
||||
reminds: [
|
||||
{
|
||||
type: Object,
|
||||
default: {
|
||||
message: null,
|
||||
createdAt: null,
|
||||
sendAt: null,
|
||||
},
|
||||
},
|
||||
],
|
||||
logged: { type: Boolean, default: false },
|
||||
apiToken: { type: String, default: genToken() },
|
||||
});
|
||||
|
@ -110,4 +150,4 @@ userSchema.method("getAchievements", async function () {
|
|||
return await canvas.encode("png");
|
||||
});
|
||||
|
||||
export default model("User", userSchema);
|
||||
export default model<IUserSchema>("User", userSchema);
|
|
@ -1,28 +1,16 @@
|
|||
import fs from "fs";
|
||||
import { CONFIG_PATH } from "../../constants/index.js";
|
||||
import logger from "../../helpers/logger.js";
|
||||
import { CONFIG_PATH } from "@/constants/index.js";
|
||||
import logger from "@/helpers/logger.js";
|
||||
|
||||
class ConfigService {
|
||||
constructor() {
|
||||
this.config = this.#loadConfig();
|
||||
}
|
||||
config = this.loadConfig();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} key - key of the config
|
||||
* @returns {*} - value of the config
|
||||
*/
|
||||
get(key) {
|
||||
get<T>(key: string): T {
|
||||
const keys = key.split(".");
|
||||
return keys.reduce((config, k) => (config && config[k] !== undefined ? config[k] : undefined), this.config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a config value.
|
||||
* @param {string} key - key of the config to set
|
||||
* @param {*} value - value to set
|
||||
*/
|
||||
set(key, value) {
|
||||
set(key: string, value: unknown) {
|
||||
const keys = key.split(".");
|
||||
keys.reduce((config, k, i) => {
|
||||
if (i === keys.length - 1) {
|
||||
|
@ -32,14 +20,10 @@ class ConfigService {
|
|||
}
|
||||
return config[k];
|
||||
}, this.config);
|
||||
this.#saveConfig();
|
||||
this.saveConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the config from the file.
|
||||
* @returns {Config} - loaded config
|
||||
*/
|
||||
#loadConfig() {
|
||||
private loadConfig() {
|
||||
if (fs.existsSync(CONFIG_PATH)) {
|
||||
return JSON.parse(fs.readFileSync(CONFIG_PATH, "utf-8"));
|
||||
} else {
|
||||
|
@ -48,10 +32,7 @@ class ConfigService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the config to the file.
|
||||
*/
|
||||
#saveConfig() {
|
||||
private saveConfig() {
|
||||
try {
|
||||
fs.writeFileSync(CONFIG_PATH, JSON.stringify(this.config, null, 4), "utf-8");
|
||||
} catch (e) {
|
|
@ -1,10 +1,12 @@
|
|||
import { CronJob } from "cron";
|
||||
import logger from "../../helpers/logger.js";
|
||||
import { CronTaskData } from "@/types.js";
|
||||
|
||||
export class CronManager {
|
||||
constructor(tasks) {
|
||||
jobs = new Map<string, { job: CronJob; isRunning: boolean; isError: boolean }>();
|
||||
tasks: CronTaskData[];
|
||||
constructor(tasks: CronTaskData[]) {
|
||||
this.tasks = tasks;
|
||||
this.jobs = new Map();
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
@ -31,7 +33,7 @@ export class CronManager {
|
|||
await task.task();
|
||||
} catch (error) {
|
||||
logger.error(`Error executing cron task "${task.name}":`, error);
|
||||
this.jobs.get(task.name).isError = true;
|
||||
this.jobs.get(task.name)!.isError = true;
|
||||
}
|
||||
},
|
||||
null,
|
||||
|
@ -50,9 +52,8 @@ export class CronManager {
|
|||
}
|
||||
|
||||
stopAll() {
|
||||
if (!this.jobs.length) return;
|
||||
if (!this.jobs.size) return;
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
for (const [_, jobInfo] of this.jobs.entries()) {
|
||||
jobInfo.job.stop();
|
||||
}
|
|
@ -1,40 +1,50 @@
|
|||
import i18next from "i18next";
|
||||
import i18next, { TOptionsBase } from "i18next";
|
||||
import Backend from "i18next-fs-backend";
|
||||
import fs from "fs/promises";
|
||||
import { resolve, join } from "path";
|
||||
import logger from "../../helpers/logger.js";
|
||||
import logger from "@/helpers/logger.js";
|
||||
import supportedLanguages from "./language-meta.js";
|
||||
import { ExtendedClient } from "@/structures/client.js";
|
||||
|
||||
interface InternationalizationServiceOptions {
|
||||
defaultLanguage?: string;
|
||||
}
|
||||
|
||||
interface WalkDirectoryResult {
|
||||
namespaces: string[];
|
||||
languages: string[];
|
||||
}
|
||||
|
||||
export default class InternationalizationService {
|
||||
/**
|
||||
* Constructs an instance of the InternationalizationService.
|
||||
*
|
||||
* @param {import("../../structures/client").ExtendedClient} client - The client instance.
|
||||
* @param {Object} [options={}] - Optional configuration options.
|
||||
*/
|
||||
constructor(client, options = {}) {
|
||||
private client: ExtendedClient;
|
||||
private options: {
|
||||
localesPath: string;
|
||||
defaultLanguage: string;
|
||||
};
|
||||
|
||||
constructor(client: ExtendedClient, options: InternationalizationServiceOptions = {}) {
|
||||
this.client = client;
|
||||
this.options = {
|
||||
localesPath: resolve(this.client.configService.get("paths.locales")),
|
||||
defaultLanguage: options.defaultLanguage || "en-US",
|
||||
};
|
||||
this.i18next = this.#init();
|
||||
this.init();
|
||||
}
|
||||
|
||||
get getSupportedLanguages() {
|
||||
get getSupportedLanguages(): string[] {
|
||||
return supportedLanguages.map(lang => lang.locale);
|
||||
}
|
||||
|
||||
async #walkDirectory(dir, namespaces = [], folderName = "") {
|
||||
private async walkDirectory(dir: string, namespaces: string[] = [], folderName: string = ""): Promise<WalkDirectoryResult> {
|
||||
const files = await fs.readdir(dir, { withFileTypes: true });
|
||||
|
||||
const languages = [];
|
||||
const languages: string[] = [];
|
||||
for (const file of files) {
|
||||
if (file.isDirectory()) {
|
||||
const isLanguage = file.name.includes("-");
|
||||
if (isLanguage) languages.push(file.name);
|
||||
|
||||
const folder = await this.#walkDirectory(join(dir, file.name), namespaces, isLanguage ? "" : `${file.name}/`);
|
||||
const folder = await this.walkDirectory(join(dir, file.name), namespaces, isLanguage ? "" : `${file.name}/`);
|
||||
|
||||
namespaces = folder.namespaces;
|
||||
} else {
|
||||
|
@ -44,10 +54,10 @@ export default class InternationalizationService {
|
|||
return { namespaces: [...new Set(namespaces)], languages };
|
||||
}
|
||||
|
||||
async #init() {
|
||||
const { namespaces, languages } = await this.#walkDirectory(this.options.localesPath);
|
||||
private async init() {
|
||||
const { namespaces, languages } = await this.walkDirectory(this.options.localesPath);
|
||||
|
||||
const i18n = await i18next.use(Backend).init({
|
||||
const i18nInstance = await i18next.use(Backend).init({
|
||||
backend: {
|
||||
loadPath: resolve(this.options.localesPath, "./{{lng}}/{{ns}}.json"),
|
||||
},
|
||||
|
@ -61,13 +71,14 @@ export default class InternationalizationService {
|
|||
initImmediate: false,
|
||||
});
|
||||
|
||||
this.client.translate = (key, options = {}) => {
|
||||
// Типизированная функция translate
|
||||
this.client.translate = (key: string, options: TOptionsBase = {}): string => {
|
||||
const lng = options.lng || this.options.defaultLanguage;
|
||||
return i18next.t(key, { lng, ...options });
|
||||
};
|
||||
|
||||
logger.log("Internationalization initialized");
|
||||
|
||||
return i18n;
|
||||
return i18nInstance;
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
import { Client } from "discord.js";
|
||||
import { Player } from "discord-player";
|
||||
import MongooseAdapter from "../adapters/database/MongooseAdapter.js";
|
||||
import logger from "../helpers/logger.js";
|
||||
import { Handlers } from "../handlers/index.js";
|
||||
import ConfigService from "../services/config/index.js";
|
||||
import InternationalizationService from "../services/languages/index.js";
|
||||
import { SUPER_CONTEXT } from "../constants/index.js";
|
||||
|
||||
export class ExtendedClient extends Client {
|
||||
/**
|
||||
* @param {import("discord.js").ClientOptions} options
|
||||
*/
|
||||
constructor(options) {
|
||||
if (SUPER_CONTEXT.getStore()) {
|
||||
return SUPER_CONTEXT.getStore();
|
||||
}
|
||||
super(options);
|
||||
|
||||
this.configService = new ConfigService();
|
||||
this.adapter = new MongooseAdapter(this.configService.get("mongoDB"));
|
||||
this.i18n = new InternationalizationService(this);
|
||||
this.cacheReminds = new Map();
|
||||
new Player(this);
|
||||
new Handlers(this);
|
||||
|
||||
SUPER_CONTEXT.enterWith(this);
|
||||
}
|
||||
|
||||
async init() {
|
||||
try {
|
||||
await this.adapter.connect();
|
||||
|
||||
await this.login(this.configService.get("token"));
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a guild data object from the database.
|
||||
* @param {string} guildId - The ID of the guild to find or create.
|
||||
* @returns {Promise<GuildModel>} The guild data object, either retrieved from the database or newly created.
|
||||
*/
|
||||
async getGuildData(guildId) {
|
||||
const { default: GuildModel } = await import("../models/GuildModel.js");
|
||||
let guildData = await this.adapter.findOne(GuildModel, { id: guildId });
|
||||
|
||||
if (!guildData) {
|
||||
guildData = new GuildModel({ id: guildId });
|
||||
await guildData.save();
|
||||
}
|
||||
|
||||
return guildData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a User data from the database.
|
||||
* @param {string} userID - The ID of the user to find or create.
|
||||
* @returns {Promise<UserModel>} The user data object, either retrieved from the database or newly created.
|
||||
*/
|
||||
async getUserData(userID) {
|
||||
const { default: UserModel } = await import("../models/UserModel.js");
|
||||
let userData = await this.adapter.findOne(UserModel, { id: userID });
|
||||
|
||||
if (!userData) {
|
||||
userData = new UserModel({ id: userID });
|
||||
await userData.save();
|
||||
}
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Member data from the database.
|
||||
* @param {string} memberId - The ID of the member to find or create.
|
||||
* @param {string} guildId - The ID of the guild the member belongs to.
|
||||
* @returns {Promise<MemberModel>} The member data object, either retrieved from the database or newly created.
|
||||
*/
|
||||
async getMemberData(memberId, guildId) {
|
||||
const { default: MemberModel } = await import("../models/MemberModel.js");
|
||||
let memberData = await this.adapter.findOne(MemberModel, { guildID: guildId, id: memberId });
|
||||
|
||||
if (!memberData) {
|
||||
memberData = new MemberModel({ id: memberId, guildID: guildId });
|
||||
await memberData.save();
|
||||
|
||||
const guildData = await this.getGuildData(guildId);
|
||||
|
||||
if (guildData) {
|
||||
guildData.members.push(memberData._id);
|
||||
await guildData.save();
|
||||
}
|
||||
}
|
||||
|
||||
return memberData;
|
||||
}
|
||||
}
|
69
src/structures/client.ts
Normal file
69
src/structures/client.ts
Normal file
|
@ -0,0 +1,69 @@
|
|||
import { Client, ClientOptions } from "discord.js";
|
||||
import { TOptionsBase } from "i18next";
|
||||
import { Handlers } from "@/handlers/index.js";
|
||||
import MongooseAdapter from "@/adapters/database/MongooseAdapter.js";
|
||||
import logger from "@/helpers/logger.js";
|
||||
import ConfigService from "@/services/config/index.js";
|
||||
import InternationalizationService from "@/services/languages/index.js";
|
||||
import { SUPER_CONTEXT } from "@/constants/index.js";
|
||||
import { cacheRemindsData } from "@/types.js";
|
||||
|
||||
export class ExtendedClient extends Client<true> {
|
||||
configService = new ConfigService();
|
||||
adapter = new MongooseAdapter(this.configService.get("mongoDB"));
|
||||
cacheReminds = new Map<string, cacheRemindsData>();
|
||||
i18n = new InternationalizationService(this);
|
||||
translate!: (
|
||||
_key: string,
|
||||
_options?:
|
||||
| TOptionsBase
|
||||
| {
|
||||
[key: string]: string;
|
||||
},
|
||||
) => string;
|
||||
|
||||
constructor(options: ClientOptions) {
|
||||
if (SUPER_CONTEXT.getStore()) {
|
||||
return SUPER_CONTEXT.getStore() as ExtendedClient;
|
||||
}
|
||||
super(options);
|
||||
|
||||
new Handlers(this);
|
||||
SUPER_CONTEXT.enterWith(this);
|
||||
}
|
||||
|
||||
async init() {
|
||||
try {
|
||||
await this.adapter.connect();
|
||||
await this.login(this.configService.get("token"));
|
||||
} catch (error) {
|
||||
logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
async getGuildData(guildId: string) {
|
||||
const { default: GuildModel } = await import("@/models/GuildModel.js");
|
||||
const guildData = await this.adapter.findOneOrCreate(GuildModel, { id: guildId });
|
||||
|
||||
return guildData;
|
||||
}
|
||||
|
||||
async getUserData(userID: string) {
|
||||
const { default: UserModel } = await import("@/models/UserModel.js");
|
||||
const userData = await this.adapter.findOneOrCreate(UserModel, { id: userID });
|
||||
|
||||
return userData;
|
||||
}
|
||||
|
||||
async getMemberData(memberId: string, guildID: string) {
|
||||
const { default: MemberModel } = await import("@/models/MemberModel.js");
|
||||
const memberData = await this.adapter.findOneOrCreate(MemberModel, { id: memberId, guildID });
|
||||
|
||||
const guildData = await this.getGuildData(guildID);
|
||||
|
||||
guildData.members.push(memberData.id);
|
||||
await guildData.save();
|
||||
|
||||
return memberData;
|
||||
}
|
||||
}
|
53
src/types.d.ts
vendored
Normal file
53
src/types.d.ts
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
import {
|
||||
AutocompleteInteraction,
|
||||
CacheType,
|
||||
ChatInputCommandInteraction,
|
||||
ContextMenuCommandInteraction,
|
||||
Interaction,
|
||||
MessageContextMenuCommandInteraction,
|
||||
PermissionsString,
|
||||
RESTPostAPIApplicationCommandsJSONBody,
|
||||
UserContextMenuCommandInteraction,
|
||||
} from "discord.js";
|
||||
import { ExtendedClient } from "./structures/client.ts";
|
||||
import { UserReminds } from "./models/UserModel.ts";
|
||||
|
||||
export type CommandData = RESTPostAPIApplicationCommandsJSONBody;
|
||||
|
||||
export type cacheRemindsData = {
|
||||
id: string;
|
||||
reminds: UserReminds[];
|
||||
};
|
||||
|
||||
export type CronTaskData = {
|
||||
name: string;
|
||||
schedule: string;
|
||||
task: () => Promise<void> | void;
|
||||
};
|
||||
|
||||
export interface CommandProps {
|
||||
interaction: ChatInputCommandInteraction | ContextMenuCommandInteraction | UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction | AutocompleteInteraction;
|
||||
client: ExtendedClient;
|
||||
}
|
||||
|
||||
export interface SlashCommandProps extends CommandProps {
|
||||
interaction: ChatInputCommandInteraction;
|
||||
}
|
||||
|
||||
export interface CommandContext<_T extends Interaction, _Cached extends CacheType> {
|
||||
interaction: Interaction<CacheType>;
|
||||
client: ExtendedClient;
|
||||
}
|
||||
|
||||
export interface CommandOptions {
|
||||
devOnly?: boolean;
|
||||
userPermissions?: PermissionsString | PermissionsString[];
|
||||
botPermissions?: PermissionsString | PermissionsString[];
|
||||
}
|
||||
|
||||
export interface CommandFileObject {
|
||||
data: CommandData;
|
||||
options?: CommandOptions;
|
||||
run: <Cached extends CacheType = CacheType>(_ctx: CommandContext<Interaction, Cached>) => Awaited<void>;
|
||||
autocompleteRun?: <Cached extends CacheType = CacheType>(_ctx: CommandContext<Interaction, Cached>) => Awaited<void>;
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import { EmbedBuilder } from "discord.js";
|
||||
import useClient from "../utils/use-client.js";
|
||||
/**
|
||||
*
|
||||
* @param {import("discord.js").EmbedData} data - embed data
|
||||
* @returns The generated EmbedBuilder instance.
|
||||
*/
|
||||
export const createEmbed = data => {
|
||||
const client = useClient();
|
||||
return new EmbedBuilder({
|
||||
footer: typeof data.footer === "object" ? data.footer : data.footer ? { text: data.footer } : client.configService.get("embed.footer"),
|
||||
...data,
|
||||
}).setColor(data.color ?? client.configService.get("embed.color"));
|
||||
};
|
10
src/utils/create-embed.ts
Normal file
10
src/utils/create-embed.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { EmbedBuilder, EmbedData } from "discord.js";
|
||||
import useClient from "./use-client.js";
|
||||
|
||||
export const createEmbed = (data: EmbedData) => {
|
||||
const client = useClient();
|
||||
return new EmbedBuilder({
|
||||
footer: typeof data.footer === "object" ? data.footer : data.footer ? { text: data.footer } : client.configService.get("embed.footer"),
|
||||
...data,
|
||||
}).setColor(data.color || client.configService.get("embed.color"));
|
||||
};
|
|
@ -1,11 +1,9 @@
|
|||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { PROJECT_ROOT } from "../constants/index.js";
|
||||
import { PROJECT_ROOT } from "@/constants/index.js";
|
||||
|
||||
export const getFilePaths = async (directory, nesting) => {
|
||||
let filePaths = [];
|
||||
|
||||
if (!directory) return;
|
||||
export const getFilePaths = async (directory: string, nesting: boolean) => {
|
||||
let filePaths: string[] = [];
|
||||
|
||||
const absoluteDirectory = path.isAbsolute(directory) ? directory : path.join(PROJECT_ROOT, directory);
|
||||
|
||||
|
@ -19,7 +17,8 @@ export const getFilePaths = async (directory, nesting) => {
|
|||
}
|
||||
|
||||
if (nesting && file.isDirectory()) {
|
||||
filePaths = [...filePaths, ...(await getFilePaths(filePath, true))];
|
||||
const nestedFiles = await getFilePaths(filePath, true);
|
||||
filePaths = [...filePaths, ...nestedFiles];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
export * from "./create-embed.js";
|
||||
export * from "./get-path.js";
|
||||
export * from "./resolve-file.js";
|
|
@ -1,15 +1,16 @@
|
|||
import { CronTaskData } from "@/types.js";
|
||||
import logger from "../helpers/logger.js";
|
||||
import { getFilePaths } from "./get-path.js";
|
||||
import { toFileURL } from "./resolve-file.js";
|
||||
|
||||
const loadCronTasks = async taskPath => {
|
||||
const loadCronTasks = async (taskPath: string): Promise<CronTaskData[]> => {
|
||||
try {
|
||||
const filePaths = (await getFilePaths(taskPath, true)).filter(file => file.endsWith(".js"));
|
||||
const filePaths = (await getFilePaths(taskPath, true)).filter(file => file.endsWith(".js") || file.endsWith(".ts"));
|
||||
|
||||
const tasks = [];
|
||||
|
||||
for (const filePath of filePaths) {
|
||||
const { data } = await import(toFileURL(filePath));
|
||||
const { data } = (await import(toFileURL(filePath))) as { data: CronTaskData };
|
||||
|
||||
if (!data) continue;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import path from "node:path";
|
||||
import { PROJECT_ROOT } from "../constants/index.js";
|
||||
|
||||
/**
|
||||
* Convert a local file path to a file URL.
|
||||
* @param {string} filePath - local file's path.
|
||||
* @returns {string} file URL
|
||||
*/
|
||||
export const toFileURL = filePath => {
|
||||
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(PROJECT_ROOT, filePath);
|
||||
return "file://" + resolvedPath.replace(/\\\\|\\/g, "/");
|
||||
};
|
7
src/utils/resolve-file.ts
Normal file
7
src/utils/resolve-file.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import path from "node:path";
|
||||
import { PROJECT_ROOT } from "@/constants/index.js";
|
||||
|
||||
export const toFileURL = (filePath: string) => {
|
||||
const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(PROJECT_ROOT, filePath);
|
||||
return "file://" + resolvedPath.replace(/\\\\|\\/g, "/");
|
||||
};
|
|
@ -1,16 +0,0 @@
|
|||
import { SUPER_CONTEXT } from "../constants/index.js";
|
||||
|
||||
/**
|
||||
* Returns the instance of the client.
|
||||
*
|
||||
* @throws {Error} Client is not initialized. Please initialize it first.
|
||||
*
|
||||
* @returns {import("../structures/client.js").ExtendedClient} The client instance.
|
||||
*/
|
||||
export default function useClient() {
|
||||
const store = SUPER_CONTEXT.getStore();
|
||||
if (!store) {
|
||||
throw new Error("Client is not initialized. Please initialize it first.");
|
||||
}
|
||||
return store;
|
||||
}
|
9
src/utils/use-client.ts
Normal file
9
src/utils/use-client.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { SUPER_CONTEXT } from "@/constants/index.js";
|
||||
|
||||
export default function useClient() {
|
||||
const store = SUPER_CONTEXT.getStore();
|
||||
if (!store) {
|
||||
throw new Error("Client is not initialized. Please initialize it first.");
|
||||
}
|
||||
return store;
|
||||
}
|
24
tsconfig.json
Normal file
24
tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022", // Версия ECMAScript
|
||||
"module": "NodeNext", // Использование ES-модулей
|
||||
"moduleResolution": "nodenext", // Разрешение модулей
|
||||
"outDir": "./dist", // Директория для скомпилированных файлов
|
||||
"rootDir": "./src", // Директория с исходным кодом
|
||||
"strict": true, // Включение строгой проверки типов
|
||||
"esModuleInterop": true, // Для совместимости с CommonJS
|
||||
"skipLibCheck": true, // Пропуск проверки типов в библиотеках
|
||||
"forceConsistentCasingInFileNames": true, // Единообразие в именах файлов
|
||||
"resolveJsonModule": true, // Разрешение импорта JSON-файлов
|
||||
"isolatedModules": true, // Изолированные модули
|
||||
"incremental": true, // Инкрементальная сборка (ускоряет повторную компиляцию, сохраняя результаты предыдущих компиляции)
|
||||
"noEmitOnError": true, // Чтобы не билдил без ошибок
|
||||
"noUnusedLocals": true, // Не использовать неиспользуемые локальные переменные
|
||||
"noUnusedParameters": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"], // Включаемые файлы
|
||||
"exclude": ["node_modules"] // Исключаемые файлы
|
||||
}
|
Loading…
Reference in a new issue