Archived
0
0
Fork 0

Compare commits

..

10 commits

49 changed files with 5865 additions and 1999 deletions

1
.gitattributes vendored
View file

@ -1,2 +1 @@
.yarn/* linguist-vendored
.pnp.cjs linguist-vendored

5
.idea/.gitignore vendored
View file

@ -1,5 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View file

@ -1,194 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</value>
</option>
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
<option name="SOFT_MARGINS" value="80,120" />
<CssCodeStyleSettings>
<option name="HEX_COLOR_UPPER_CASE" value="true" />
<option name="HEX_COLOR_LONG_FORMAT" value="true" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="ENFORCE_QUOTES_ON_FORMAT" value="true" />
</CssCodeStyleSettings>
<DBN-PSQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
<HTMLCodeStyleSettings>
<option name="HTML_UNIFORM_INDENT" value="true" />
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
<option name="HTML_DO_NOT_INDENT_CHILDREN_OF" value="" />
</HTMLCodeStyleSettings>
<JSCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</JSCodeStyleSettings>
<Markdown>
<option name="MAX_LINES_AROUND_HEADER" value="0" />
<option name="MAX_LINES_AROUND_BLOCK_ELEMENTS" value="0" />
<option name="MAX_LINES_BETWEEN_PARAGRAPHS" value="0" />
</Markdown>
<ScssCodeStyleSettings>
<option name="HEX_COLOR_UPPER_CASE" value="true" />
<option name="HEX_COLOR_LONG_FORMAT" value="true" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="ENFORCE_QUOTES_ON_FORMAT" value="true" />
</ScssCodeStyleSettings>
<TypeScriptCodeStyleSettings version="0">
<option name="FORCE_SEMICOLON_STYLE" value="true" />
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
<option name="USE_PUBLIC_MODIFIER" value="true" />
<option name="PREFER_AS_TYPE_CAST" value="true" />
<option name="USE_DOUBLE_QUOTES" value="false" />
<option name="FORCE_QUOTE_STYlE" value="true" />
<option name="ENFORCE_TRAILING_COMMA" value="WhenMultiline" />
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
<option name="IMPORT_SORT_MODULE_NAME" value="true" />
</TypeScriptCodeStyleSettings>
<codeStyleSettings language="CSS">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<NAME>.*</NAME>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="HTML">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JavaScript">
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_FOR" value="false" />
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Markdown">
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="SASS">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="SCSS">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<NAME>.*</NAME>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="TypeScript">
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="ALIGN_MULTILINE_FOR" value="false" />
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<indentOptions>
<option name="INDENT_SIZE" value="2" />
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="Vue">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="2" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

View file

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View file

@ -1,6 +0,0 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="/*&#10; * This file is part of ArgonBot&#10; *&#10; * ArgonBot is free software: you can redistribute it and/or modify&#10; * it under the terms of the GNU General Public License as published by&#10; * the Free Software Foundation, either version 3 of the License, or&#10; * (at your option) any later version.&#10; *&#10; * ArgonBot is distributed in the hope that it will be useful,&#10; * but WITHOUT ANY WARRANTY; without even the implied warranty of&#10; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10; * GNU General Public License for more details.&#10; *&#10; * You should have received a copy of the GNU General Public License&#10; * along with ArgonBot. If not, see &lt;https: //www.gnu.org/licenses/&gt;.&#10; */" />
<option name="myName" value="GPL-3.0-or-later" />
</copyright>
</component>

View file

@ -1,6 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

View file

@ -1,13 +0,0 @@
<component name="InspectionProjectProfileManager">
<settings>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="INFORMATION" />
<item index="1" class="java.lang.String" itemvalue="TYPO" />
<item index="2" class="java.lang.String" itemvalue="SERVER PROBLEM" />
<item index="3" class="java.lang.String" itemvalue="WEAK WARNING" />
<item index="4" class="java.lang.String" itemvalue="INFO" />
<item index="5" class="java.lang.String" itemvalue="WARNING" />
<item index="6" class="java.lang.String" itemvalue="ERROR" />
</list>
</settings>
</component>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EslintConfiguration">
<option name="fix-on-save" value="true" />
</component>
</project>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ArgonBot.iml" filepath="$PROJECT_DIR$/.idea/ArgonBot.iml" />
</modules>
</component>
</project>

View file

@ -1,17 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Tests" type="mocha-javascript-test-runner">
<node-interpreter>project</node-interpreter>
<node-options />
<mocha-package>yarn:package.json:mocha</mocha-package>
<working-directory>$PROJECT_DIR$</working-directory>
<pass-parent-env>true</pass-parent-env>
<envs>
<env name="NODE_CONFIG_ENV" value="tests" />
</envs>
<ui>bdd</ui>
<extra-mocha-options>-r ts-node/register -r tsconfig-paths/register</extra-mocha-options>
<test-kind>PATTERN</test-kind>
<test-pattern>tests/**/*.ts</test-pattern>
<method v="2" />
</configuration>
</component>

