basic structure
This commit is contained in:
commit
60b215760b
|
@ -0,0 +1,2 @@
|
|||
node_modules/
|
||||
out/
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"reporter": "@mochajs/multi-reporter",
|
||||
"ui": ["bdd"]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"mocha-junit-reporter": true,
|
||||
"spec": true
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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,
|
||||
];
|
|
@ -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!');
|
||||
},
|
||||
}
|
|
@ -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 */
|
||||
|
|
@ -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,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();
|
||||
|
|
@ -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/**/*"
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue