1
0
Fork 0

basic structure

This commit is contained in:
Sean Sube 2022-12-14 23:41:21 -06:00
commit 60b215760b
14 changed files with 2434 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules/
out/

5
.mocharc.json Normal file
View File

@ -0,0 +1,5 @@
{
"reporter": "@mochajs/multi-reporter",
"ui": ["bdd"]
}

5
.reporters.json Normal file
View File

@ -0,0 +1,5 @@
{
"mocha-junit-reporter": true,
"spec": true
}

61
Makefile Normal file
View File

@ -0,0 +1,61 @@
.PHONY: build ci clean lint package run test
# JS targets
node_modules: deps
ci: deps lint build-shebang test
clean:
rm -rf node_modules/
rm -rf out/
deps:
yarn install
build: deps
yarn tsc
build-shebang: build
sed -i '1s;^;#! /usr/bin/env node\n\n;g' $(shell pwd)/out/src/index.js
chmod ug+x out/src/index.js
COVER_OPTS := --all \
--exclude ".eslintrc.js" \
--exclude "docs/**" \
--exclude "out/coverage/**" \
--exclude "vendor/**" \
--check-coverage \
--branches 90 \
--lines 90 \
--functions 75 \
--statements 90 \
--reporter=text-summary \
--reporter=lcov \
--reporter=cobertura \
--report-dir=out/coverage
MOCHA_OPTS := --async-only \
--check-leaks \
--forbid-only \
--recursive \
--require source-map-support/register \
--require out/test/setup.js \
--sort
lint: deps
yarn eslint src/ test/ --ext .ts,.tsx
test: build
MOCHA_FILE=out/test-results.xml yarn c8 $(COVER_OPTS) mocha $(MOCHA_OPTS) "out/**/Test*.js"
# image-building targets
image-imager:
DOCKER_ROOT="$(shell pwd)" /imager/build.sh build push
image-podman:
podman build -f Containerfile .
# run targets
run: build
node out/src/index.js

46
package.json Normal file
View File

@ -0,0 +1,46 @@
{
"name": "conan-discord",
"version": "0.1.0",
"description": "Conan Exiles Discord bot",
"main": "out/src/index.js",
"author": "Sean Sube <seansube@gmail.com>",
"license": "MIT",
"type": "module",
"dependencies": {
"discord.js": "^14.7.1"
},
"devDependencies": {
"@apextoaster/js-utils": "^0.5.0",
"@istanbuljs/nyc-config-typescript": "^1.0.2",
"@mochajs/multi-reporter": "^1.1.0",
"@types/chai-as-promised": "^7.1.5",
"@types/mocha": "^10.0.1",
"@types/sinon-chai": "^3.2.9",
"@types/yargs": "^17.0.17",
"c8": "^7.12.0",
"chai": "^4.3.7",
"chai-as-promised": "^7.1.1",
"eslint": "^8.29.0",
"eslint-plugin-chai": "^0.0.1",
"eslint-plugin-chai-expect": "^3.0.0",
"eslint-plugin-chai-expect-keywords": "^2.1.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-mocha": "^10.1.0",
"eslint-plugin-no-null": "^1.0.2",
"eslint-plugin-sonarjs": "^0.17.0",
"fast-check": "^3.4.0",
"mocha": "^10.2.0",
"mocha-foam": "^0.1.10",
"mocha-junit-reporter": "^2.2.0",
"noicejs": "^5.0.0-3",
"sinon": "^15.0.0",
"sinon-chai": "^3.7.0",
"source-map-support": "^0.5.21",
"tslib": "^2.4.1",
"typescript": "^4.9.4",
"yargs": "^17.6.2"
},
"nyc": {
"extends": "@istanbuljs/nyc-config-typescript"
}
}

22
src/args.ts Normal file
View File

@ -0,0 +1,22 @@
import yargs from 'yargs';
export interface ParsedArgs {
token: string;
}
export async function parseArgs(argv: Array<string>): Promise<ParsedArgs> {
const parser = yargs(argv).usage('Usage: conan-discord [options]')
.options({
token: {
default: '',
desc: 'bot token',
type: 'string',
},
})
.help()
.exitProcess(false);
const args = await parser.parse(argv);
return args;
}

11
src/command/index.ts Normal file
View File

@ -0,0 +1,11 @@
import { SlashCommandBuilder } from 'discord.js';
import { ping } from './ping.js';
export interface Command {
data: SlashCommandBuilder;
execute: Function;
}
export const COMMANDS: Array<Command> = [
ping,
];

10
src/command/ping.ts Normal file
View File

@ -0,0 +1,10 @@
import { SlashCommandBuilder } from 'discord.js';
export const ping = {
data: new SlashCommandBuilder()
.setName('ping')
.setDescription('Replies with Pong!'),
async execute(interaction: any) {
await interaction.reply('Pong!');
},
}

15
src/index.ts Normal file
View File

@ -0,0 +1,15 @@
import process from 'node:process';
import { ExitCode, main } from './main.js';
const ARGS_START = 2; // trim the first few, yargs does not like them
/* c8 ignore start */
main(process.argv.slice(ARGS_START)).then((code) => {
process.exit(code);
}).catch((err) => {
console.error('uncaught error from main', err);
process.exit(ExitCode.ERROR);
});
/* c8 ignore stop */

51
src/main.ts Normal file
View File

@ -0,0 +1,51 @@
import { signal, SIGNAL_STOP } from '@apextoaster/js-utils';
import { Client, Events, GatewayIntentBits, Partials } from 'discord.js';
import { parseArgs } from './args.js';
import { COMMANDS } from './command/index.js';
export enum ExitCode {
SUCCESS = 0,
ERROR = 1,
}
export async function main(argv: Array<string>): Promise<ExitCode> {
const args = await parseArgs(argv);
console.log('conan-discord', args);
for (const cmd of COMMANDS) {
console.log(cmd.data.toJSON());
}
const client = new Client({
intents: [
GatewayIntentBits.DirectMessages,
GatewayIntentBits.DirectMessageReactions,
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.MessageContent,
],
partials: [
Partials.Channel,
],
});
client.once(Events.ClientReady, c => {
console.log(`Ready! Logged in as ${c.user.tag}`);
});
client.on(Events.MessageCreate, (interaction: any) => {
console.log(interaction);
// run slash commands here
});
client.login(args.token);
await signal(SIGNAL_STOP);
return ExitCode.SUCCESS;
}

0
src/types.ts Normal file
View File

21
test/setup.ts Normal file
View File

@ -0,0 +1,21 @@
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import sinonChai from 'sinon-chai';
export function setupTests(): void {
/**
* This will break the whole test run if any test leaks an unhandled rejection.
*/
process.on('unhandledRejection', (reason, promise) => {
/* c8 ignore next 3 */
// eslint-disable-next-line no-console
console.error('unhandled error during tests', reason);
process.exit(1);
});
chai.use(chaiAsPromised);
chai.use(sinonChai);
}
setupTests();

45
tsconfig.json Normal file
View File

@ -0,0 +1,45 @@
{
"compileOnSave": false,
"compilerOptions": {
"allowJs": false,
"allowSyntheticDefaultImports": true,
"declaration": true,
"declarationMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"lib": [
"es2017",
"esnext.asynciterable"
],
"module": "esnext",
"moduleResolution": "node",
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"outDir": "out",
"sourceMap": true,
"strict": true,
"strictNullChecks": true,
"target": "es2017",
"types": [
"chai-as-promised",
"mocha",
"node",
"sinon-chai"
],
"typeRoots": [
"node_modules/@types",
"node_modules",
"vendor"
]
},
"exclude": [
"node_modules"
],
"include": [
"src/**/*",
"test/**/*"
]
}

2140
yarn.lock Normal file

File diff suppressed because it is too large Load Diff