View file

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="clean" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="clean" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View file

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="commit" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="commit" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View file

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="compile:dev" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="compile:dev" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View file

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="lint" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="lint" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View file

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="run:dev" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="run:dev" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View file

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="watch:bot" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="watch:bot" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View file

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="watch:tsc" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/package.json" />
<command value="run" />
<scripts>
<script value="watch:tsc" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -1,6 +0,0 @@
{
"recommendations": [
"arcanis.vscode-zipfs",
"dbaeumer.vscode-eslint"
]
}

15
.vscode/settings.json vendored
View file

@ -1,15 +0,0 @@
{
"search.exclude": {
"**/.yarn": true,
},
"editor.formatOnPaste": true,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"typescript.enablePromptUseWorkspaceTsdk": true,
"eslint.format.enable": true,
"eslint.lintTask.enable": true,
"eslint.packageManager": "yarn",
"editor.insertSpaces": false,
"editor.tabSize": 2,
"typescript.preferences.quoteStyle": "single"
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

768
.yarn/releases/yarn-3.1.0.cjs vendored Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,3 +1,7 @@
nmMode: hardlinks-local
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
spec: "@yarnpkg/plugin-typescript"
@ -6,6 +10,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
yarnPath: .yarn/releases/yarn-sources.cjs
nodeLinker: node-modules
yarnPath: .yarn/releases/yarn-3.1.0.cjs

View file

@ -1 +1 @@
# Argon Bot
UwU

View file

@ -2,5 +2,12 @@
"token": "",
"logLevel": "",
"prefix": "",
"owner": ""
"owner": "",
"db": {
"host": "",
"port": "0000",
"user": "",
"password": "",
"database": ""
}
}

View file

@ -0,0 +1,31 @@
/*
* This file is part of ArgonBot
*
* ArgonBot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ArgonBot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ArgonBot. If not, see <https: //www.gnu.org/licenses/>.
*/
exports.shorthands = undefined;
exports.up = (pgm) => {
pgm.createTable('settings', {
id: {
type: 'varchar(20)',
},
locale: {
type: 'varchar(10)',
default: 'en-US',
notNull: true,
},
});
};

View file

