mirror of
https://github.com/ReVanced/revanced-bots.git
synced 2026-01-12 06:06:21 +00:00
Compare commits
40 Commits
@revanced/
...
@revanced/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8168f79ac6 | ||
|
|
38c06997b4 | ||
|
|
cdb6001955 | ||
|
|
e748a4da92 | ||
|
|
300e5cff3b | ||
|
|
6685ffb855 | ||
|
|
cbf91162e2 | ||
|
|
bd906fbf54 | ||
|
|
27662ed91a | ||
|
|
d0acab1915 | ||
|
|
e86180fe29 | ||
|
|
1f5c5a92a6 | ||
|
|
b79a1c7575 | ||
|
|
3559ed1cb5 | ||
|
|
042b155b5e | ||
|
|
673aa189be | ||
|
|
c503a86c53 | ||
|
|
1bd973ea6c | ||
|
|
4bb965e9ff | ||
|
|
a8ceeb29ae | ||
|
|
96a6540434 | ||
|
|
e02c86a9c4 | ||
|
|
e82f2ab34b | ||
|
|
2a6f3c3013 | ||
|
|
875bd209b2 | ||
|
|
2b601b1a1d | ||
|
|
164570d176 | ||
|
|
0d4898dae8 | ||
|
|
38e00eb4e5 | ||
|
|
3117af5497 | ||
|
|
6a87464b40 | ||
|
|
5db076aee5 | ||
|
|
12f5aaf70f | ||
|
|
94d0dcc32b | ||
|
|
4834685186 | ||
|
|
ffe0a3ddf5 | ||
|
|
89d8ab1ee5 | ||
|
|
f142c2b82e | ||
|
|
7dfbf6c92c | ||
|
|
55631b220f |
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
@@ -14,6 +14,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
# @revanced/bot-websocket-api [1.0.0-dev.5](https://github.com/revanced/revanced-helper/compare/@revanced/bot-websocket-api@1.0.0-dev.4...@revanced/bot-websocket-api@1.0.0-dev.5) (2024-07-23)
|
||||
|
||||
# @revanced/bot-websocket-api [1.0.0-dev.4](https://github.com/revanced/revanced-helper/compare/@revanced/bot-websocket-api@1.0.0-dev.3...@revanced/bot-websocket-api@1.0.0-dev.4) (2024-07-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **apis/websocket:** hardcoded paths in tesseract worker builds ([38e00eb](https://github.com/revanced/revanced-helper/commit/38e00eb4e59c763bd74d27b9b9b482ea66e4dcf4))
|
||||
|
||||
# @revanced/bot-websocket-api [1.0.0-dev.3](https://github.com/revanced/revanced-helper/compare/@revanced/bot-websocket-api@1.0.0-dev.2...@revanced/bot-websocket-api@1.0.0-dev.3) (2024-07-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **apis/websocket:** build and runtime issues ([89d8ab1](https://github.com/revanced/revanced-helper/commit/89d8ab1ee58278a9a96cdc31c679d0a0a0d865af))
|
||||
|
||||
# @revanced/bot-websocket-api [1.0.0-dev.2](https://github.com/revanced/revanced-helper/compare/@revanced/bot-websocket-api@1.0.0-dev.1...@revanced/bot-websocket-api@1.0.0-dev.2) (2024-07-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **apis/websocket:** also include tesseract core files in build ([7dfbf6c](https://github.com/revanced/revanced-helper/commit/7dfbf6c92c49100954fa4aca471dce4ab9fd9565))
|
||||
|
||||
# @revanced/bot-websocket-api 1.0.0-dev.1 (2024-07-22)
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ FROM base AS build
|
||||
WORKDIR /build
|
||||
COPY . .
|
||||
RUN bun install --frozen-lockfile
|
||||
RUN cd apis/websocket && bun --bun run build
|
||||
RUN cd apis/websocket && bun run build
|
||||
|
||||
FROM base AS release
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "@revanced/bot-websocket-api",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"version": "1.0.0-dev.1",
|
||||
"version": "1.0.0-dev.5",
|
||||
"description": "🧦 WebSocket API server for bots assisting ReVanced",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,23 +1,34 @@
|
||||
import { createLogger } from '@revanced/bot-shared'
|
||||
import { cp } from 'fs/promises'
|
||||
import { cp, rm } from 'fs/promises'
|
||||
|
||||
async function build(): Promise<void> {
|
||||
const logger = createLogger()
|
||||
const logger = createLogger()
|
||||
|
||||
logger.info('Building Tesseract.js worker...')
|
||||
await Bun.build({
|
||||
entrypoints: ['../../node_modules/tesseract.js/src/worker-script/node/index.js'],
|
||||
target: 'bun',
|
||||
outdir: './dist/worker',
|
||||
})
|
||||
logger.info('Cleaning previous build...')
|
||||
await rm('./dist', { recursive: true })
|
||||
|
||||
logger.info('Building WebSocket API...')
|
||||
await Bun.build({
|
||||
entrypoints: ['./src/index.ts'],
|
||||
outdir: './dist',
|
||||
target: 'bun',
|
||||
})
|
||||
}
|
||||
logger.info('Building WebSocket API...')
|
||||
await Bun.build({
|
||||
entrypoints: ['./src/index.ts'],
|
||||
outdir: './dist',
|
||||
target: 'bun',
|
||||
minify: true,
|
||||
sourcemap: 'external',
|
||||
})
|
||||
|
||||
await build()
|
||||
logger.info('Building Tesseract.js worker...')
|
||||
await Bun.build({
|
||||
entrypoints: ['../../node_modules/tesseract.js/src/worker-script/node/index.js'],
|
||||
external: ['tesseract.js-core/*'],
|
||||
target: 'bun',
|
||||
outdir: './dist/worker',
|
||||
minify: true,
|
||||
sourcemap: 'external',
|
||||
})
|
||||
|
||||
// Tesseract.js is really bad for minification
|
||||
// It forcefully requires this core module to be present which contains the WASM files
|
||||
logger.info('Copying Tesseract.js Core...')
|
||||
await cp('../../node_modules/tesseract.js-core', './dist/node_modules/tesseract.js-core', { recursive: true })
|
||||
|
||||
logger.info('Copying config...')
|
||||
await cp('config.json', 'dist/config.json')
|
||||
|
||||
@@ -53,11 +53,11 @@ export interface WitMessageResponse {
|
||||
}>
|
||||
}
|
||||
|
||||
const TesseractWorkerPath = joinPath(import.meta.dir, 'worker', 'index.js')
|
||||
const TesseractCompiledWorkerExists = await pathExists(TesseractWorkerPath)
|
||||
const TesseractWorkerDirPath = joinPath(import.meta.dir, 'worker')
|
||||
const TesseractWorkerPath = joinPath(TesseractWorkerDirPath, 'index.js')
|
||||
|
||||
export const tesseract = await createTesseractWorker(
|
||||
'eng',
|
||||
OEM.DEFAULT,
|
||||
TesseractCompiledWorkerExists ? { workerPath: TesseractWorkerPath } : undefined,
|
||||
(await pathExists(TesseractWorkerDirPath)) ? { workerPath: TesseractWorkerPath } : undefined,
|
||||
)
|
||||
|
||||
1
bots/discord/.gitignore
vendored
1
bots/discord/.gitignore
vendored
@@ -181,6 +181,7 @@ config.ts
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
.drizzle
|
||||
|
||||
# Auto-generated files
|
||||
src/commands/index.ts
|
||||
|
||||
151
bots/discord/CHANGELOG.md
Normal file
151
bots/discord/CHANGELOG.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# @revanced/discord-bot [1.0.0-dev.8](https://github.com/revanced/revanced-helper/compare/@revanced/discord-bot@1.0.0-dev.7...@revanced/discord-bot@1.0.0-dev.8) (2024-07-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bots/discord:** cross-device link build errors ([38c0699](https://github.com/revanced/revanced-helper/commit/38c06997b4d0f7bb3f1e62618a5e3f088c522e30))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bots/discord:** blacklist and whitelist for filters ([cdb6001](https://github.com/revanced/revanced-helper/commit/cdb600195520dba33110c40841629259e317055e))
|
||||
|
||||
# @revanced/discord-bot [1.0.0-dev.7](https://github.com/revanced/revanced-helper/compare/@revanced/discord-bot@1.0.0-dev.6...@revanced/discord-bot@1.0.0-dev.7) (2024-07-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bot/discord:** start remove preset timeout for `role-preset` command ([cbf9116](https://github.com/revanced/revanced-helper/commit/cbf91162e27dd4c1ecb976927ab708f1d882abca))
|
||||
* **bots/discord:** only check for member permissions when specified while correcting responses ([b79a1c7](https://github.com/revanced/revanced-helper/commit/b79a1c7575e94c3e62654c87775cac497be4a50a))
|
||||
* **bots/discord:** set timeout for eligible mutes to unmute faster ([1f5c5a9](https://github.com/revanced/revanced-helper/commit/1f5c5a92a639973b83a1204355538936e69a4454))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bots/discord:** add `replyToReplied` option in response config ([27662ed](https://github.com/revanced/revanced-helper/commit/27662ed91a79bfac7d3f091834e859a7b57366ce))
|
||||
|
||||
# @revanced/discord-bot [1.0.0-dev.6](https://github.com/revanced/revanced-helper/compare/@revanced/discord-bot@1.0.0-dev.5...@revanced/discord-bot@1.0.0-dev.6) (2024-07-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bots/discord:** ci issues causing database to not be auto generated ([673aa18](https://github.com/revanced/revanced-helper/commit/673aa189bef1009a3e32ba3b1291a5ee84f2def3))
|
||||
|
||||
# @revanced/discord-bot [1.0.0-dev.5](https://github.com/revanced/revanced-helper/compare/@revanced/discord-bot@1.0.0-dev.4...@revanced/discord-bot@1.0.0-dev.5) (2024-07-23)
|
||||
|
||||
# @revanced/discord-bot [1.0.0-dev.4](https://github.com/revanced/revanced-helper/compare/@revanced/discord-bot@1.0.0-dev.3...@revanced/discord-bot@1.0.0-dev.4) (2024-07-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bots/discord:** wrong database schema path ([875bd20](https://github.com/revanced/revanced-helper/commit/875bd209b252566414bf89349839cabc01697e1c))
|
||||
|
||||
# @revanced/discord-bot [1.0.0-dev.3](https://github.com/revanced/revanced-helper/compare/@revanced/discord-bot@1.0.0-dev.2...@revanced/discord-bot@1.0.0-dev.3) (2024-07-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bots/discord:** revert dist denesting, fixes config not found ([0d4898d](https://github.com/revanced/revanced-helper/commit/0d4898dae8b26f8466d3f6b8f62875866f581644))
|
||||
|
||||
# @revanced/discord-bot [1.0.0-dev.2](https://github.com/revanced/revanced-helper/compare/@revanced/discord-bot@1.0.0-dev.1...@revanced/discord-bot@1.0.0-dev.2) (2024-07-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **bots/discord:** don't nest builds in src directory, autogen db when missing ([4834685](https://github.com/revanced/revanced-helper/commit/48346851864c4d4b6276388644dd24ce16222b3e))
|
||||
|
||||
# @revanced/discord-bot 1.0.0-dev.1 (2024-07-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bots/discord/commands/mute:** use existing `parseDuration` util function' ([3e07429](https://github.com/revanced/revanced-helper/commit/3e07429664f7dbb6ce653083e0adb1a232737fde))
|
||||
* **bots/discord/commands/unmute:** fix option description and embeds ([7fdf8c0](https://github.com/revanced/revanced-helper/commit/7fdf8c0dc722e21fe5a3ad6ef8d3a306ef85f532))
|
||||
* **bots/discord/commands:** minor issues ([3b2596e](https://github.com/revanced/revanced-helper/commit/3b2596e748cf2cde1500ef2ded55f0faabc2c272))
|
||||
* **bots/discord/commands:** refactor and add checks ([a2bf3ea](https://github.com/revanced/revanced-helper/commit/a2bf3eade99b46f9ffb55d45b8caf1bcf3d22a9b))
|
||||
* **bots/discord/database:** fix schema for role presets ([4aa138a](https://github.com/revanced/revanced-helper/commit/4aa138a9af8db7093ef637470fcfdea1f5341236))
|
||||
* **bots/discord/scripts:** unintentional escaping on windows ([09dc706](https://github.com/revanced/revanced-helper/commit/09dc70632da0597fdb26677acee3f6fccbb2b9b5))
|
||||
* **bots/discord/utils/discord/embeds:** set thumbnail on moderation embeds ([b056291](https://github.com/revanced/revanced-helper/commit/b056291ad0f2e2eac5eec8aa71f15dbc769aa0f9))
|
||||
* **bots/discord/utils/discord/rolePresets:** correct property access for presets ([4c6ad11](https://github.com/revanced/revanced-helper/commit/4c6ad11be30c1d6af97c4ae40fc62d05fa7bdd57))
|
||||
* **bots/discord/utils/discord:** add `moderation` module related functions ([7e8270f](https://github.com/revanced/revanced-helper/commit/7e8270f7d260322e1950e058b221ab088bd595d0))
|
||||
* **bots/discord/utils/duration:** fix empty string returning with duration is 0 ([83c314e](https://github.com/revanced/revanced-helper/commit/83c314ef5f721abc355272db0e4c182dcfe5d943))
|
||||
* **bots/discord:** apply active role presets if members rejoin ([f50b26b](https://github.com/revanced/revanced-helper/commit/f50b26b82d66c88fd1dbb8c07d77c177c0e781df))
|
||||
* **bots/discord:** check token before connecting to bot api ([f3e4408](https://github.com/revanced/revanced-helper/commit/f3e4408aa28fb6a9d21365af8c1bea3d07b481de))
|
||||
* **bots/discord:** clear role presets after they expire ([faa81f4](https://github.com/revanced/revanced-helper/commit/faa81f4d887eaeae809651f5b68187d033a260f2))
|
||||
* **bots/discord:** connect to discord API even if initial bot API connection fails ([6658b58](https://github.com/revanced/revanced-helper/commit/6658b582dbeba7e072a7a04c4efa255e7f634aef))
|
||||
* **bots/discord:** do decancer after resetting nickname ([0303fe3](https://github.com/revanced/revanced-helper/commit/0303fe3e367c07e92f831365d5548ca5b03435b2))
|
||||
* **bots/discord:** follow-up if reply is already sent when error ([f75060b](https://github.com/revanced/revanced-helper/commit/f75060bc9cda44902cf872def73c116a6df039d7))
|
||||
* **bots/discord:** messed up file name for `unmute` command ([399dca7](https://github.com/revanced/revanced-helper/commit/399dca71538fe5c8831977694a97058254a17578))
|
||||
* **bots/discord:** owners cannot bypass checks on some commands ([39cba97](https://github.com/revanced/revanced-helper/commit/39cba973418027ba6ed67e1ae5ab5c6458807562))
|
||||
* **bots/discord:** remove auto-generated files ([fb8af00](https://github.com/revanced/revanced-helper/commit/fb8af008661bf37389e01cba19d64a8b4fc82139))
|
||||
* **bots/discord:** remove usage of macros ([7f27c56](https://github.com/revanced/revanced-helper/commit/7f27c5607ceeeef56d67097e88f68caa1b8791b3))
|
||||
* **bots/discord:** remove useless feature ([d830e48](https://github.com/revanced/revanced-helper/commit/d830e48bc2de7aa457eab3a5f96ae652a93178f9))
|
||||
* **bots/discord:** use `APIEmbed` for response config ([35b9448](https://github.com/revanced/revanced-helper/commit/35b944800a3943c187d5b0e0d3e465ad7d2056fe))
|
||||
* **bots/discord:** use env for initializing database ([af3759c](https://github.com/revanced/revanced-helper/commit/af3759caf428fada3b3f4a51852543d6fb280018))
|
||||
* **bots/discord:** wrong command file path being imported ([fa0159c](https://github.com/revanced/revanced-helper/commit/fa0159c3a8dd4dad8778ccdb75b9e7c02ebbb64f))
|
||||
* config file not being read ([474a8be](https://github.com/revanced/revanced-helper/commit/474a8be4af4eb2bae6e80a893439d846ad4f7503))
|
||||
* **discord-bot:** also execute slash commands ([f0d45b2](https://github.com/revanced/revanced-helper/commit/f0d45b2c926ed753e2d21f2e06e24d7e6c43880a))
|
||||
* **discord-bot:** check for role position ([d332043](https://github.com/revanced/revanced-helper/commit/d332043b1a4bb7ac9698a2fc912832e184130b4b))
|
||||
* **discord-bot:** check if the member has the role ([9bff68c](https://github.com/revanced/revanced-helper/commit/9bff68c8c40c692764e4dec15a058e35059efbc9))
|
||||
* **discord-bot:** not executing slash commands ([aa08087](https://github.com/revanced/revanced-helper/commit/aa0808768b90844c5fbd3e75d9f2d01c723b0151))
|
||||
* **discord-bot:** only send lowercased text ([7803758](https://github.com/revanced/revanced-helper/commit/78037580dc92883f5ca21157e45268850cb5db90))
|
||||
* dislike button not working properly ([85eba55](https://github.com/revanced/revanced-helper/commit/85eba554247738066af72a8efd0de215ec1164dc))
|
||||
* fix deprecation ([4373ede](https://github.com/revanced/revanced-helper/commit/4373ede855333f209676551162a525238656e1f8))
|
||||
* fix the fiter for the interaction collector ([a9ff003](https://github.com/revanced/revanced-helper/commit/a9ff00394a73f68a6793c2b35ff184675ee5a72c))
|
||||
* ignore message if there's no content ([3cbebc2](https://github.com/revanced/revanced-helper/commit/3cbebc284277808495e64cf0fb47c555924ad9c5))
|
||||
* move modules to `/bots` ([cd7156e](https://github.com/revanced/revanced-helper/commit/cd7156e792e65777ad1ab5a6f5d828b9ef6a9754))
|
||||
* trainAI not using the bin location ([bd29943](https://github.com/revanced/revanced-helper/commit/bd2994388bc65f720120ef49edb6ba8163260309))
|
||||
|
||||
|
||||
### chore
|
||||
|
||||
* fix more build issues ([77fefb9](https://github.com/revanced/revanced-helper/commit/77fefb9bef286a22f40a4d76b79c64fcc5a2467f))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add wit.ai support ([1909e2c](https://github.com/revanced/revanced-helper/commit/1909e2c42148d635dcd045c738d88f65c8be16e3))
|
||||
* **bots/discord/commands/reply:** send stacktrace when failed ([9f1ac37](https://github.com/revanced/revanced-helper/commit/9f1ac379276c11da65235577a9c6717e01cb02eb))
|
||||
* **bots/discord/commands:** add `ban` and `unban` commands ([dc4863d](https://github.com/revanced/revanced-helper/commit/dc4863dc208b3fede4d4def323306ab58daffe04))
|
||||
* **bots/discord/commands:** add `eval` command ([e64d1da](https://github.com/revanced/revanced-helper/commit/e64d1da00cc2ba718da5a4b0da141fe86a0e48d2))
|
||||
* **bots/discord/commands:** add `mute` and `unmute` commands ([c0fa2fe](https://github.com/revanced/revanced-helper/commit/c0fa2fe1c36acdc7c52cde277aa7da867065f55e))
|
||||
* **bots/discord/commands:** add `purge` and `role-preset` commands ([fb01ce5](https://github.com/revanced/revanced-helper/commit/fb01ce57400130c93751a11573eb444c0ba103eb))
|
||||
* **bots/discord/commands:** allow process exception in `exception-test` ([ca47535](https://github.com/revanced/revanced-helper/commit/ca475356ad95fec86e8e8b5bf4bbf17b70add5fe))
|
||||
* **bots/discord/utils/discord/embeds:** expose `applyCommonEmbedStyles` fn ([2d794ed](https://github.com/revanced/revanced-helper/commit/2d794ede7d7a208bd3616c45e8e6d2a2cd83e9ed))
|
||||
* **bots/discord/utils/embeds:** make title parameter nullable ([ee885ca](https://github.com/revanced/revanced-helper/commit/ee885ca7585a55fdc31e137ae29dc13a37ce2fb2))
|
||||
* **bots/discord/utils/fs:** use `recursive` option for listing files ([da21e1a](https://github.com/revanced/revanced-helper/commit/da21e1a6f76deaeb477203b04263bd170863825b))
|
||||
* **bots/discord/utils:** add duration utility ([a9add9e](https://github.com/revanced/revanced-helper/commit/a9add9ea9affb42bdfcb17cf4b268feec5729854))
|
||||
* **bots/discord/utils:** add functions for role presets ([fb32a04](https://github.com/revanced/revanced-helper/commit/fb32a04ad38be8d0836dc99259b6ef05a0825830))
|
||||
* **bots/discord/utils:** allow loading commands from custom dir ([8b690b8](https://github.com/revanced/revanced-helper/commit/8b690b879bb5c6023c8fc863afbd9fd1d02719bb))
|
||||
* **bots/discord:** add `api.disconnectRetryInterval` config ([2f86586](https://github.com/revanced/revanced-helper/commit/2f8658617923c07f6847cbf1fdfc5f5379d95b6c))
|
||||
* **bots/discord:** add `moderation.roles` config to be used in `moderation` commands ([39d5b3a](https://github.com/revanced/revanced-helper/commit/39d5b3a479b4d856aabe12cc31177c24f88ae23e))
|
||||
* **bots/discord:** add `ocrTriggers` resp config, embed footer scan mode ([744a56a](https://github.com/revanced/revanced-helper/commit/744a56a4fdc8844e37959a88bcf81ee39fe726ef))
|
||||
* **bots/discord:** add a better way to manage databases ([a68d726](https://github.com/revanced/revanced-helper/commit/a68d72687584332587455962b0202a306288057d))
|
||||
* **bots/discord:** add more fallbacks for decancering ([2e1e009](https://github.com/revanced/revanced-helper/commit/2e1e009b4272495798313bd3bd61f258875c62e1))
|
||||
* **bots/discord:** add source ([f9d50a0](https://github.com/revanced/revanced-helper/commit/f9d50a0a6bef8beaa428a0a555bfa4f879f685f1))
|
||||
* **bots/discord:** improve logs ([6abb740](https://github.com/revanced/revanced-helper/commit/6abb7409945c10bd3af451fb45ef4b4d4ebe9489))
|
||||
* **bots/discord:** sanitize `BasicDatabase` inputs ([fd76e0a](https://github.com/revanced/revanced-helper/commit/fd76e0af72fe28b414ae3b5e8d3886e58561e57e))
|
||||
* **bots/discord:** support nickname decancering ([1723e8c](https://github.com/revanced/revanced-helper/commit/1723e8cacf96e8c6bdee22cfd30e89524fdcef74))
|
||||
* **bots/discord:** switch to `drizzle-orm` ([e204b7b](https://github.com/revanced/revanced-helper/commit/e204b7b7566fd7fa423baef32977a8575d44a9e0))
|
||||
* **bots/discord:** update config ([197d2ac](https://github.com/revanced/revanced-helper/commit/197d2acea89c38e43858d52736508d449152e804))
|
||||
* discord bot scanning messages ([d1bd3b2](https://github.com/revanced/revanced-helper/commit/d1bd3b2b7e4985a64e9b070ab006cc6f3508c46e))
|
||||
* **discord-bot:** a way to train AI ([355a508](https://github.com/revanced/revanced-helper/commit/355a50803adc85b5579155b55ddbba4fa0449237))
|
||||
* **discord-bot:** command handler and train cmd ([6aee8a4](https://github.com/revanced/revanced-helper/commit/6aee8a4c63eb108800fcb0a23ca61f200d8f1f2a))
|
||||
* **discord-bot:** event handler ([0ad5ece](https://github.com/revanced/revanced-helper/commit/0ad5ece08593c0db111fa4a592b42c6e0348fd1c))
|
||||
* GODEL AI ([0ba525c](https://github.com/revanced/revanced-helper/commit/0ba525c4a5802106d582c75f713728accf2f151a))
|
||||
* initalize discord bot ([bb4a5a7](https://github.com/revanced/revanced-helper/commit/bb4a5a77eefbc7ac88536f73a111df1050b235e7))
|
||||
* initialize helper client ([7f9ca77](https://github.com/revanced/revanced-helper/commit/7f9ca77e0331ec143160ee51ed7c3aa9e4e70b9c))
|
||||
* message buttons for training ([6551ca9](https://github.com/revanced/revanced-helper/commit/6551ca9dadc2e3ddfe98875e80ed61f7d71a1651))
|
||||
* platform specific responses ([18e57b0](https://github.com/revanced/revanced-helper/commit/18e57b0c320732a937bb60db11c5d6794ed11522))
|
||||
* prettier and eslint ([1c27ccb](https://github.com/revanced/revanced-helper/commit/1c27ccb17c85f0f6982db45de426181d2c231d0e))
|
||||
* refactor and new features ([#7](https://github.com/revanced/revanced-helper/issues/7)) ([8b9f45d](https://github.com/revanced/revanced-helper/commit/8b9f45dc22de29dc2ccb1cfab9a026db00457e25))
|
||||
* run bots in one process ([d26d533](https://github.com/revanced/revanced-helper/commit/d26d53317440c64fb775cea609a87d29be6c8b40))
|
||||
* training and replies changed ([715aa91](https://github.com/revanced/revanced-helper/commit/715aa918cf84213c9b19591a398d7532eb3f232a))
|
||||
* **utils/discord/embeds:** allow adding extra fields for moderation embeds ([49ce9a7](https://github.com/revanced/revanced-helper/commit/49ce9a7ca3d8558b73a9b94dfe7a01d809db6fff))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* In `@revanced/discord-bot`, its environment variable
|
||||
`DATABASE_URL` has been renamed to `DATABASE_PATH`
|
||||
and the `file:` prefix is no longer needed
|
||||
@@ -6,7 +6,7 @@ FROM base AS build
|
||||
WORKDIR /build
|
||||
COPY . .
|
||||
RUN bun install --frozen-lockfile
|
||||
RUN cd bots/discord && bun --bun run build
|
||||
RUN cd bots/discord && bun run build
|
||||
|
||||
FROM base AS release
|
||||
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import type { Config } from './config.schema'
|
||||
// @ts-check
|
||||
|
||||
/**
|
||||
* @type {import('./config.schema').Config}
|
||||
*/
|
||||
export default {
|
||||
owners: ['USER_ID_HERE'],
|
||||
guilds: ['GUILD_ID_HERE'],
|
||||
admin: {
|
||||
users: ['USER_ID_HERE'],
|
||||
roles: {
|
||||
GUILD_ID_HERE: ['ROLE_ID_HERE'],
|
||||
},
|
||||
},
|
||||
moderation: {
|
||||
cure: {
|
||||
defaultName: 'Server member',
|
||||
@@ -30,11 +37,19 @@ export default {
|
||||
checkExpiredEvery: 3600,
|
||||
},
|
||||
messageScan: {
|
||||
scanBots: false,
|
||||
scanOutsideGuilds: false,
|
||||
filter: {
|
||||
channels: ['CHANNEL_ID_HERE'],
|
||||
roles: ['ROLE_ID_HERE'],
|
||||
users: ['USER_ID_HERE'],
|
||||
whitelist: false,
|
||||
whitelist: {
|
||||
channels: ['CHANNEL_ID_HERE'],
|
||||
roles: ['ROLE_ID_HERE'],
|
||||
users: ['USER_ID_HERE'],
|
||||
},
|
||||
blacklist: {
|
||||
channels: ['CHANNEL_ID_HERE'],
|
||||
roles: ['ROLE_ID_HERE'],
|
||||
users: ['USER_ID_HERE'],
|
||||
},
|
||||
},
|
||||
humanCorrections: {
|
||||
falsePositiveLabel: 'false_positive',
|
||||
@@ -48,16 +63,32 @@ export default {
|
||||
allowedAttachmentMimeTypes: ['image/jpeg', 'image/png', 'image/webp'],
|
||||
responses: [
|
||||
{
|
||||
filterOverride: {
|
||||
whitelist: {
|
||||
channels: ['CHANNEL_ID_HERE'],
|
||||
roles: ['ROLE_ID_HERE'],
|
||||
users: ['USER_ID_HERE'],
|
||||
},
|
||||
blacklist: {
|
||||
channels: ['CHANNEL_ID_HERE'],
|
||||
roles: ['ROLE_ID_HERE'],
|
||||
users: ['USER_ID_HERE'],
|
||||
},
|
||||
},
|
||||
triggers: {
|
||||
text: [/^regexp?$/, { label: 'label', threshold: 0.85 }],
|
||||
},
|
||||
response: {
|
||||
title: 'Embed title',
|
||||
description: 'Embed description',
|
||||
fields: [
|
||||
embeds: [
|
||||
{
|
||||
name: 'Field name',
|
||||
value: 'Field value',
|
||||
title: 'Embed title',
|
||||
description: 'Embed description',
|
||||
fields: [
|
||||
{
|
||||
name: 'Field name',
|
||||
value: 'Field value',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -70,4 +101,4 @@ export default {
|
||||
disconnectLimit: 3,
|
||||
disconnectRetryInterval: 10000,
|
||||
},
|
||||
} satisfies Config as Config
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import type { APIEmbed } from 'discord.js'
|
||||
import type { BaseMessageOptions } from 'discord.js'
|
||||
|
||||
export type Config = {
|
||||
owners: string[]
|
||||
guilds: string[]
|
||||
admin?: {
|
||||
users?: string[]
|
||||
roles?: Record<string, string[]>
|
||||
}
|
||||
moderation?: {
|
||||
roles: string[]
|
||||
cure?: {
|
||||
@@ -18,12 +20,12 @@ export type Config = {
|
||||
guilds: Record<string, Record<string, RolePresetConfig>>
|
||||
}
|
||||
messageScan?: {
|
||||
scanBots?: boolean
|
||||
scanOutsideGuilds?: boolean
|
||||
allowedAttachmentMimeTypes: string[]
|
||||
filter: {
|
||||
roles?: string[]
|
||||
users?: string[]
|
||||
channels?: string[]
|
||||
whitelist: boolean
|
||||
filter?: {
|
||||
whitelist?: Filter
|
||||
blacklist?: Filter
|
||||
}
|
||||
humanCorrections: {
|
||||
falsePositiveLabel: string
|
||||
@@ -57,6 +59,7 @@ export type ConfigMessageScanResponse = {
|
||||
}
|
||||
filterOverride?: NonNullable<Config['messageScan']>['filter']
|
||||
response: ConfigMessageScanResponseMessage | null
|
||||
replyToReplied?: boolean
|
||||
}
|
||||
|
||||
export type ConfigMessageScanResponseLabelConfig = {
|
||||
@@ -70,4 +73,10 @@ export type ConfigMessageScanResponseLabelConfig = {
|
||||
threshold: number
|
||||
}
|
||||
|
||||
export type ConfigMessageScanResponseMessage = APIEmbed
|
||||
export type Filter = {
|
||||
roles?: string[]
|
||||
users?: string[]
|
||||
channels?: string[]
|
||||
}
|
||||
|
||||
export type ConfigMessageScanResponseMessage = BaseMessageOptions
|
||||
|
||||
@@ -29,9 +29,8 @@ The distribution files will be placed inside the `dist` directory. Inside will i
|
||||
|
||||
To deploy the bot, you'll need to:
|
||||
|
||||
1. Replace the `config.ts` file with your own configuration _(optional)_
|
||||
2. [Build the bot as seen in the previous step](#-building)
|
||||
3. Run the `reload-slash-commands` script
|
||||
1. [Build the bot as seen in the previous step](#-building)
|
||||
2. Run the `reload-slash-commands` script
|
||||
This is to ensure all commands are registered, so they can be used.
|
||||
**It may take up to 2 hours until **global** commands are updated. This is a Discord limitation.**
|
||||
|
||||
@@ -40,7 +39,7 @@ To deploy the bot, you'll need to:
|
||||
bun run scripts/reload-slash-commands.ts
|
||||
```
|
||||
|
||||
4. Copy contents of the `dist` directory
|
||||
3. Copy contents of the `dist` directory
|
||||
|
||||
```sh
|
||||
# For instance, we'll copy them both to /usr/src/discord-bot
|
||||
@@ -48,18 +47,10 @@ To deploy the bot, you'll need to:
|
||||
cp -R ./dist/* /usr/src/discord-bot
|
||||
```
|
||||
|
||||
5. Copy the empty database (or use your own existing database)
|
||||
|
||||
```sh
|
||||
# By default, the build script creates the database called "db.sqlite3"
|
||||
# Unless you specify otherwise via the "DATABASE_PATH" environment variable
|
||||
cp ./db.sqlite3 /usr/src/discord-bot
|
||||
```
|
||||
|
||||
6. Configure environment variables
|
||||
4. Configure environment variables
|
||||
As seen in [`.env.example`](../.env.example). You can also optionally use a `.env` file which **Bun will automatically load**.
|
||||
|
||||
7. Finally, run the bot
|
||||
5. Finally, run the bot
|
||||
|
||||
```sh
|
||||
cd /usr/src/discord-bot
|
||||
|
||||
@@ -3,6 +3,7 @@ import { defineConfig } from 'drizzle-kit'
|
||||
export default defineConfig({
|
||||
dialect: 'sqlite',
|
||||
schema: './src/database/schemas.ts',
|
||||
out: './.drizzle',
|
||||
dbCredentials: {
|
||||
url: process.env['DATABASE_PATH'] ? `file:./${process.env['DATABASE_PATH']}` : 'file:./db.sqlite3',
|
||||
},
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
"name": "@revanced/discord-bot",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.0-dev.8",
|
||||
"description": "🤖 Discord bot assisting ReVanced",
|
||||
"main": "src/index.ts",
|
||||
"scripts": {
|
||||
"register": "bun run scripts/reload-slash-commands.ts",
|
||||
"start": "bun prepare && bun run src/index.ts",
|
||||
"dev": "bun prepare && bun --watch src/index.ts",
|
||||
"build:config": "bun build config.ts --outdir=dist",
|
||||
"build": "bun prepare && bun build:config && bun build src/index.ts -e ./config.js --target=bun --outdir=dist/src",
|
||||
"build": "bun prepare && bun run scripts/build.ts",
|
||||
"watch": "bun dev",
|
||||
"prepare": "bun run scripts/generate-indexes.ts && drizzle-kit push"
|
||||
"prepare": "bun run scripts/generate-indexes.ts && bunx drizzle-kit generate --name=schema"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
24
bots/discord/scripts/build.ts
Normal file
24
bots/discord/scripts/build.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { createLogger } from '@revanced/bot-shared'
|
||||
import { cp, rename, rm } from 'fs/promises'
|
||||
|
||||
const logger = createLogger()
|
||||
|
||||
logger.warn('Cleaning previous build...')
|
||||
await rm('./dist', { recursive: true })
|
||||
|
||||
logger.info('Building bot...')
|
||||
await Bun.build({
|
||||
entrypoints: ['./src/index.ts'],
|
||||
outdir: './dist/src',
|
||||
target: 'bun',
|
||||
external: ['./config.js'],
|
||||
minify: true,
|
||||
sourcemap: 'external',
|
||||
})
|
||||
|
||||
logger.info('Copying config...')
|
||||
await cp('./config.js', './dist/config.js')
|
||||
|
||||
logger.info('Copying database schema...')
|
||||
await cp('./.drizzle', './dist/.drizzle', { recursive: true })
|
||||
await rm('./.drizzle', { recursive: true })
|
||||
@@ -1,50 +1,53 @@
|
||||
import { REST } from '@discordjs/rest'
|
||||
import { getMissingEnvironmentVariables } from '@revanced/bot-shared'
|
||||
import { Routes } from 'discord-api-types/v9'
|
||||
import type {
|
||||
RESTGetCurrentApplicationResult,
|
||||
RESTPutAPIApplicationCommandsResult,
|
||||
RESTPutAPIApplicationGuildCommandsResult,
|
||||
} from 'discord.js'
|
||||
import { config, discord, logger } from '../src/context'
|
||||
console.log('Deprecated. New implementation to be done.')
|
||||
process.exit(1)
|
||||
|
||||
// Check if token exists
|
||||
// import { REST } from '@discordjs/rest'
|
||||
// import { getMissingEnvironmentVariables } from '@revanced/bot-shared'
|
||||
// import { Routes } from 'discord-api-types/v9'
|
||||
// import type {
|
||||
// RESTGetCurrentApplicationResult,
|
||||
// RESTPutAPIApplicationCommandsResult,
|
||||
// RESTPutAPIApplicationGuildCommandsResult,
|
||||
// } from 'discord.js'
|
||||
// import { config, discord, logger } from '../src/context'
|
||||
|
||||
const missingEnvs = getMissingEnvironmentVariables(['DISCORD_TOKEN'])
|
||||
if (missingEnvs.length) {
|
||||
for (const env of missingEnvs) logger.fatal(`${env} is not defined in environment variables`)
|
||||
process.exit(1)
|
||||
}
|
||||
// // Check if token exists
|
||||
|
||||
// Group commands by global and guild
|
||||
// const missingEnvs = getMissingEnvironmentVariables(['DISCORD_TOKEN'])
|
||||
// if (missingEnvs.length) {
|
||||
// for (const env of missingEnvs) logger.fatal(`${env} is not defined in environment variables`)
|
||||
// process.exit(1)
|
||||
// }
|
||||
|
||||
const { global: globalCommands = [], guild: guildCommands = [] } = Object.groupBy(Object.values(discord.commands), c =>
|
||||
c.global ? 'global' : 'guild',
|
||||
)
|
||||
// // Group commands by global and guild
|
||||
|
||||
// Set commands
|
||||
// const { global: globalCommands = [], guild: guildCommands = [] } = Object.groupBy(Object.values(discord.commands), c =>
|
||||
// c.global ? 'global' : 'guild',
|
||||
// )
|
||||
|
||||
const rest = new REST({ version: '10' }).setToken(process.env['DISCORD_TOKEN']!)
|
||||
// // Set commands
|
||||
|
||||
try {
|
||||
const app = (await rest.get(Routes.currentApplication())) as RESTGetCurrentApplicationResult
|
||||
const data = (await rest.put(Routes.applicationCommands(app.id), {
|
||||
body: globalCommands.map(({ data }) => {
|
||||
if (!data.dm_permission) data.dm_permission = true
|
||||
logger.warn(`Command ${data.name} has no dm_permission set, forcing to true as it is a global command`)
|
||||
return data
|
||||
}),
|
||||
})) as RESTPutAPIApplicationCommandsResult
|
||||
// const rest = new REST({ version: '10' }).setToken(process.env['DISCORD_TOKEN']!)
|
||||
|
||||
logger.info(`Reloaded ${data.length} global commands`)
|
||||
// try {
|
||||
// const app = (await rest.get(Routes.currentApplication())) as RESTGetCurrentApplicationResult
|
||||
// const data = (await rest.put(Routes.applicationCommands(app.id), {
|
||||
// body: globalCommands.map(({ data }) => {
|
||||
// if (!data.dm_permission) data.dm_permission = true
|
||||
// logger.warn(`Command ${data.name} has no dm_permission set, forcing to true as it is a global command`)
|
||||
// return data
|
||||
// }),
|
||||
// })) as RESTPutAPIApplicationCommandsResult
|
||||
|
||||
for (const guildId of config.guilds) {
|
||||
const data = (await rest.put(Routes.applicationGuildCommands(app.id, guildId), {
|
||||
body: guildCommands.map(x => x.data),
|
||||
})) as RESTPutAPIApplicationGuildCommandsResult
|
||||
// logger.info(`Reloaded ${data.length} global commands`)
|
||||
|
||||
logger.info(`Reloaded ${data.length} guild commands for guild ${guildId}`)
|
||||
}
|
||||
} catch (e) {
|
||||
logger.fatal(e)
|
||||
}
|
||||
// for (const guildId of config.guilds) {
|
||||
// const data = (await rest.put(Routes.applicationGuildCommands(app.id, guildId), {
|
||||
// body: guildCommands.map(x => x.data),
|
||||
// })) as RESTPutAPIApplicationGuildCommandsResult
|
||||
|
||||
// logger.info(`Reloaded ${data.length} guild commands for guild ${guildId}`)
|
||||
// }
|
||||
// } catch (e) {
|
||||
// logger.fatal(e)
|
||||
// }
|
||||
|
||||
@@ -12,7 +12,7 @@ export default {
|
||||
.setDMPermission(true)
|
||||
.toJSON(),
|
||||
|
||||
ownerOnly: true,
|
||||
adminOnly: true,
|
||||
global: true,
|
||||
|
||||
async execute(_, interaction) {
|
||||
|
||||
@@ -25,7 +25,7 @@ export default {
|
||||
.setDMPermission(true)
|
||||
.toJSON(),
|
||||
|
||||
ownerOnly: true,
|
||||
adminOnly: true,
|
||||
global: true,
|
||||
|
||||
async execute(_, interaction) {
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
.setDMPermission(true)
|
||||
.toJSON(),
|
||||
|
||||
ownerOnly: true,
|
||||
adminOnly: true,
|
||||
global: true,
|
||||
|
||||
async execute({ api, logger }, interaction) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SlashCommandBuilder } from 'discord.js'
|
||||
|
||||
import CommandError, { CommandErrorType } from '$/classes/CommandError'
|
||||
import { applyRolePreset } from '$/utils/discord/rolePresets'
|
||||
import { applyRolePreset, removeRolePreset } from '$/utils/discord/rolePresets'
|
||||
import type { Command } from '../types'
|
||||
|
||||
import { config } from '$/context'
|
||||
@@ -24,7 +24,7 @@ export default {
|
||||
|
||||
global: false,
|
||||
|
||||
async execute({ logger }, interaction, { userIsOwner }) {
|
||||
async execute({ logger }, interaction, { isExecutorBotAdmin: isExecutorAdmin }) {
|
||||
const user = interaction.options.getUser('member', true)
|
||||
const reason = interaction.options.getString('reason') ?? 'No reason provided'
|
||||
const duration = interaction.options.getString('duration')
|
||||
@@ -48,7 +48,7 @@ export default {
|
||||
if (!member.manageable)
|
||||
throw new CommandError(CommandErrorType.Generic, 'This user cannot be managed by the bot.')
|
||||
|
||||
if (moderator.roles.highest.comparePositionTo(member.roles.highest) <= 0 && !userIsOwner)
|
||||
if (moderator.roles.highest.comparePositionTo(member.roles.highest) <= 0 && !isExecutorAdmin)
|
||||
throw new CommandError(
|
||||
CommandErrorType.InvalidUser,
|
||||
'You cannot mute a user with a role equal to or higher than yours.',
|
||||
@@ -60,6 +60,11 @@ export default {
|
||||
createModerationActionEmbed('Muted', user, interaction.user, reason, durationMs),
|
||||
)
|
||||
|
||||
if (durationMs)
|
||||
setTimeout(() => {
|
||||
removeRolePreset(member, 'mute')
|
||||
}, durationMs)
|
||||
|
||||
logger.info(
|
||||
`Moderator ${interaction.user.tag} (${interaction.user.id}) muted ${user.tag} (${user.id}) until ${expires} because ${reason}`,
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
|
||||
global: false,
|
||||
|
||||
async execute({ logger }, interaction, { userIsOwner }) {
|
||||
async execute({ logger }, interaction, { isExecutorBotAdmin: isExecutorAdmin }) {
|
||||
const action = interaction.options.getString('action', true) as 'apply' | 'remove'
|
||||
const user = interaction.options.getUser('member', true)
|
||||
const preset = interaction.options.getString('preset', true)
|
||||
@@ -61,7 +61,7 @@ export default {
|
||||
'The duration must be at least 1 millisecond long.',
|
||||
)
|
||||
|
||||
if (moderator.roles.highest.comparePositionTo(member.roles.highest) <= 0 && !userIsOwner)
|
||||
if (moderator.roles.highest.comparePositionTo(member.roles.highest) <= 0 && !isExecutorAdmin)
|
||||
throw new CommandError(
|
||||
CommandErrorType.InvalidUser,
|
||||
'You cannot apply a role preset to a user with a role equal to or higher than yours.',
|
||||
@@ -79,6 +79,11 @@ export default {
|
||||
)
|
||||
}
|
||||
|
||||
if (expires)
|
||||
setTimeout(() => {
|
||||
removeRolePreset(member, preset)
|
||||
}, expires)
|
||||
|
||||
await sendPresetReplyAndLogs(action, interaction, user, preset, expires)
|
||||
},
|
||||
} satisfies Command
|
||||
|
||||
@@ -39,10 +39,10 @@ export type Command = {
|
||||
roles?: string[]
|
||||
}
|
||||
/**
|
||||
* Whether this command can only be used by bot owners.
|
||||
* Whether this command can only be used by bot admins.
|
||||
* @default false
|
||||
*/
|
||||
ownerOnly?: boolean
|
||||
adminOnly?: boolean
|
||||
/**
|
||||
* Whether to register this command as a global slash command.
|
||||
* This is set to `false` and commands will be registered in allowed guilds only by default.
|
||||
@@ -52,5 +52,5 @@ export type Command = {
|
||||
}
|
||||
|
||||
export interface Info {
|
||||
userIsOwner: boolean
|
||||
isExecutorBotAdmin: boolean
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Database } from 'bun:sqlite'
|
||||
import { existsSync, readFileSync, readdirSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import { Client as APIClient } from '@revanced/bot-api'
|
||||
import { createLogger } from '@revanced/bot-shared'
|
||||
import { ActivityType, Client as DiscordClient, Partials } from 'discord.js'
|
||||
import { Client as DiscordClient, Partials } from 'discord.js'
|
||||
import { drizzle } from 'drizzle-orm/bun-sqlite'
|
||||
|
||||
// Export config first, as commands require them
|
||||
@@ -25,11 +27,37 @@ export const api = {
|
||||
},
|
||||
},
|
||||
}),
|
||||
isStopping: false,
|
||||
intentionallyDisconnecting: false,
|
||||
disconnectCount: 0,
|
||||
}
|
||||
|
||||
const db = new Database(process.env['DATABASE_PATH'])
|
||||
const DatabasePath = process.env['DATABASE_PATH']
|
||||
const DatabaseSchemaDir = join(import.meta.dir, '..', '.drizzle')
|
||||
|
||||
let dbSchemaFileName: string | undefined
|
||||
|
||||
if (DatabasePath && !existsSync(DatabasePath)) {
|
||||
logger.warn('Database file not found, trying to create from schema...')
|
||||
|
||||
try {
|
||||
const file = readdirSync(DatabaseSchemaDir, { withFileTypes: true })
|
||||
.filter(file => file.isFile() && file.name.endsWith('.sql'))
|
||||
.sort()
|
||||
.at(-1)
|
||||
|
||||
if (!file) throw new Error('No schema file found')
|
||||
|
||||
dbSchemaFileName = file.name
|
||||
logger.debug(`Using schema file: ${dbSchemaFileName}`)
|
||||
} catch (e) {
|
||||
logger.fatal('Could not create database from schema, check if the schema file exists and is accessible')
|
||||
logger.fatal(e)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
const db = new Database(DatabasePath)
|
||||
if (dbSchemaFileName) db.run(readFileSync(join(DatabaseSchemaDir, dbSchemaFileName)).toString())
|
||||
|
||||
export const database = drizzle(db, {
|
||||
schema: schemas,
|
||||
@@ -52,14 +80,6 @@ export const discord = {
|
||||
repliedUser: true,
|
||||
},
|
||||
partials: [Partials.Message, Partials.Reaction],
|
||||
presence: {
|
||||
activities: [
|
||||
{
|
||||
type: ActivityType.Watching,
|
||||
name: 'cat videos',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
commands: Object.fromEntries(Object.values<Command>(commands).map(cmd => [cmd.data.name, cmd])) as Record<
|
||||
string,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { on, withContext } from '$utils/api/events'
|
||||
import { DisconnectReason, HumanizedDisconnectReason } from '@revanced/bot-shared'
|
||||
|
||||
withContext(on, 'disconnect', ({ api, config, logger }, reason, msg) => {
|
||||
if (reason === DisconnectReason.PlannedDisconnect && api.isStopping) return
|
||||
if (reason === DisconnectReason.PlannedDisconnect && api.intentionallyDisconnecting) return
|
||||
|
||||
const ws = api.client.ws
|
||||
if (!ws.disconnected) ws.disconnect()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import CommandError from '$/classes/CommandError'
|
||||
import { isAdmin } from '$/utils/discord/permissions'
|
||||
import { createErrorEmbed, createStackTraceEmbed } from '$utils/discord/embeds'
|
||||
import { on, withContext } from '$utils/discord/events'
|
||||
|
||||
@@ -11,14 +12,14 @@ withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||
logger.debug(`Command ${interaction.commandName} being invoked by ${interaction.user.tag}`)
|
||||
if (!command) return void logger.error(`Command ${interaction.commandName} not implemented but registered!!!`)
|
||||
|
||||
const isOwner = config.owners.includes(interaction.user.id)
|
||||
const isExecutorBotAdmin = isAdmin(await interaction.guild?.members.fetch(interaction.user.id) || interaction.user, config.admin)
|
||||
|
||||
/**
|
||||
* Owner check
|
||||
* Admin check
|
||||
*/
|
||||
if (command.ownerOnly && !isOwner)
|
||||
if (command.adminOnly && !isExecutorBotAdmin)
|
||||
return void (await interaction.reply({
|
||||
embeds: [createErrorEmbed('Massive skill issue', 'This command can only be used by the bot owners.')],
|
||||
embeds: [createErrorEmbed('Massive skill issue', 'This command can only be used by the bot admins.')],
|
||||
ephemeral: true,
|
||||
}))
|
||||
|
||||
@@ -39,7 +40,7 @@ withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||
*/
|
||||
if (interaction.inGuild()) {
|
||||
// Bot owners get bypass
|
||||
if (command.memberRequirements && !isOwner) {
|
||||
if (command.memberRequirements && !isExecutorBotAdmin) {
|
||||
const { permissions = 0n, roles = [], mode } = command.memberRequirements
|
||||
|
||||
const member = await interaction.guild!.members.fetch(interaction.user.id)
|
||||
@@ -69,7 +70,7 @@ withContext(on, 'interactionCreate', async (context, interaction) => {
|
||||
|
||||
try {
|
||||
logger.debug(`Command ${interaction.commandName} being executed`)
|
||||
await command.execute(context, interaction, { userIsOwner: isOwner })
|
||||
await command.execute(context, interaction, { isExecutorBotAdmin })
|
||||
} catch (err) {
|
||||
logger.error(`Error while executing command ${interaction.commandName}:`, err)
|
||||
await interaction[interaction.replied ? 'followUp' : 'reply']({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MessageScanLabeledResponseReactions } from '$/constants'
|
||||
import { responses } from '$/database/schemas'
|
||||
import { getResponseFromText, shouldScanMessage } from '$/utils/discord/messageScan'
|
||||
import { getResponseFromText, messageMatchesFilter } from '$/utils/discord/messageScan'
|
||||
import { createMessageScanResponseEmbed } from '$utils/discord/embeds'
|
||||
import { on, withContext } from '$utils/discord/events'
|
||||
|
||||
@@ -13,21 +13,26 @@ withContext(on, 'messageCreate', async (context, msg) => {
|
||||
} = context
|
||||
|
||||
if (!config || !config.responses) return
|
||||
if (msg.author.bot && !config.scanBots)
|
||||
if (!msg.inGuild() && !config.scanOutsideGuilds) return
|
||||
if (msg.inGuild() && msg.member?.partial) await msg.member.fetch()
|
||||
|
||||
const filteredResponses = config.responses.filter(x => shouldScanMessage(msg, x.filterOverride ?? config.filter))
|
||||
const filteredResponses = config.responses.filter(x => messageMatchesFilter(msg, x.filterOverride ?? config.filter))
|
||||
if (!filteredResponses.length) return
|
||||
|
||||
if (msg.content.length) {
|
||||
try {
|
||||
logger.debug(`Classifying message ${msg.id}`)
|
||||
|
||||
const { response, label } = await getResponseFromText(msg.content, filteredResponses, context)
|
||||
const { response, label, replyToReplied } = await getResponseFromText(msg.content, filteredResponses, context)
|
||||
|
||||
if (response) {
|
||||
logger.debug('Response found')
|
||||
|
||||
const reply = await msg.reply({
|
||||
embeds: [createMessageScanResponseEmbed(response, label ? 'nlp' : 'match')],
|
||||
const toReply = replyToReplied ? await msg.fetchReference() : msg
|
||||
const reply = await toReply.reply({
|
||||
...response,
|
||||
embeds: response.embeds?.map(it => createMessageScanResponseEmbed(it, label ? 'nlp' : 'match')),
|
||||
})
|
||||
|
||||
if (label)
|
||||
@@ -64,7 +69,8 @@ withContext(on, 'messageCreate', async (context, msg) => {
|
||||
if (response) {
|
||||
logger.debug(`Response found for attachment: ${attachment.url}`)
|
||||
await msg.reply({
|
||||
embeds: [createMessageScanResponseEmbed(response, 'ocr')],
|
||||
...response,
|
||||
embeds: response.embeds?.map(it => createMessageScanResponseEmbed(it, 'ocr')),
|
||||
})
|
||||
|
||||
break
|
||||
@@ -14,6 +14,7 @@ import type { ConfigMessageScanResponseLabelConfig } from '$/../config.schema'
|
||||
import { responses } from '$/database/schemas'
|
||||
import { handleUserResponseCorrection } from '$/utils/discord/messageScan'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { isAdmin } from '$/utils/discord/permissions'
|
||||
|
||||
const PossibleReactions = Object.values(Reactions) as string[]
|
||||
|
||||
@@ -32,7 +33,7 @@ withContext(on, 'messageReactionAdd', async (context, rct, user) => {
|
||||
if (reactionMessage.author.id !== reaction.client.user!.id) return
|
||||
if (!PossibleReactions.includes(reaction.emoji.name!)) return
|
||||
|
||||
if (!config.owners.includes(user.id)) {
|
||||
if (!isAdmin(reactionMessage.member || reactionMessage.author)) {
|
||||
// User is in guild, and config has member requirements
|
||||
if (
|
||||
reactionMessage.inGuild() &&
|
||||
@@ -46,7 +47,12 @@ withContext(on, 'messageReactionAdd', async (context, rct, user) => {
|
||||
const member = await reactionMessage.guild.members.fetch(user.id)
|
||||
const { permissions, roles } = allowedMembers
|
||||
|
||||
if (!(member.permissions.has(permissions ?? 0n) || roles?.some(role => member.roles.cache.has(role))))
|
||||
if (
|
||||
!(
|
||||
(permissions ? member.permissions.has(permissions) : false) ||
|
||||
roles?.some(role => member.roles.cache.has(role))
|
||||
)
|
||||
)
|
||||
return
|
||||
} else if (allowedUsers) {
|
||||
if (!allowedUsers.includes(user.id)) return
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { Command } from '$commands/types'
|
||||
import { listAllFilesRecursive } from '$utils/fs'
|
||||
|
||||
export const loadCommands = async (dir: string) => {
|
||||
const commandsMap: Record<string, Command> = {}
|
||||
const files = listAllFilesRecursive(dir)
|
||||
const commands = await Promise.all(
|
||||
files.map(async file => {
|
||||
const command = await import(file)
|
||||
return command.default
|
||||
}),
|
||||
)
|
||||
|
||||
for (const command of commands) {
|
||||
if (command) commandsMap[command.data.name] = command
|
||||
}
|
||||
|
||||
return commandsMap
|
||||
}
|
||||
@@ -24,16 +24,19 @@ export const createSuccessEmbed = (title: string | null, description?: string) =
|
||||
)
|
||||
|
||||
export const createMessageScanResponseEmbed = (
|
||||
response: ConfigMessageScanResponseMessage,
|
||||
response: NonNullable<ConfigMessageScanResponseMessage['embeds']>[number],
|
||||
mode: 'ocr' | 'nlp' | 'match',
|
||||
) => {
|
||||
// biome-ignore lint/style/noParameterAssign: While this is confusing, it is fine for this purpose
|
||||
if ('toJSON' in response) response = response.toJSON()
|
||||
|
||||
const embed = new EmbedBuilder().setTitle(response.title ?? null)
|
||||
|
||||
if (response.description) embed.setDescription(response.description)
|
||||
if (response.fields) embed.addFields(response.fields)
|
||||
|
||||
embed.setFooter({
|
||||
text: `ReVanced • Done via ${MessageScanHumanizedMode[mode]}`,
|
||||
text: `ReVanced • Via ${MessageScanHumanizedMode[mode]}`,
|
||||
iconURL: ReVancedLogoURL,
|
||||
})
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@ import { type Response, responses } from '$/database/schemas'
|
||||
import type {
|
||||
Config,
|
||||
ConfigMessageScanResponse,
|
||||
ConfigMessageScanResponseLabelConfig,
|
||||
ConfigMessageScanResponseMessage,
|
||||
ConfigMessageScanResponseLabelConfig
|
||||
} from 'config.schema'
|
||||
import type { Message, PartialUser, User } from 'discord.js'
|
||||
import { eq } from 'drizzle-orm'
|
||||
@@ -15,9 +14,12 @@ export const getResponseFromText = async (
|
||||
// Just to be safe that we will never use data from the context parameter
|
||||
{ api, logger }: Omit<typeof import('src/context'), 'config'>,
|
||||
ocrMode = false,
|
||||
) => {
|
||||
let label: string | undefined
|
||||
let response: ConfigMessageScanResponseMessage | undefined | null
|
||||
): Promise<ConfigMessageScanResponse & { label?: string }> => {
|
||||
let responseConfig: Awaited<ReturnType<typeof getResponseFromText>> = {
|
||||
triggers: {},
|
||||
response: null
|
||||
}
|
||||
|
||||
const firstLabelIndexes: number[] = []
|
||||
|
||||
// Test if all regexes before a label trigger is matched
|
||||
@@ -25,29 +27,28 @@ export const getResponseFromText = async (
|
||||
const trigger = responses[i]!
|
||||
|
||||
// Filter override check is not neccessary here, we are already passing responses that match the filter
|
||||
// from the messageCreate handler
|
||||
// from the messageCreate handler, see line 17 of messageCreate handler
|
||||
const {
|
||||
triggers: { text: textTriggers, image: imageTriggers },
|
||||
response: resp,
|
||||
triggers: { text: textTriggers, image: imageTriggers }
|
||||
} = trigger
|
||||
if (response) break
|
||||
if (responseConfig) break
|
||||
|
||||
if (ocrMode) {
|
||||
if (imageTriggers)
|
||||
for (const regex of imageTriggers)
|
||||
if (regex.test(content)) {
|
||||
logger.debug(`Message matched regex (OCR mode): ${regex.source}`)
|
||||
response = resp
|
||||
responseConfig = trigger
|
||||
break
|
||||
}
|
||||
} else
|
||||
for (let j = 0; j < textTriggers!.length; j++) {
|
||||
const trigger = textTriggers![j]!
|
||||
const regex = textTriggers![j]!
|
||||
|
||||
if (trigger instanceof RegExp) {
|
||||
if (trigger.test(content)) {
|
||||
logger.debug(`Message matched regex (before mode): ${trigger.source}`)
|
||||
response = resp
|
||||
if (regex instanceof RegExp) {
|
||||
if (regex.test(content)) {
|
||||
logger.debug(`Message matched regex (before mode): ${regex.source}`)
|
||||
responseConfig = trigger
|
||||
break
|
||||
}
|
||||
} else {
|
||||
@@ -58,7 +59,7 @@ export const getResponseFromText = async (
|
||||
}
|
||||
|
||||
// If none of the regexes match, we can search for labels immediately
|
||||
if (!response && !ocrMode) {
|
||||
if (!responseConfig && !ocrMode) {
|
||||
logger.debug('No match from before regexes, doing NLP')
|
||||
const scan = await api.client.parseText(content)
|
||||
if (scan.labels.length) {
|
||||
@@ -76,24 +77,22 @@ export const getResponseFromText = async (
|
||||
|
||||
if (!labelConfig) {
|
||||
logger.warn(`No label config found for label ${matchedLabel.name}`)
|
||||
return { response: null, label: undefined }
|
||||
return responseConfig
|
||||
}
|
||||
|
||||
if (matchedLabel.confidence >= triggerConfig!.threshold) {
|
||||
logger.debug('Label confidence is enough')
|
||||
label = matchedLabel.name
|
||||
response = labelConfig.response
|
||||
responseConfig = labelConfig
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we still don't have a label, we can match all regexes after the initial label trigger
|
||||
if (!response) {
|
||||
// If we still don't have a response config, we can match all regexes after the initial label trigger
|
||||
if (!responseConfig) {
|
||||
logger.debug('No match from NLP, doing after regexes')
|
||||
for (let i = 0; i < responses.length; i++) {
|
||||
const {
|
||||
triggers: { text: textTriggers },
|
||||
response: resp,
|
||||
triggers: { text: textTriggers }
|
||||
} = responses[i]!
|
||||
const firstLabelIndex = firstLabelIndexes[i] ?? -1
|
||||
|
||||
@@ -103,7 +102,7 @@ export const getResponseFromText = async (
|
||||
if (trigger instanceof RegExp) {
|
||||
if (trigger.test(content)) {
|
||||
logger.debug(`Message matched regex (after mode): ${trigger.source}`)
|
||||
response = resp
|
||||
responseConfig = responses[i]!
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -111,30 +110,21 @@ export const getResponseFromText = async (
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
response,
|
||||
label,
|
||||
}
|
||||
return responseConfig
|
||||
}
|
||||
|
||||
export const shouldScanMessage = (
|
||||
export const messageMatchesFilter = (
|
||||
message: Message,
|
||||
filter: NonNullable<Config['messageScan']>['filter'],
|
||||
): message is Message<true> => {
|
||||
if (message.author.bot) return false
|
||||
if (!message.guild) return false
|
||||
) => {
|
||||
if (!filter) return true
|
||||
|
||||
const filters = [
|
||||
filter.users?.includes(message.author.id),
|
||||
message.member?.roles.cache.some(x => filter.roles?.includes(x.id)),
|
||||
filter.channels?.includes(message.channel.id),
|
||||
]
|
||||
const memberRoles = new Set(message.member?.roles.cache.keys())
|
||||
const blFilter = filter.blacklist
|
||||
|
||||
if (filter.whitelist && filters.every(x => !x)) return false
|
||||
if (!filter.whitelist && filters.some(x => x)) return false
|
||||
|
||||
return true
|
||||
// If matches blacklist, will return false
|
||||
// Any other case, will return true
|
||||
return !(blFilter && (blFilter.channels?.includes(message.channelId) || blFilter.roles?.some(role => memberRoles.has(role)) || blFilter.users?.includes(message.author.id)))
|
||||
}
|
||||
|
||||
export const handleUserResponseCorrection = async (
|
||||
@@ -158,8 +148,10 @@ export const handleUserResponseCorrection = async (
|
||||
correctedById: user.id,
|
||||
})
|
||||
.where(eq(responses.replyId, response.replyId))
|
||||
|
||||
await reply.edit({
|
||||
embeds: [createMessageScanResponseEmbed(correctLabelResponse.response, 'nlp')],
|
||||
...correctLabelResponse.response,
|
||||
embeds: correctLabelResponse.response.embeds?.map(it => createMessageScanResponseEmbed(it, 'nlp')),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
11
bots/discord/src/utils/discord/permissions.ts
Normal file
11
bots/discord/src/utils/discord/permissions.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { GuildMember, type User } from 'discord.js'
|
||||
import config from '../../../config'
|
||||
|
||||
export const isAdmin = (userOrMember: User | GuildMember) => {
|
||||
return config.admin?.users?.includes(userOrMember.id) || (userOrMember instanceof GuildMember && isMemberAdmin(userOrMember))
|
||||
}
|
||||
|
||||
export const isMemberAdmin = (member: GuildMember) => {
|
||||
const roles = new Set(member.roles.cache.keys())
|
||||
return Boolean(config?.admin?.roles?.[member.guild.id]?.some(role => roles.has(role)))
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
"composite": false,
|
||||
"exactOptionalPropertyTypes": false,
|
||||
"esModuleInterop": true,
|
||||
"allowJs": true,
|
||||
"paths": {
|
||||
"$/*": ["./src/*"],
|
||||
"$constants": ["./src/constants"],
|
||||
|
||||
@@ -41,11 +41,11 @@
|
||||
"@tsconfig/strictest": "^2.0.5",
|
||||
"@types/bun": "^1.1.6",
|
||||
"conventional-changelog-conventionalcommits": "^7.0.2",
|
||||
"lefthook": "^1.7.4",
|
||||
"lefthook": "^1.7.5",
|
||||
"portainer-service-webhook": "https://github.com/newarifrh/portainer-service-webhook#v1",
|
||||
"semantic-release": "^24.0.0",
|
||||
"turbo": "^2.0.9",
|
||||
"typescript": "^5.5.3"
|
||||
"typescript": "^5.5.4"
|
||||
},
|
||||
"trustedDependencies": [
|
||||
"@biomejs/biome",
|
||||
@@ -54,6 +54,7 @@
|
||||
"lefthook"
|
||||
],
|
||||
"patchedDependencies": {
|
||||
"@semantic-release/npm@12.0.1": "patches/@semantic-release%2Fnpm@12.0.1.patch"
|
||||
"@semantic-release/npm@12.0.1": "patches/@semantic-release%2Fnpm@12.0.1.patch",
|
||||
"drizzle-kit@0.22.8": "patches/drizzle-kit@0.22.8.patch"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,23 +53,34 @@ export class ClientWebSocketManager {
|
||||
}
|
||||
}, this.timeout)
|
||||
|
||||
this.#socket.on('open', () => {
|
||||
this.disconnected = false
|
||||
clearTimeout(timeout)
|
||||
this.#listen()
|
||||
rs()
|
||||
})
|
||||
|
||||
this.#socket.on('error', err => {
|
||||
clearTimeout(timeout)
|
||||
const errorBeforeReadyHandler = (err: Error) => {
|
||||
cleanup()
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
this.#socket.on('close', (code, reason) => {
|
||||
const closeBeforeReadyHandler = (code: number, reason: Buffer) => {
|
||||
clearTimeout(timeout)
|
||||
this._handleDisconnect(code, reason.toString())
|
||||
throw new Error('WebSocket connection closed before ready')
|
||||
})
|
||||
}
|
||||
|
||||
const readyHandler = () => {
|
||||
this.disconnected = false
|
||||
cleanup()
|
||||
this.#listen()
|
||||
rs()
|
||||
}
|
||||
|
||||
const cleanup = () => {
|
||||
this.#socket.off('open', readyHandler)
|
||||
this.#socket.off('close', closeBeforeReadyHandler)
|
||||
this.#socket.off('error', errorBeforeReadyHandler)
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
|
||||
this.#socket.on('open', readyHandler)
|
||||
this.#socket.on('error', errorBeforeReadyHandler)
|
||||
this.#socket.on('close', closeBeforeReadyHandler)
|
||||
} catch (e) {
|
||||
rj(e)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
diff --git a/node_modules/@semantic-release/npm/.bun-tag-3853154e196b7721 b/.bun-tag-3853154e196b7721
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/node_modules/@semantic-release/npm/.bun-tag-550461f23a8ec245 b/.bun-tag-550461f23a8ec245
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/node_modules/@semantic-release/npm/.bun-tag-c9c8130945517add b/.bun-tag-c9c8130945517add
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
|
||||
diff --git a/lib/prepare.js b/lib/prepare.js
|
||||
index 3e76bec44cf595a1b4141728336bed904d4d518d..c6baf4e8de9bdf7536f9ad2e9eb9c360e031c7b5 100644
|
||||
index 3e76bec44cf595a1b4141728336bed904d4d518d..4b25ca64879bbee2a600f2b23b738c86136ad9c6 100644
|
||||
--- a/lib/prepare.js
|
||||
+++ b/lib/prepare.js
|
||||
@@ -1,6 +1,7 @@
|
||||
@@ -14,7 +20,7 @@ index 3e76bec44cf595a1b4141728336bed904d4d518d..c6baf4e8de9bdf7536f9ad2e9eb9c360
|
||||
|
||||
export default async function (
|
||||
npmrc,
|
||||
@@ -11,19 +12,12 @@ export default async function (
|
||||
@@ -11,19 +12,13 @@ export default async function (
|
||||
|
||||
logger.log("Write version %s to package.json in %s", version, basePath);
|
||||
|
||||
@@ -36,10 +42,11 @@ index 3e76bec44cf595a1b4141728336bed904d4d518d..c6baf4e8de9bdf7536f9ad2e9eb9c360
|
||||
|
||||
- await versionResult;
|
||||
+ await writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, detectIndent(pkgJsonRaw).indent))
|
||||
+ await execa("bun", ["install"]);
|
||||
|
||||
if (tarballDir) {
|
||||
logger.log("Creating npm package version %s", version);
|
||||
@@ -38,7 +32,7 @@ export default async function (
|
||||
@@ -38,7 +33,7 @@ export default async function (
|
||||
// Only move the tarball if we need to
|
||||
// Fixes: https://github.com/semantic-release/npm/issues/169
|
||||
if (tarballSource !== tarballDestination) {
|
||||
|
||||
21
patches/drizzle-kit@0.22.8.patch
Normal file
21
patches/drizzle-kit@0.22.8.patch
Normal file
@@ -0,0 +1,21 @@
|
||||
diff --git a/bin.cjs b/bin.cjs
|
||||
index 142ed9c20f28dc1080bebfb52325fa308c6cb771..9d3bea0787f6c05df11567c6821bc85743286340 100644
|
||||
--- a/bin.cjs
|
||||
+++ b/bin.cjs
|
||||
@@ -22053,7 +22053,7 @@ var init_sqliteImports = __esm({
|
||||
const { unregister } = await safeRegister();
|
||||
for (let i2 = 0; i2 < imports.length; i2++) {
|
||||
const it = imports[i2];
|
||||
- const i0 = require(`${it}`);
|
||||
+ const i0 = await import(`${it}`);
|
||||
const prepared = prepareFromExports3(i0);
|
||||
tables.push(...prepared.tables);
|
||||
}
|
||||
@@ -129572,6 +129572,7 @@ var generateCommand = new Command("generate").option("--dialect <dialect>", "Dat
|
||||
} else {
|
||||
assertUnreachable(dialect7);
|
||||
}
|
||||
+ process.exit(0);
|
||||
});
|
||||
var migrateCommand = new Command("migrate").option(
|
||||
"--config <config>",
|
||||
@@ -31,7 +31,7 @@ const Options = {
|
||||
[
|
||||
'@semantic-release/git',
|
||||
{
|
||||
assets: ['CHANGELOG.md', 'package.json'],
|
||||
assets: ['CHANGELOG.md', 'package.json', '../../bun.lockb'],
|
||||
},
|
||||
],
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user