@ -21,6 +21,7 @@
"coverage": "NODE_CONFIG_ENV=tests nyc yarn run test",
"lint": "eslint --format=pretty src/**/*.ts",
"lint:save": "eslint --format=pretty --save src/**/*.ts",
"migrate": "node-pg-migrate",
"postinstall": "husky install",
"release:alpha": "standard-version --prelease alpha -s",
"release:beta": "standard-version --prelease beta -s",
@ -33,74 +34,86 @@
"watch:tsc": "tsc --watch"
},
"dependencies": {
"@discordjs/opus": "^0.5.3",
"@discordjs/voice": "^0.5.1",
"bufferutil": "^4.0.3",
"chalk": "^4.1.1",
"@discordjs/opus": "^0.6.0",
"@discordjs/voice": "^0.7.2",
"bufferutil": "^4.0.5",
"chalk": "^4.1.2",
"config": "^3.3.6",
"discord.js": "dev",
"discord.js": "^13.3.0",
"erlpack": "^0.1.3",
"ffmpeg-static": "^4.4.0",
"figlet": "^1.5.0",
"figlet": "^1.5.2",
"gradient-string": "^1.2.0",
"i18next": "^20.3.2",
"i18next-fluent": "^1.0.1",
"i18next": "^21.3.3",
"i18next-fluent": "^2.0.0",
"i18next-fs-backend": "^1.1.1",
"jsonschema": "^1.4.0",
"luxon": "^1.27.0",
"luxon": "^2.0.2",
"module-alias": "^2.2.2",
"node-gyp": "^8.1.0",
"node-pg-migrate": "^6.0.0",
"pg": "^8.7.1",
"sodium": "^3.0.2",
"sql-template-strings": "^2.2.2",
"terminal-link": "^3.0.0",
"tslib": "^2.3.0",
"typescript": "^4.3.4",
"utf-8-validate": "^5.0.5",
"vm2": "^3.9.3",
"tslib": "^2.3.1",
"typescript": "^4.4.4",
"utf-8-validate": "^5.0.7",
"vm2": "^3.9.5",
"zlib-sync": "^0.1.7"
},
"devDependencies": {
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
"@commitlint/prompt-cli": "^12.1.4",
"@commitlint/cli": "^13.2.1",
"@commitlint/config-conventional": "^13.2.0",
"@commitlint/prompt-cli": "^13.2.1",
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-typescript": "^8.2.1",
"@types/chai": "^4.2.19",
"@types/config": "^0.0.38",
"@types/eslint": "^7.2.13",
"@types/figlet": "^1.5.1",
"@types/gradient-string": "^1.1.1",
"@types/i18next-fs-backend": "^1.0.0",
"@types/luxon": "^1.27.0",
"@types/mocha": "^8.2.2",
"@types/module-alias": "^2.0.0",
"@types/node": "^15.12.5",
"@types/rimraf": "^3.0.0",
"@types/sinon": "^10.0.2",
"@types/source-map-support": "^0.5.3",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"@typescript-eslint/parser": "^4.28.1",
"@typescript-eslint/typescript-estree": "^4.28.1",
"@rollup/plugin-strip": "^2.1.0",
"@rollup/plugin-typescript": "^8.3.0",
"@types/chai": "^4.2.22",
"@types/config": "^0.0.40",
"@types/eslint": "^7.28.2",
"@types/figlet": "^1.5.4",
"@types/gradient-string": "^1.1.2",
"@types/i18next-fs-backend": "^1.1.2",
"@types/luxon": "^2.0.5",
"@types/mocha": "^8.2.3",
"@types/module-alias": "^2.0.1",
"@types/node": "^16.11.6",
"@types/pg": "^8.6.1",
"@types/rimraf": "^3.0.2",
"@types/rollup-plugin-progress": "^1.1.1",
"@types/rollup-plugin-size-snapshot": "^0.10.1",
"@types/sinon": "^10.0.6",
"@types/source-map-support": "^0.5.4",
"@typescript-eslint/eslint-plugin": "^5.2.0",
"@typescript-eslint/parser": "^5.2.0",
"@typescript-eslint/typescript-estree": "^5.2.0",
"chai": "^4.3.4",
"eslint": "^7.29.0",
"eslint": "^8.1.0",
"eslint-formatter-pretty": "^4.1.0",
"eslint-plugin-header": "^3.1.1",
"husky": "^6.0.0",
"husky": "^7.0.4",
"i18next-chained-backend": "^3.0.2",
"lint-staged": "^11.0.0",
"mocha": "^9.0.1",
"nodemon": "^2.0.8",
"lint-staged": "^11.2.6",
"mocha": "^9.1.3",
"nodemon": "^2.0.14",
"nyc": "^15.1.0",
"rimraf": "^3.0.2",
"rollup": "^2.52.3",
"rollup": "^2.58.3",
"rollup-plugin-analyzer": "^4.0.0",
"rollup-plugin-multi-input": "^1.3.1",
"rollup-plugin-progress": "^1.1.2",
"rollup-plugin-size-snapshot": "^0.12.0",
"rollup-plugin-sizes": "^1.0.4",
"rollup-plugin-terser": "^7.0.2",
"sinon": "^11.1.1",
"source-map-support": "^0.5.19",
"standard-version": "^9.3.0",
"ts-node": "^10.0.0",
"tsconfig-paths": "^3.9.0",
"typescript-eslint-language-service": "^4.1.4"
"rollup-plugin-visualizer": "^5.5.2",
"sinon": "^11.1.2",
"source-map-support": "^0.5.20",
"standard-version": "^9.3.2",
"ts-node": "^10.4.0",
"ts-sql-plugin": "^0.10.0",
"tsconfig-paths": "^3.11.0",
"typescript-eslint-language-service": "^4.1.5"
},
"eslintConfig": {
"root": true,
@ -164,29 +177,6 @@
"license-header.txt"
],
"no-case-declarations": "off",
"keyword-spacing": [
"error",
{
"overrides": {
"if": {
"before": false,
"after": false
},
"catch": {
"before": true,
"after": false
},
"switch": {
"before": true,
"after": false
},
"for": {
"before": true,
"after": false
}
}
}
],
"@typescript-eslint/no-non-null-assertion": "off"
},
"reportUnusedDisableDirectives": true

View file

@ -18,6 +18,8 @@ import typescript from '@rollup/plugin-typescript';
import json from '@rollup/plugin-json';
import { terser } from 'rollup-plugin-terser';
import multiInput from 'rollup-plugin-multi-input';
import progress from 'rollup-plugin-progress';
import analyze from 'rollup-plugin-analyzer';
export default {
input: ['src/index.ts', 'src/commands/**/*.ts'],
@ -30,5 +32,7 @@ export default {
json({ compact: true, preferConst: true }),
terser(),
multiInput(),
progress(),
analyze(),
],
};

View file

@ -0,0 +1,102 @@
/*
* This file is part of ArgonBot
*
* ArgonBot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ArgonBot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ArgonBot. If not, see <https: //www.gnu.org/licenses/>.
*/
import Command from '@structures/command';
import { ECommandRunIn, IGuildSettings } from '@utils/types';
import { query } from '@utils/utils';
import type { Client, Message } from 'discord.js';
import i18next from 'i18next';
import SQL from 'sql-template-strings';
export default class extends Command {
public constructor(client: Client, file: string) {
super(client, file, {
shortDescription: i18next.t('commands:settings.shortDescription'),
extendedDescription: i18next.t('commands:settings.extendedDescription'),
usage: 'set locale en-US',
runIn: ECommandRunIn.Server,
args: [
{
name: 'action',
acceptedValues: [ 'set', 'get', 'reset' ],
description: i18next.t('commands:settings.actionArg'),
},
{
name: 'setting',
description: i18next.t('commands:settings.settingArg'),
},
{
name: 'value',
description: i18next.t('commands:settings.valueArg'),
optional: true,
goToEnd: true,
},
],
});
}
public async run(message: Message, action: string, setting: string, value: string): Promise<void> {
switch(action) {
case 'set':
await this.setSetting(message, setting, value);
break;
case 'get':
break;
case 'reset':
break;
default:
break;
}
}
private async setSetting(message: Message, setting: string, value: string): Promise<void> {
let findGuild = await query<IGuildSettings>(SQL`SELECT *
FROM bot.public.settings
WHERE id = ${message.guild?.id}`);
if(findGuild && findGuild.rowCount === 0) {
await query(SQL`INSERT INTO bot.public.settings (id)
VALUES (${message.guild?.id})`);
findGuild = await query<IGuildSettings>(SQL`SELECT *
FROM bot.public.settings
WHERE id = ${message.guild?.id}`);
}
switch(setting) {
case 'locale':
case 'language':
if(findGuild) {
const guildSettings = findGuild.rows[0]!;
if(guildSettings.locale === value)
await message.reply(i18next.t('commands:settings.localeAlreadySet', { locale: guildSettings.locale }));
else {
await query(SQL`UPDATE bot.public.settings
SET locale=${value}
WHERE id = ${message.guild?.id}`);
await message.channel.send(i18next.t('commands:settings.localeSuccessfullySet', { locale: value }));
}
}
break;
case 'get':
break;
case 'reset':
break;
default:
break;
}
}
}

View file

@ -15,17 +15,17 @@
* along with ArgonBot. If not, see <https: //www.gnu.org/licenses/>.
*/
import Command from '@structures/command';
import { capitalize } from '@utils/utils';
import config from 'config';
import { Client, Message, MessageButton, MessageEmbed, MessageSelectMenu, MessageSelectOptionData } from 'discord.js';
import i18next from 'i18next';
// TODO: Redo this mf
export default class extends Command {
public constructor(client: Client, file: string) {
super(client, file, {
shortDescription: i18next.t('commands:help.shortDescription'),
extendedDescription: i18next.t('commands:help.extendedDescription'),
usage: 'vm',
args: [
{
name: 'command',
@ -50,7 +50,7 @@ export default class extends Command {
commandGroups.push({
name: command.options.group!,
embed: new MessageEmbed(),
commands: [command],
commands: [ command ],
});
categories.push(command.options.group!);
@ -60,7 +60,7 @@ export default class extends Command {
commandGroups.forEach((val, index) => {
val.embed = new MessageEmbed();
val.embed.setAuthor(i18next.t('commands:help.embedName'));
val.embed.setTitle(val.name.toUpperCase());
val.embed.setTitle(capitalize(val.name));
val.embed.setColor(message.member?.roles.highest.color ?? 0xFFFFFF);
val.embed.setFooter(`Page ${index + 1}/${commandGroups.length}`);
val.embed.setTimestamp();
@ -89,15 +89,15 @@ export default class extends Command {
chooseHelpCategory.setPlaceholder(i18next.t('commands:help.categoryPlaceholder'));
for(const category of categories) {
dropDownOptions.push({ label: category, value: category });
dropDownOptions.push({ label: capitalize(category), value: category });
}
chooseHelpCategory.addOptions(dropDownOptions);
const helpMsg = await message.channel.send({
content: i18next.t('commands:help.helpScreenBtnHelp'),
embeds: [commandGroups[0]!.embed],
components: [[previousCategoryBtn, nextCategoryBtn], [chooseHelpCategory]],
embeds: [ commandGroups[0]!.embed ],
components: [ [ previousCategoryBtn, nextCategoryBtn ], [ chooseHelpCategory ] ],
});
const buttonCollector = helpMsg.channel.createMessageComponentInteractionCollector({ time: 60000 });
@ -111,33 +111,33 @@ export default class extends Command {
previousCategoryBtn.setDisabled(false);
}
if(currentPage !== 0) {
if(currentPage + 1 !== commandGroups.length) {
nextCategoryBtn.setDisabled(false);
previousCategoryBtn.setDisabled(true);
previousCategoryBtn.setDisabled(false);
}
await interaction.update({
content: i18next.t('commands:help.helpScreenBtnHelp'),
embeds: [commandGroups[currentPage]!.embed],
components: [[previousCategoryBtn, nextCategoryBtn], [chooseHelpCategory]],
embeds: [ commandGroups[currentPage]!.embed ],
components: [ [ previousCategoryBtn, nextCategoryBtn ], [ chooseHelpCategory ] ],
});
} else if(interaction.customID === 'previousCategoryBtn') {
currentPage--;
if(currentPage + 1 !== commandGroups.length) {
nextCategoryBtn.setDisabled(false);
previousCategoryBtn.setDisabled(false);
}
if(currentPage === 0) {
previousCategoryBtn.setDisabled(true);
nextCategoryBtn.setDisabled(false);
}
if(currentPage !== 0) {
nextCategoryBtn.setDisabled(false);
previousCategoryBtn.setDisabled(true);
}
await interaction.update({
content: i18next.t('commands:help.helpScreenBtnHelp'),
embeds: [commandGroups[currentPage]!.embed],
components: [[previousCategoryBtn, nextCategoryBtn], [chooseHelpCategory]],
embeds: [ commandGroups[currentPage]!.embed ],
components: [ [ previousCategoryBtn, nextCategoryBtn ], [ chooseHelpCategory ] ],
});
} else if(interaction.customID === 'chooseHelpCategory') {
currentPage = categories.indexOf(interaction.values[0]);
@ -147,9 +147,9 @@ export default class extends Command {
nextCategoryBtn.setDisabled(false);
}
if(currentPage !== 0) {
if(currentPage + 1 !== commandGroups.length) {
nextCategoryBtn.setDisabled(false);
previousCategoryBtn.setDisabled(true);
previousCategoryBtn.setDisabled(false);
}
if(currentPage + 1 === commandGroups.length) {
@ -159,8 +159,8 @@ export default class extends Command {
await interaction.update({
content: i18next.t('commands:help.helpScreenBtnHelp'),
embeds: [commandGroups[currentPage]!.embed],
components: [[previousCategoryBtn, nextCategoryBtn], [chooseHelpCategory]],
embeds: [ commandGroups[currentPage]!.embed ],
components: [ [ previousCategoryBtn, nextCategoryBtn ], [ chooseHelpCategory ] ],
});
}
});
@ -171,7 +171,8 @@ export default class extends Command {
await helpMsg.edit({
content: i18next.t('commands:help.helpTimedOut'),
embeds: [commandGroups[currentPage]!.embed],
embeds: [ commandGroups[currentPage]!.embed ],
components: [],
});
});
} else {
@ -180,17 +181,18 @@ export default class extends Command {
if(findCommand) {
const commandEmbed = new MessageEmbed();
commandEmbed.setAuthor(i18next.t('commands:help.embedName'));
commandEmbed.setTitle(findCommand.options.name!.toUpperCase());
commandEmbed.setTitle(capitalize(findCommand.options.name!));
commandEmbed.setColor(message.member?.roles.highest.color ?? 0xFFFFFF);
commandEmbed.setTimestamp();
commandEmbed.setDescription(i18next.t('commands:help.commandDescription', {
name: findCommand.options.name,
category: capitalize(findCommand.options.group!),
description: findCommand.options.extendedDescription ?? i18next.t('commands:generic.noExtendedDescription'),
usage: findCommand.options.usage ? `!${findCommand.options.name} ${findCommand.options.usage}` : i18next.t('commands:generic.noUsage'),
}));
await message.channel.send({ embeds: [commandEmbed] });
await message.channel.send({ embeds: [ commandEmbed ] });
} else {
await message.reply(i18next.t('commands:help.unknownCommand'));
}

View file

@ -15,7 +15,6 @@
* along with ArgonBot. If not, see <https: //www.gnu.org/licenses/>.
*/
import Command from '@structures/command';
import type { Client, Message } from 'discord.js';
import i18next from 'i18next';
import { transpile } from 'typescript';
@ -26,10 +25,11 @@ export default class extends Command {
super(client, file, {
shortDescription: i18next.t('commands:vm.shortDescription'),
extendedDescription: i18next.t('commands:vm.extendedDescription'),
usage: 'js const test = \'test\'; return test;',
args: [
{
name: 'language',
acceptedValues: ['js', 'javascript', 'ts', 'typescript'],
acceptedValues: [ 'js', 'javascript', 'ts', 'typescript' ],
description: i18next.t('commands:vm.languageArg'),
},
{
@ -48,7 +48,7 @@ export default class extends Command {
switch(vmLang.toLowerCase()) {
case 'js':
case 'javascript':
await message.reply(i18next.t('commands:vm.computing', { language: 'JavaScript' }));
await message.channel.send(i18next.t('commands:vm.computing', { language: 'JavaScript' }));
try {
let returnVal: string;
@ -57,14 +57,14 @@ export default class extends Command {
else
returnVal = await javascriptVM.run(`(() => {${code}})()`);
await message.reply(`\`\`\`js\n${returnVal}\`\`\``);
await message.channel.send(`\`\`\`js\n${returnVal}\`\`\``);
} catch(err) {
await message.reply(i18next.t('commands:vm.error', { error: err.message, language: 'JavaScript' }));
}
break;
case 'ts':
case 'typescript':
await message.reply(i18next.t('commands:vm.computing', { language: 'TypeScript' }));
await message.channel.send(i18next.t('commands:vm.computing', { language: 'TypeScript' }));
try {
const jsCode = transpile(code);
@ -75,7 +75,7 @@ export default class extends Command {
else
returnVal = await javascriptVM.run(`(() => {${jsCode}}()`);
await message.reply(`\`\`\`js\n${returnVal}\`\`\``);
await message.channel.send(`\`\`\`js\n${returnVal}\`\`\``);
} catch(err) {
await message.reply(i18next.t('commands:vm.error', { error: err.message, language: 'TypeScript' }));
}

View file

@ -21,9 +21,10 @@ import ArgonClient from '@lib/ArgonClient';
import { Defaults } from '@utils/defaults';
import { debug, error, fatal, info, verbose } from '@utils/logger';
import { ECommandRunIn, ELoggingScope } from '@utils/types';
import { walkDir } from '@utils/utils';
import { connectToDB, walkDir } from '@utils/utils';
import chalk from 'chalk';
import config from 'config';
import { Collection } from 'discord.js';
import figlet from 'figlet';
import gradient from 'gradient-string';
import i18next from 'i18next';
@ -36,6 +37,7 @@ import { Validator } from 'jsonschema';
import { DateTime } from 'luxon';
import process from 'process';
const commandCooldowns: Collection<string, Collection<string, number>> = new Collection();
let isBotReady = false;
info('Starting bot... Please wait!', ELoggingScope.Startup);
@ -69,7 +71,8 @@ figlet('Argon Bot', (err, data) => {
});
const client = new ArgonClient({
intents: ['GUILDS', 'GUILD_MESSAGES'],
intents: [ 'GUILDS', 'GUILD_MESSAGES', 'DIRECT_MESSAGES' ],
partials: [ 'CHANNEL' ],
});
client.on('message', async (msg) => {
@ -89,26 +92,56 @@ client.on('message', async (msg) => {
if(findCommand.options.ownerOnly && msg.author.id !== config.get('owner')) {
await msg.reply(i18next.t('commands:errors.ownerOnly'));
msg.channel.stopTyping();
return;
}
if((findCommand.options.runIn === ECommandRunIn.DM) && msg.channel.type !== 'dm') {
await msg.reply(i18next.t('commands:errors.dmsOnly'));
msg.channel.stopTyping();
return;
}
if((findCommand.options.runIn === ECommandRunIn.Server) && msg.channel.type !== 'text') {
await msg.reply(i18next.t('commands:errors.serverOnly'));
msg.channel.stopTyping();
return;
}
if(msg.author.id !== config.get('owner')) {
if(!commandCooldowns.has(findCommand.options.name!)) {
commandCooldowns.set(findCommand.options.name!, new Collection());
}
const now = Date.now();
const timestamps = commandCooldowns.get(findCommand.options.name!);
const cooldownAmount = findCommand.options.cooldown! * 1000;
if(timestamps!.has(msg.author.id)) {
const expirationTime = timestamps!.get(msg.author.id)! + cooldownAmount;
if(now < expirationTime) {
const timeLeft = (expirationTime - now) / 1000;
await msg.reply(i18next.t('commands:errors.cooldownError', {
time: timeLeft.toFixed(1),
command: findCommand.options.name,
}));
msg.channel.stopTyping();
return;
}
}
timestamps!.set(msg.author.id, now);
setTimeout(() => timestamps!.delete(msg.author.id), cooldownAmount);
}
try {
info(`Command ${findCommand.options.name} is being ran in ${msg.guild ? msg.guild.name : 'DMs'} by ${msg.author.username}`, ELoggingScope.Command);
await findCommand.run(msg, ...args);
info(`Finished running ${findCommand.options.name} in ${msg.guild ? msg.guild.name : `${msg.author.username} DMs`}`, ELoggingScope.Command);
msg.channel.stopTyping();
} catch(e) {
console.error(e);
error(`An error has occurred while running ${findCommand.options.name}!\n${e.message}`, ELoggingScope.Command);
await msg.reply(i18next.t('commands:errors.runError', { error: e.message }));
msg.channel.stopTyping();
@ -119,14 +152,14 @@ client.on('ready', async () => {
info('Loading translations...', ELoggingScope.Startup);
await i18next.use(Fluent).use(Backend).init({
supportedLngs: ['en-US', 'owo'],
supportedLngs: [ 'en-US', 'owo' ],
lng: 'en-US',
fallbackLng: 'en-US',
defaultNS: 'common',
fallbackNS: 'common',
ns: ['common', 'commands'],
ns: [ 'common', 'commands' ],
backend: {
backends: [FSBackend],
backends: [ FSBackend ],
backendOptions: [
{
loadPath: `${process.cwd()}/translations/{{lng}}/{{ns}}.json`,
@ -137,7 +170,7 @@ client.on('ready', async () => {
info('Finished loading translations.', ELoggingScope.Startup);
info('Loading commands...', ELoggingScope.Startup);
info('Loading commands...', ELoggingScope.Command);
try {
const files = await walkDir(`${__dirname}/commands`);
@ -151,16 +184,20 @@ client.on('ready', async () => {
client.commands.set(command.options.name, command);
debug(`Loaded command ${command.options.name}`, ELoggingScope.Startup);
debug(`Loaded command ${command.options.name}`, ELoggingScope.Command);
}
});
info(`Finished loading commands! Found ${client.commands.size} commands.`, ELoggingScope.Startup);
info(`Finished loading commands! Found ${client.commands.size} commands.`, ELoggingScope.Command);
} catch(err) {
console.log(err);
fatal(`An error has occurred while attempting to load command files! Please see error below\n${err.message}`, ELoggingScope.Startup);
fatal(`An error has occurred while attempting to load command files! Please see error below\n${err.message}`, ELoggingScope.Command);
}
info('Creating Database Pool...', ELoggingScope.Database);
await connectToDB(config.get('db'));
info('Finished creating Database Pool', ELoggingScope.Database);
info('Bot is ready!', ELoggingScope.Startup);
debug(`Total number of Servers: ${client.guilds.cache.size}`, ELoggingScope.Startup);
debug(`Total number of Users: ${client.users.cache.size}`, ELoggingScope.Startup);

View file

@ -18,9 +18,11 @@ import type Command from '@structures/command';
import { Client, ClientOptions, Collection } from 'discord.js';
export default class extends Client {
public override readonly commands: Collection<string, Command> = new Collection();
public commands: Collection<string, Command>;
public constructor(options: ClientOptions) {
super(options);
this.commands = new Collection<string, Command>();
}
}

View file

@ -0,0 +1,16 @@
/*
* This file is part of ArgonBot
*
* ArgonBot is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ArgonBot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ArgonBot. If not, see <https: //www.gnu.org/licenses/>.
*/

View file

@ -31,6 +31,7 @@ export default abstract class Command {
const defaultOptions: ICommandOptions = {
name: path.basename(this.file, path.extname(this.file)),
group: path.basename(path.dirname(this.file)) === 'commands' ? '' : path.basename(path.dirname(this.file)),
cooldown: 5,
};
this.options = config.util.extendDeep(defaultOptions, options);

View file

@ -14,13 +14,10 @@
* You should have received a copy of the GNU General Public License
* along with ArgonBot. If not, see <https: //www.gnu.org/licenses/>.
*/
import type ArgonClient from '@lib/ArgonClient';
import type Command from '@structures/command';
declare module 'discord.js' {
export interface Client {
constructor: typeof ArgonClient;
readonly commands: Collection<string, Command>;
interface Client{
commands: Collection<string, Command>;
}
}

View file

@ -19,7 +19,7 @@ export const Defaults = {
logLevel: 'info',
},
configSchema: {
required: ['token', 'logLevel', 'prefix', 'owner'],
required: [ 'token', 'logLevel', 'prefix', 'owner', 'db' ],
type: 'object',
properties: {
token: {
@ -46,6 +46,33 @@ export const Defaults = {
$id: '#/properties/owner',
type: 'string',
},
db: {
$id: '#/properties/db',
type: 'object',
required: [ 'host', 'port', 'user', 'password', 'database' ],
properties: {
host: {
$id: '#/properties/db/host',
type: 'string',
},
port: {
$id: '#/properties/db/port',
type: 'string',
},
user: {
$id: '#/properties/db/user',
type: 'string',
},
password: {
$id: '#/properties/db/password',
type: 'string',
},
database: {
$id: '#/properties/db/database',
type: 'string',
},
},
},
},
additionalProperties: false,
},

View file

@ -21,6 +21,7 @@ export enum ELoggingScope {
Command = 'COMMAND',
Payload = 'PAYLOAD',
Query = 'QUERY',
Database = 'DATABASE',
}
export enum ECommandRunIn {
@ -37,6 +38,7 @@ export interface ICommandOptions {
extendedDescription?: string;
usage?: string;
ownerOnly?: boolean;
cooldown?: number;
runIn?: ECommandRunIn;
args?: {
name: string;
@ -47,4 +49,9 @@ export interface ICommandOptions {
}[];
}
export interface IGuildSettings {
id: string,
locale: string;
}
// Type Aliases

View file

@ -14,8 +14,14 @@
* You should have received a copy of the GNU General Public License
* along with ArgonBot. If not, see <https: //www.gnu.org/licenses/>.
*/
import { error, info } from '@utils/logger';
import { ELoggingScope } from '@utils/types';
import fs from 'fs';
import path from 'path';
import pg, { QueryResult } from 'pg';
import type { SQLStatement } from 'sql-template-strings';
let pool: pg.Pool;
export const walkDir = async (dir: string): Promise<string[]> => {
let results: string[] = [];
@ -53,3 +59,48 @@ export const walkDir = async (dir: string): Promise<string[]> => {
});
});
};
export const capitalize = (string: string): string => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
export const connectToDB = async (connectionData: pg.PoolConfig): Promise<void> => {
pool = new pg.Pool(connectionData);
pool.on('connect', () => {
info('Connected to the Postgres Database!', ELoggingScope.Database);
});
pool.on('error', (err) => {
error(`An error has occurred with node-postgres!\n${err.message}`, ELoggingScope.Database);
});
};
export const query = async <t>(query: SQLStatement): Promise<QueryResult<t> | void> => {
if(!pool) return error('Attempted to query to the Database when a connection has not been made yet... Discarding' +
' request.', ELoggingScope.Query);
else {
const client = await pool.connect();
try {
info('BEGIN', ELoggingScope.Query);
await client.query('BEGIN');
info(query.text, ELoggingScope.Query);
const result = await client.query<t>(query);
info('COMMIT', ELoggingScope.Query);
await client.query('COMMIT');
return result;
} catch(e) {
error(`An error has occurred while attempting to query "${query}"... Rolling back changes`, ELoggingScope.Database);
info('ROLLBACK', ELoggingScope.Query);
await client.query('ROLLBACK');
throw e;
} finally {
client.release();
}
}
};

View file

@ -30,7 +30,7 @@ describe('verbose()', () => {
verbose('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch('Test Message')).to.be.true;
});
it('check if Logging Scopes are being logged', () => {
verbose('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch(/COMMAND/)).to.be.true;
@ -51,7 +51,7 @@ describe('debug()', () => {
debug('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch('Test Message')).to.be.true;
});
it('check if Logging Scopes are being logged', () => {
debug('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch(/COMMAND/)).to.be.true;
@ -72,7 +72,7 @@ describe('info()', () => {
info('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch('Test Message')).to.be.true;
});
it('check if Logging Scopes are being logged', () => {
info('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch(/COMMAND/)).to.be.true;
@ -93,7 +93,7 @@ describe('warn()', () => {
warn('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch('Test Message')).to.be.true;
});
it('check if Logging Scopes are being logged', () => {
warn('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch(/COMMAND/)).to.be.true;
@ -114,7 +114,7 @@ describe('error()', () => {
error('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch('Test Message')).to.be.true;
});
it('check if Logging Scopes are being logged', () => {
error('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch(/COMMAND/)).to.be.true;
@ -135,7 +135,7 @@ describe('fatal()', () => {
fatal('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch('Test Message')).to.be.true;
});
it('check if Logging Scopes are being logged', () => {
fatal('Test Message', ELoggingScope.Command);
expect(spy.calledWithMatch(/COMMAND/)).to.be.true;

View file

@ -18,14 +18,24 @@
"nextCategoryBtn": "Next Category",
"previousCategoryBtn": "Previous Category",
"helpTimedOut": "Timed Out",
"commandDescription": "Name: { $name }\nCategory: { $category }\nDescription: { $description }\nUsage: { $usage }",
"commandDescription": "Name: `{ $name }`\nCategory: `{ $category }`\nDescription: `{ $description }`\nUsage: `{ $usage }`",
"categoryPlaceholder": "Choose a category!"
},
"settings": {
"shortDescription": "Changes the current server settings",
"extendedDescription": "Changes the current server settings for better server customization",
"actionArg": "What action you want to take",
"settingArg": "What setting you want to view/set\nOr optionally, you can put 'help' if you are unsure what to do with that action",
"valueArg": "The value you want to set (This is ignored if you are only getting/resetting a setting).",
"localeAlreadySet": "The language of the bot in this server is already set to { $locale }!",
"localeSuccessfullySet": "The language of the bot has been successfully set to { $locale }!"
},
"errors": {
"ownerOnly": "Only the bot owner can run this command!",
"dmsOnly": "You can only run this command in DMs!",
"serverOnly": "You can only run this command in a server!",
"runError": "I'm sorry but an error has occurred while running this command! Please file an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```"
"runError": "I'm sorry but an error has occurred while running this command! Please file an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```",
"cooldownError": "Please wait { $time } more second(s) before reusing the `{ $command }` command."
},
"generic": {
"noShortDescription": "No short description given!",

View file

@ -18,14 +18,15 @@
"nextCategoryBtn": "Nyext Categowy",
"previousCategoryBtn": "Pwevious Categowy",
"helpTimedOut": "Timed Out",
"commandDescription": "Nyame: { $name }\nCategowy: { $category }\nDescwiption: { $description }\nUsage: { $usage }",
"commandDescription": "Nyame: `{ $name }`\nCategowy: `{ $category }`\nDescwiption: `{ $description }`\nUsage: `{ $usage }`",
"categoryPlaceholder": "Choose a categowy (・`ω´・)"
},
"errors": {
"ownerOnly": "Onwy the bot ownyew can wun this command ^w^",
"dmsOnly": "You can onwy wun this command in DMs owo",
"serverOnly": "You can onwy wun this command in a sewvew owo",
"runError": "I'm sowwy but an ewwow has occuwwed whiwe wunnying this command ;;w;; Pwease fiwe an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```"
"runError": "I'm sowwy but an ewwow has occuwwed whiwe wunnying this command ;;w;; Pwease fiwe an issue to https://code.relms.dev/Relms/ArgonBot!\n```{ $error }```",
"cooldownError": "Pwease wait { $time } mowe second(s) befowe weusing the `{ $command }` command."
},
"generic": {
"noShortDescription": "Nyo showt descwiption given >w<",

View file

@ -25,9 +25,7 @@
"strictPropertyInitialization": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"moduleResolution": "Node",
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noPropertyAccessFromIndexSignature": true,
"noUncheckedIndexedAccess": true,
@ -52,9 +50,19 @@
"inlineSourceMap": true,
"inlineSources": true,
"baseUrl": ".",
"moduleResolution": "Node",
"plugins": [
{
"name": "typescript-eslint-language-service"
},
{
"name": "ts-sql-plugin",
"mock": "0",
"cost_pattern": "/\\(cost=\\d+\\.?\\d*\\.\\.(\\d+\\.?\\d*)/",
"error_cost": null,
"warn_cost": null,
"info_cost": null,
"schema_command": "pg"
}
],
"paths": {

5116
yarn.lock

File diff suppressed because it is too large Load diff