mirror of https://github.com/AlphaNecron/Void.git
build: converted everything into typescript
This commit is contained in:
parent
4553004c29
commit
91482bfd68
|
@ -11,6 +11,7 @@ prefix = '&'
|
||||||
token = ''
|
token = ''
|
||||||
admin = ['']
|
admin = ['']
|
||||||
log_channel = ''
|
log_channel = ''
|
||||||
|
default_uid = 1
|
||||||
hostname = 'example.com'
|
hostname = 'example.com'
|
||||||
|
|
||||||
[shortener]
|
[shortener]
|
||||||
|
|
16
package.json
16
package.json
|
@ -1,30 +1,28 @@
|
||||||
{
|
{
|
||||||
"name": "void",
|
"name": "void",
|
||||||
"version": "0.3.0",
|
"version": "0.4.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14"
|
"node": ">=14"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_ENV=development node server",
|
"dev": "NODE_ENV=development ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\" server",
|
||||||
"build": "npm-run-all build:schema build:next",
|
"build": "npm-run-all build:schema build:next",
|
||||||
"build:next": "next build",
|
"build:next": "next build",
|
||||||
"build:schema": "prisma generate --schema=prisma/schema.prisma",
|
"build:schema": "prisma generate --schema=prisma/schema.prisma",
|
||||||
"start:server": "node server",
|
"start": "ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\" server",
|
||||||
"start:twilight": "ts-node --compiler-options \"{\\\"module\\\":\\\"commonjs\\\"}\" twilight",
|
|
||||||
"start": "npm-run-all -p start:server start:twilight",
|
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"lint": "next lint --fix"
|
"lint": "next lint --fix"
|
||||||
},
|
},
|
||||||
"prisma": {
|
"prisma": {
|
||||||
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
|
"seed": "ts-node --compiler-options {\"module\":\"commonjs\"} prisma/seed.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/react": "^1.6.8",
|
"@chakra-ui/react": "^1.6.8",
|
||||||
"@emotion/react": "^11",
|
"@emotion/react": "^11",
|
||||||
"@emotion/styled": "^11",
|
"@emotion/styled": "^11",
|
||||||
"@iarna/toml": "^2.2.5",
|
"@iarna/toml": "^2.2.5",
|
||||||
"@prisma/client": "^3.1.1",
|
"@prisma/client": "^3.2.0",
|
||||||
"@reduxjs/toolkit": "^1.6.1",
|
"@reduxjs/toolkit": "^1.6.1",
|
||||||
"argon2": "^0.28.2",
|
"argon2": "^0.28.2",
|
||||||
"cookie": "^0.4.1",
|
"cookie": "^0.4.1",
|
||||||
|
@ -34,7 +32,7 @@
|
||||||
"framer-motion": "^4",
|
"framer-motion": "^4",
|
||||||
"multer": "^1.4.3",
|
"multer": "^1.4.3",
|
||||||
"next": "^11.1.2",
|
"next": "^11.1.2",
|
||||||
"prisma": "^3.1.1",
|
"prisma": "^3.2.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-dropzone": "^11.4.2",
|
"react-dropzone": "^11.4.2",
|
||||||
|
@ -48,7 +46,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^13.2.0",
|
"@commitlint/cli": "^13.2.0",
|
||||||
"@commitlint/config-conventional": "^13.2.0",
|
"@commitlint/config-conventional": "^13.2.0",
|
||||||
"@types/node": "^14.14.31",
|
"@types/node": "^16.10.3",
|
||||||
"@types/react": "^17.0.27",
|
"@types/react": "^17.0.27",
|
||||||
"@typescript-eslint/parser": "^4.32.0",
|
"@typescript-eslint/parser": "^4.32.0",
|
||||||
"eslint": "7.32.0",
|
"eslint": "7.32.0",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const { error } = require('../src/lib/logger');
|
import { error } from '../src/lib/logger';
|
||||||
const prismaRun = require('./prismaRun');
|
import prismaRun from './prismaRun';
|
||||||
|
|
||||||
module.exports = async (config) => {
|
export default async function(config) {
|
||||||
try {
|
try {
|
||||||
await prismaRun(config.core.database_url, ['migrate', 'deploy']);
|
await prismaRun(config.core.database_url, ['migrate', 'deploy']);
|
||||||
await prismaRun(config.core.database_url, ['generate'], true);
|
await prismaRun(config.core.database_url, ['generate'], true);
|
|
@ -1,7 +1,7 @@
|
||||||
const { spawn } = require('child_process');
|
import { spawn } from 'child_process';
|
||||||
const { join } = require('path');
|
import { join } from 'path';
|
||||||
|
|
||||||
module.exports = (url, args, nostdout = false) => {
|
export default function run(url: string, args: string[], nostdout?: boolean): Promise<string> {
|
||||||
return new Promise((res, rej) => {
|
return new Promise((res, rej) => {
|
||||||
const proc = spawn(join(process.cwd(), 'node_modules', '.bin', 'prisma'), args, {
|
const proc = spawn(join(process.cwd(), 'node_modules', '.bin', 'prisma'), args, {
|
||||||
env: {
|
env: {
|
||||||
|
@ -9,9 +9,7 @@ module.exports = (url, args, nostdout = false) => {
|
||||||
...process.env
|
...process.env
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let a = '';
|
let a = '';
|
||||||
|
|
||||||
proc.stdout.on('data', d => {
|
proc.stdout.on('data', d => {
|
||||||
if (!nostdout) console.log(d.toString());
|
if (!nostdout) console.log(d.toString());
|
||||||
a += d.toString();
|
a += d.toString();
|
|
@ -1,15 +1,15 @@
|
||||||
const next = require('next');
|
import { PrismaClient } from '@prisma/client';
|
||||||
const { createServer } = require('http');
|
import { mkdir, readFile, stat } from 'fs/promises';
|
||||||
const { stat, mkdir, readFile } = require('fs/promises');
|
import { createServer } from 'http';
|
||||||
const { extname } = require('path');
|
import next from 'next';
|
||||||
const { PrismaClient } = require('@prisma/client');
|
import { extname, join } from 'path';
|
||||||
const validateConfig = require('./validateConfig');
|
import deployDb from '../scripts/deployDb';
|
||||||
const { info, error } = require('../src/lib/logger');
|
import prismaRun from '../scripts/prismaRun';
|
||||||
const prismaRun = require('../scripts/prismaRun');
|
import { error, info } from '../src/lib/logger';
|
||||||
const configReader = require('../src/lib/configReader');
|
import mimetypes from '../src/lib/mimetypes';
|
||||||
const mimes = require('../src/lib/mimetype');
|
import validate from '../src/lib/validateConfig';
|
||||||
const deployDb = require('../scripts/deployDb');
|
import readConfig from '../src/lib/configReader';
|
||||||
const { join } = require('path');
|
import start from '../twilight/twilight';
|
||||||
|
|
||||||
info('SERVER', 'Starting Void server');
|
info('SERVER', 'Starting Void server');
|
||||||
|
|
||||||
|
@ -17,22 +17,26 @@ const dev = process.env.NODE_ENV === 'development';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const config = await validateConfig(configReader());
|
const config = await validate(readConfig());
|
||||||
const data = await prismaRun(config.core.database_url, ['migrate', 'status'], true);
|
const data = await prismaRun(config.core.database_url, ['migrate', 'status'], true);
|
||||||
if (data.match(/Following migrations? have not yet been applied/)) {
|
if (data.match(/Following migrations? have not yet been applied/)) {
|
||||||
info('DB', 'Some migrations are not applied, applying them now...');
|
info('DB', 'Some migrations are not applied, applying them now...');
|
||||||
await deployDb(config);
|
await deployDb(config);
|
||||||
info('DB', 'Finished applying migrations');
|
info('DB', 'Finished applying migrations');
|
||||||
await prismaRun(config.core.database_url, ['db', 'seed'], false)
|
await prismaRun(config.core.database_url, ['db', 'seed'])
|
||||||
}
|
}
|
||||||
process.env.DATABASE_URL = config.core.database_url;
|
process.env.DATABASE_URL = config.core.database_url;
|
||||||
|
if (config.bot.enabled) {
|
||||||
|
if (!config.bot.token) error('BOT', 'Token is not specified');
|
||||||
|
else start(config);
|
||||||
|
}
|
||||||
await stat('./.next');
|
await stat('./.next');
|
||||||
await mkdir(config.uploader.directory, { recursive: true });
|
await mkdir(config.uploader.directory, { recursive: true });
|
||||||
const app = next({
|
const app = next({
|
||||||
dir: '.',
|
dir: '.',
|
||||||
dev,
|
dev,
|
||||||
quiet: dev
|
quiet: dev
|
||||||
}, config.core.port, config.core.host);
|
});
|
||||||
await app.prepare();
|
await app.prepare();
|
||||||
const handle = app.getRequestHandler();
|
const handle = app.getRequestHandler();
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
@ -58,7 +62,7 @@ const dev = process.env.NODE_ENV === 'development';
|
||||||
if (file) {
|
if (file) {
|
||||||
res.setHeader('Content-Type', file.mimetype);
|
res.setHeader('Content-Type', file.mimetype);
|
||||||
} else {
|
} else {
|
||||||
const mimetype = mimes[extname(parts[2])] ?? 'application/octet-stream';
|
const mimetype = mimetypes[extname(parts[2])] ?? 'application/octet-stream';
|
||||||
res.setHeader('Content-Type', mimetype);
|
res.setHeader('Content-Type', mimetype);
|
||||||
}
|
}
|
||||||
res.setHeader('Content-Length', data.byteLength);
|
res.setHeader('Content-Length', data.byteLength);
|
||||||
|
@ -78,9 +82,10 @@ const dev = process.env.NODE_ENV === 'development';
|
||||||
srv.on('listening', async () => {
|
srv.on('listening', async () => {
|
||||||
info('SERVER', `Listening on ${config.core.host}:${config.core.port}`);
|
info('SERVER', `Listening on ${config.core.host}:${config.core.port}`);
|
||||||
});
|
});
|
||||||
srv.listen(config.core.port, config.core.host ?? '0.0.0.0');
|
srv.listen(config.core.port, config.core.host);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e.message && e.message.startsWith('Could not find a production')) {
|
if (e.message && e.message.startsWith('Could not find a production')) {
|
||||||
|
console.log(e.message);
|
||||||
error('WEB', 'There is no production build - run yarn build');
|
error('WEB', 'There is no production build - run yarn build');
|
||||||
} else if (e.code && e.code === 'ENOENT') {
|
} else if (e.code && e.code === 'ENOENT') {
|
||||||
if (e.path === './.next') error('WEB', 'There is no production build - run yarn build');
|
if (e.path === './.next') error('WEB', 'There is no production build - run yarn build');
|
|
@ -1,4 +1,5 @@
|
||||||
import configReader from './configReader';
|
import readConfig from './configReader';
|
||||||
import type { Config } from './types';
|
import type { Config } from './types';
|
||||||
if (!global.config) global.config = configReader() as Config;
|
|
||||||
|
if (!global.config) global.config = readConfig() as Config;
|
||||||
export default global.config;
|
export default global.config;
|
|
@ -1,6 +1,7 @@
|
||||||
const { join } = require('path');
|
import { existsSync, readFileSync } from 'fs';
|
||||||
const { info, error } = require('./logger');
|
import { join } from 'path';
|
||||||
const { existsSync, readFileSync } = require('fs');
|
import { error, info } from './logger';
|
||||||
|
import parse from '@iarna/toml/parse-string';
|
||||||
|
|
||||||
const e = (val, type, fn) => ({ val, type, fn });
|
const e = (val, type, fn) => ({ val, type, fn });
|
||||||
|
|
||||||
|
@ -21,13 +22,14 @@ const envValues = [
|
||||||
e('BOT_TOKEN', 'string', (c, v) => c.bot.token = v),
|
e('BOT_TOKEN', 'string', (c, v) => c.bot.token = v),
|
||||||
e('BOT_ADMINS', 'array', (c, v) => v ? c.bot.admins = v : c.bot.admins = []),
|
e('BOT_ADMINS', 'array', (c, v) => v ? c.bot.admins = v : c.bot.admins = []),
|
||||||
e('BOT_LOG_CHANNEL', 'string', (c, v) => c.bot.log_channel = v),
|
e('BOT_LOG_CHANNEL', 'string', (c, v) => c.bot.log_channel = v),
|
||||||
|
e('BOT_DEFAULT_UID', 'string', (c, v) => c.bot.default_uid = v),
|
||||||
e('BOT_HOSTNAME', 'string', (c, v) => c.bot.hostname = v),
|
e('BOT_HOSTNAME', 'string', (c, v) => c.bot.hostname = v),
|
||||||
|
|
||||||
e('SHORTENER_ROUTE', 'string', (c, v) => c.shortener.route = v),
|
e('SHORTENER_ROUTE', 'string', (c, v) => c.shortener.route = v),
|
||||||
e('SHORTENER_LENGTH', 'number', (c, v) => c.shortener.length = v)
|
e('SHORTENER_LENGTH', 'number', (c, v) => c.shortener.length = v)
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports = () => {
|
export default function readConfig() {
|
||||||
if (!existsSync(join(process.cwd(), 'config.toml'))) {
|
if (!existsSync(join(process.cwd(), 'config.toml'))) {
|
||||||
error('CONFIG', 'Config file not found, please create one.');
|
error('CONFIG', 'Config file not found, please create one.');
|
||||||
return tryReadEnv();
|
return tryReadEnv();
|
||||||
|
@ -35,7 +37,7 @@ module.exports = () => {
|
||||||
if (process.env.JEST_WORKER_ID) return;
|
if (process.env.JEST_WORKER_ID) return;
|
||||||
info('CONFIG', 'Reading config file');
|
info('CONFIG', 'Reading config file');
|
||||||
const str = readFileSync(join(process.cwd(), 'config.toml'), 'utf8');
|
const str = readFileSync(join(process.cwd(), 'config.toml'), 'utf8');
|
||||||
const parsed = require('@iarna/toml/parse-string')(str);
|
const parsed = parse(str);
|
||||||
return parsed;
|
return parsed;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -60,6 +62,7 @@ function tryReadEnv() {
|
||||||
prefix: undefined,
|
prefix: undefined,
|
||||||
admins: undefined,
|
admins: undefined,
|
||||||
log_channel: undefined,
|
log_channel: undefined,
|
||||||
|
default_uid: undefined,
|
||||||
hostname: undefined
|
hostname: undefined
|
||||||
},
|
},
|
||||||
shortener: {
|
shortener: {
|
||||||
|
@ -70,7 +73,7 @@ function tryReadEnv() {
|
||||||
|
|
||||||
for (let i = 0, L = envValues.length; i !== L; ++i) {
|
for (let i = 0, L = envValues.length; i !== L; ++i) {
|
||||||
const envValue = envValues[i];
|
const envValue = envValues[i];
|
||||||
let value = process.env[envValue.val];
|
let value = process.env[envValue.val] as any;
|
||||||
if (!value) {
|
if (!value) {
|
||||||
envValues[i].fn(config, undefined);
|
envValues[i].fn(config, undefined);
|
||||||
} else {
|
} else {
|
|
@ -1,29 +0,0 @@
|
||||||
const colors = {
|
|
||||||
red: '\x1b[41m',
|
|
||||||
green: '\x1b[42m',
|
|
||||||
yellow: '\x1b[43m',
|
|
||||||
blue: '\x1b[44m',
|
|
||||||
magenta: '\x1b[45m',
|
|
||||||
cyan: '\x1b[46m',
|
|
||||||
reset: '\x1b[0m',
|
|
||||||
black: '\x1b[30m'
|
|
||||||
};
|
|
||||||
|
|
||||||
function log(color, stype, msg, srv) {
|
|
||||||
console.log(`${colors.blue}${colors.black} ${(new Date()).toLocaleTimeString()} ${color} ${srv}/${stype} ${colors.reset} ${msg}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
debug: function(stype, msg) {
|
|
||||||
log(colors.magenta, stype, msg, 'DBUG');
|
|
||||||
},
|
|
||||||
warn: function(stype, msg) {
|
|
||||||
log(colors.yellow, stype, msg, 'WARN');
|
|
||||||
},
|
|
||||||
error: function(stype, msg) {
|
|
||||||
log(colors.red, stype, msg, 'ERR');
|
|
||||||
},
|
|
||||||
info: function(stype, msg) {
|
|
||||||
log(colors.cyan, stype, msg, 'INFO');
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
const colors = {
|
||||||
|
red: '\x1b[41m',
|
||||||
|
green: '\x1b[42m',
|
||||||
|
yellow: '\x1b[43m',
|
||||||
|
blue: '\x1b[44m',
|
||||||
|
magenta: '\x1b[45m',
|
||||||
|
cyan: '\x1b[46m',
|
||||||
|
reset: '\x1b[0m',
|
||||||
|
black: '\x1b[30m'
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Severity { Debug = 'DEBUG', Warn = 'WARN', Error = 'ERR', Info = 'INFO' };
|
||||||
|
|
||||||
|
function log(color: string, type: string, msg, srv = '') {
|
||||||
|
console.log(`${colors.blue}${colors.black} ${(new Date()).toLocaleTimeString()} ${color} ${srv}/${type} ${colors.reset} ${msg}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function debug(type, msg) {
|
||||||
|
log(colors.magenta, type, msg, Severity.Debug);
|
||||||
|
};
|
||||||
|
export function warn(type, msg) {
|
||||||
|
log(colors.yellow, type, msg, Severity.Warn);
|
||||||
|
};
|
||||||
|
export function error(type, msg) {
|
||||||
|
log(colors.red, type, msg, Severity.Error);
|
||||||
|
};
|
||||||
|
export function info(type, msg) {
|
||||||
|
log(colors.cyan, type, msg, Severity.Info);
|
||||||
|
};
|
|
@ -1,4 +1,4 @@
|
||||||
module.exports = {
|
const mimetypes = {
|
||||||
'.aac': 'audio/aac',
|
'.aac': 'audio/aac',
|
||||||
'.abw': 'application/x-abiword',
|
'.abw': 'application/x-abiword',
|
||||||
'.arc': 'application/x-freearc',
|
'.arc': 'application/x-freearc',
|
||||||
|
@ -75,4 +75,6 @@ module.exports = {
|
||||||
'.3gp': 'video/3gpp',
|
'.3gp': 'video/3gpp',
|
||||||
'.3g2': 'video/3gpp2',
|
'.3g2': 'video/3gpp2',
|
||||||
'.7z': 'application/x-7z-compressed'
|
'.7z': 'application/x-7z-compressed'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default mimetypes;
|
|
@ -3,7 +3,7 @@ export interface Core {
|
||||||
secret: string;
|
secret: string;
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
database_url: string
|
database_url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Bot {
|
export interface Bot {
|
||||||
|
@ -12,6 +12,7 @@ export interface Bot {
|
||||||
token: string;
|
token: string;
|
||||||
admins: string[];
|
admins: string[];
|
||||||
log_channel: string;
|
log_channel: string;
|
||||||
|
default_uid: number;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const yup = require('yup');
|
import * as yup from 'yup';
|
||||||
|
|
||||||
const validator = yup.object({
|
const validator = yup.object({
|
||||||
core: yup.object({
|
core: yup.object({
|
||||||
|
@ -14,7 +14,8 @@ const validator = yup.object({
|
||||||
token: yup.string(),
|
token: yup.string(),
|
||||||
admins: yup.array().default([]),
|
admins: yup.array().default([]),
|
||||||
log_channel: yup.string(),
|
log_channel: yup.string(),
|
||||||
hostname: yup.string()
|
default_uid: yup.number().default(1),
|
||||||
|
hostname: yup.string().default('localhost')
|
||||||
}),
|
}),
|
||||||
shortener: yup.object({
|
shortener: yup.object({
|
||||||
allow_vanity: yup.bool().default(false),
|
allow_vanity: yup.bool().default(false),
|
||||||
|
@ -29,10 +30,10 @@ const validator = yup.object({
|
||||||
}).required(),
|
}).required(),
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = async config => {
|
export default async function validate(config) {
|
||||||
try {
|
try {
|
||||||
return await validator.validate(config, { abortEarly: false });
|
return await validator.validate(config, { abortEarly: false });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw `${e.errors.length} errors occured\n${e.errors.map(x => '\t' + x).join('\n')}`;
|
throw `${e.errors.length} errors occured\n${e.errors.map(x => '\t' + x).join('\n')}`;
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -3,7 +3,7 @@ import cfg from 'lib/config';
|
||||||
import generate, { emoji, zws } from 'lib/generators';
|
import generate, { emoji, zws } from 'lib/generators';
|
||||||
import { info } from 'lib/logger';
|
import { info } from 'lib/logger';
|
||||||
import { NextApiReq, NextApiRes, withVoid } from 'lib/middleware/withVoid';
|
import { NextApiReq, NextApiRes, withVoid } from 'lib/middleware/withVoid';
|
||||||
import mimetypes from 'lib/mimetype';
|
import mimetypes from 'lib/mimetypes';
|
||||||
import prisma from 'lib/prisma';
|
import prisma from 'lib/prisma';
|
||||||
import multer from 'multer';
|
import multer from 'multer';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
|
@ -13,4 +13,4 @@ export default function Index() {
|
||||||
<meta property='og:description' content='Free and open source file hosting service.'/>
|
<meta property='og:description' content='Free and open source file hosting service.'/>
|
||||||
</Head>
|
</Head>
|
||||||
);
|
);
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
"dom.iterable",
|
"dom.iterable",
|
||||||
"esnext"
|
"esnext"
|
||||||
],
|
],
|
||||||
"allowJs": true,
|
"allowJs": false,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": false,
|
"strict": false,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
@ -32,7 +32,8 @@
|
||||||
"hooks/*": [
|
"hooks/*": [
|
||||||
"hooks/*"
|
"hooks/*"
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
"allowJs": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
"next-env.d.ts",
|
"next-env.d.ts",
|
||||||
|
@ -44,8 +45,5 @@
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"uploads"
|
"uploads"
|
||||||
],
|
|
||||||
"collectCoverageFrom": [
|
|
||||||
"!src/lib/config.ts"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Message, MessageEmbed } from 'discord.js';
|
import { Message, MessageEmbed } from 'discord.js';
|
||||||
import config from '../../src/lib/config';
|
import config from '../../src/lib/config';
|
||||||
import { commands } from '../index';
|
import { commands } from '../twilight';
|
||||||
|
|
||||||
const help = {
|
const help = {
|
||||||
command: 'help',
|
command: 'help',
|
||||||
|
|
|
@ -35,10 +35,11 @@ const shorten = {
|
||||||
data: {
|
data: {
|
||||||
short: vanity ? vanity : rand,
|
short: vanity ? vanity : rand,
|
||||||
destination: schemify(dest),
|
destination: schemify(dest),
|
||||||
userId: user.id,
|
userId: config.bot.default_uid,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
info('URL', `User shortened a URL: ${url.destination} (${url.id})`);
|
info('URL', `User ${msg.author.username}#${msg.author.discriminator} shortened a URL: ${url.destination} (${url.id})`);
|
||||||
|
global.logger.log(`User ${msg.author.username}#${msg.author.discriminator} shortened a URL: ${url.destination} (${url.id})`);
|
||||||
msg.channel.send(`http${config.core.secure ? 's' : ''}://${config.bot.hostname}${config.shortener.route}/${url.short}`);
|
msg.channel.send(`http${config.core.secure ? 's' : ''}://${config.bot.hostname}${config.shortener.route}/${url.short}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { Message } from 'discord.js';
|
||||||
|
import { writeFile } from 'fs/promises';
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
import { extname, join } from 'path';
|
||||||
|
import url from 'url';
|
||||||
|
import config from '../../src/lib/config';
|
||||||
|
import generate, { emoji, zws } from '../../src/lib/generators';
|
||||||
|
import { info, error } from '../../src/lib/logger';
|
||||||
|
import mimetypes from '../../src/lib/mimetypes';
|
||||||
|
import prisma from '../../src/lib/prisma';
|
||||||
|
|
||||||
|
const upload = {
|
||||||
|
command: 'upload',
|
||||||
|
description: 'Upload a new file',
|
||||||
|
syntax: '{PREFIX}upload <url> [generator]',
|
||||||
|
scopes: ['dm', 'text'],
|
||||||
|
execute: async (msg: Message, args: string[]) => {
|
||||||
|
if (!args[0]) return msg.channel.send('No URL.');
|
||||||
|
let buffer, res;
|
||||||
|
try {
|
||||||
|
res = await fetch(args[0]);
|
||||||
|
if (!res.ok) return msg.channel.send('Unable to fetch the file.');
|
||||||
|
buffer = await res.buffer();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
error('BOT', e.message);
|
||||||
|
return msg.channel.send(e.message);
|
||||||
|
}
|
||||||
|
const fileName = url.parse(args[0]).pathname;
|
||||||
|
const ext = extname(fileName);
|
||||||
|
const rand = generate(config.uploader.length);
|
||||||
|
let slug;
|
||||||
|
switch (args[1] ?? 'normal') {
|
||||||
|
case 'zws': {
|
||||||
|
slug = zws(config.uploader.length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'emoji': {
|
||||||
|
slug = emoji(config.uploader.length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
slug = rand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const deletionToken = generate(15);
|
||||||
|
function getMimetype(current, ext) {
|
||||||
|
if (current === 'application/octet-stream') {
|
||||||
|
if (mimetypes[ext]) {
|
||||||
|
return mimetypes[ext];
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
const file = await prisma.file.create({
|
||||||
|
data: {
|
||||||
|
slug,
|
||||||
|
origFileName: fileName.split('/').pop(),
|
||||||
|
fileName: `${rand}${ext}`,
|
||||||
|
mimetype: getMimetype(res.headers.get('Content-Type'), ext),
|
||||||
|
userId: config.bot.default_uid,
|
||||||
|
deletionToken
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await writeFile(join(process.cwd(), config.uploader.directory, file.fileName), buffer);
|
||||||
|
info('FILE', `User ${msg.author.username}#${msg.author.discriminator} uploaded a file: ${file.fileName} (${file.id})`);
|
||||||
|
global.logger.log(`User ${msg.author.username}#${msg.author.discriminator} uploaded a file: ${file.fileName}`);
|
||||||
|
msg.channel.send(`http${config.core.secure ? 's' : ''}://${config.bot.hostname}/${file.slug}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default upload;
|
|
@ -2,7 +2,6 @@ import { Message, MessageEmbed } from 'discord.js';
|
||||||
import { info } from '../../src/lib/logger';
|
import { info } from '../../src/lib/logger';
|
||||||
import prisma from '../../src/lib/prisma';
|
import prisma from '../../src/lib/prisma';
|
||||||
import { generateToken, hashPassword } from '../../src/lib/utils';
|
import { generateToken, hashPassword } from '../../src/lib/utils';
|
||||||
import { logger } from '../index';
|
|
||||||
|
|
||||||
const user = {
|
const user = {
|
||||||
command: 'user',
|
command: 'user',
|
||||||
|
@ -42,7 +41,7 @@ const user = {
|
||||||
{ name: 'id', value: newUser.id },
|
{ name: 'id', value: newUser.id },
|
||||||
{ name: 'Username', value: newUser.username }
|
{ name: 'Username', value: newUser.username }
|
||||||
);
|
);
|
||||||
logger.log(embed);
|
global.logger.log(embed);
|
||||||
msg.channel.send(embed.addField('Token', newUser.token));
|
msg.channel.send(embed.addField('Token', newUser.token));
|
||||||
info('USER',`${msg.author.username}#${msg} created a user: ${newUser.username}`);
|
info('USER',`${msg.author.username}#${msg} created a user: ${newUser.username}`);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +62,7 @@ const user = {
|
||||||
.setColor('#B794F4')
|
.setColor('#B794F4')
|
||||||
.setFooter(`By: ${msg.author.username}#${msg.author.discriminator}`)
|
.setFooter(`By: ${msg.author.username}#${msg.author.discriminator}`)
|
||||||
.addField('Username', userToDelete.username, true);
|
.addField('Username', userToDelete.username, true);
|
||||||
logger.log(embed);
|
global.logger.log(embed);
|
||||||
msg.channel.send(embed);
|
msg.channel.send(embed);
|
||||||
info('USER',`${msg.author.username}#${msg} created a user: ${userToDelete.username}`);
|
info('USER',`${msg.author.username}#${msg} created a user: ${userToDelete.username}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
import Discord, { Message, MessageEmbed } from 'discord.js';
|
import Discord, { Message, MessageEmbed } from 'discord.js';
|
||||||
import { readdir } from 'fs';
|
import { readdir } from 'fs';
|
||||||
import { exit } from 'process';
|
|
||||||
import config from '../src/lib/config';
|
|
||||||
import { error, info } from '../src/lib/logger';
|
import { error, info } from '../src/lib/logger';
|
||||||
import { Logger } from './utils/logger';
|
import { Logger } from './utils/logger';
|
||||||
|
|
||||||
if (!config.bot.enabled) exit(0);
|
let config;
|
||||||
process.env.DATABASE_URL = config.core.database_url;
|
|
||||||
if (!config.bot.token) exit(1);
|
|
||||||
|
|
||||||
export let logger;
|
|
||||||
|
|
||||||
const client = new Discord.Client();
|
const client = new Discord.Client();
|
||||||
|
|
||||||
|
@ -17,23 +11,23 @@ export const commands = [];
|
||||||
|
|
||||||
client.once('ready', () => {
|
client.once('ready', () => {
|
||||||
info('BOT', 'Twilight is ready');
|
info('BOT', 'Twilight is ready');
|
||||||
logger = new Logger(client);
|
global.logger = new Logger(client);
|
||||||
logger.log(new MessageEmbed()
|
global.logger.log(new MessageEmbed()
|
||||||
.setTitle('Twilight is ready')
|
.setTitle('Twilight is ready')
|
||||||
.setColor('#B794F4'));
|
.setColor('#B794F4'));
|
||||||
readdir(`${__dirname}/commands`, (err, files) => {
|
readdir(`${__dirname}/commands`, (err, files) => {
|
||||||
if(err) error('BOT', err.message);
|
if(err) error('BOT', err.message);
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
if (file.toString().includes('.ts')) {
|
if (file.toString().includes('.ts')) {
|
||||||
commands.push(require(`${__dirname}/commands/${file.toString()}`).default);
|
import(`${__dirname}/commands/${file.toString()}`).then(command => commands.push(command.default));
|
||||||
info('COMMAND', `Loaded command: ${file.toString().split('.').slice(0, -1)}`);}
|
info('COMMAND', `Loaded command: ${file.toString().split('.').slice(0, -1)}`);}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on('message', (msg: Message) => {
|
client.on('message', (msg: Message) => {
|
||||||
if (config.bot.admins.includes(msg.author.id) && msg.content.startsWith(config.bot.prefix)) {
|
if ((config.admins).includes(msg.author.id) && msg.content.startsWith(config.prefix)) {
|
||||||
const args = msg.content.slice(config.bot.prefix.length).trim().split(/ +/g);
|
const args = msg.content.slice(config.prefix.length).trim().split(/ +/g);
|
||||||
const cmd = args.shift().toString().toLowerCase();
|
const cmd = args.shift().toString().toLowerCase();
|
||||||
commands.forEach(command => {
|
commands.forEach(command => {
|
||||||
if (command.command === cmd)
|
if (command.command === cmd)
|
||||||
|
@ -44,4 +38,7 @@ client.on('message', (msg: Message) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.login(config.bot.token);
|
export default function start({ bot }) {
|
||||||
|
config = bot;
|
||||||
|
client.login(config.token);
|
||||||
|
}
|
|
@ -1,11 +1,13 @@
|
||||||
import type { PrismaClient } from '@prisma/client';
|
import type { PrismaClient } from '@prisma/client';
|
||||||
import type { Config } from './src/lib/types';
|
import type { Config } from './src/lib/types';
|
||||||
|
import type { Logger } from './twilight/utils/logger';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
namespace NodeJS {
|
namespace NodeJS {
|
||||||
interface Global {
|
interface Global {
|
||||||
prisma: PrismaClient;
|
prisma: PrismaClient;
|
||||||
config: Config;
|
config: Config;
|
||||||
|
logger: Logger;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
44
yarn.lock
44
yarn.lock
|
@ -1098,22 +1098,22 @@
|
||||||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.4.4.tgz#11d5db19bd178936ec89cd84519c4de439574398"
|
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.4.4.tgz#11d5db19bd178936ec89cd84519c4de439574398"
|
||||||
integrity sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg==
|
integrity sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg==
|
||||||
|
|
||||||
"@prisma/client@^3.1.1":
|
"@prisma/client@^3.2.0":
|
||||||
version "3.1.1"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.1.1.tgz#f4012631528049c22d12b212846dcf503db33cfe"
|
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.2.0.tgz#6aa79b2945ca7553d5a4c14bbe0067d9f975e061"
|
||||||
integrity sha512-8ud8vVFMIg37yrkZ4wPpjKoMxFbCL0Pesq5eyLnag/s0LTKsVEN7ZBIQq9JzWW+AUqOzGKXr2Jt4Sl8xdGI99w==
|
integrity sha512-YCS/N3DZWoaKXhyS8dHwgUvT/NKXvlLbB5fsy0FvYC305JgNtMLjNbxsx0HjIcNw82MEhP7zWEXNvOLpOgGCUg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/engines-version" "3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f"
|
"@prisma/engines-version" "3.2.0-34.afdab2f10860244038c4e32458134112852d4dad"
|
||||||
|
|
||||||
"@prisma/engines-version@3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f":
|
"@prisma/engines-version@3.2.0-34.afdab2f10860244038c4e32458134112852d4dad":
|
||||||
version "3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f"
|
version "3.2.0-34.afdab2f10860244038c4e32458134112852d4dad"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f.tgz#f9908eb7808f2a546634398063942eaecb2474ef"
|
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.2.0-34.afdab2f10860244038c4e32458134112852d4dad.tgz#bd63ad4bbc32935ec43e93cb59220495893c844d"
|
||||||
integrity sha512-EuEMKLuwIcBO7uInZQHeG1yaywcfl32Tq8TDf5tgLvblk+ka70sej7S67lh3BV5gXMLTc3GdthSHPfDqZEK5uA==
|
integrity sha512-zYzFOmFvk5YzShqm6DuK7ULtjbJQpebAeD3gcpPfPjx6Uf9pug3bxeswp8/3sk2KKVUeKPUQg5p3TZLskyBNjA==
|
||||||
|
|
||||||
"@prisma/engines@3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f":
|
"@prisma/engines@3.2.0-34.afdab2f10860244038c4e32458134112852d4dad":
|
||||||
version "3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f"
|
version "3.2.0-34.afdab2f10860244038c4e32458134112852d4dad"
|
||||||
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f.tgz#7b45708e6a42523dc9bc2214e5c62781f608dc3a"
|
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.2.0-34.afdab2f10860244038c4e32458134112852d4dad.tgz#d8e6ceaddae105f0c882ac9113873f8f1e89d64a"
|
||||||
integrity sha512-6NEp0VlLho3hVtIvj2P4h0e19AYqQSXtFGts8gSIXDnV+l5pRFZaDMfGo2RiLMR0Kfrs8c3ZYxYX0sWmVL0tWw==
|
integrity sha512-MiZORXXsGORXTF9RqqKIlN/2ohkaxAWTsS7qxDJTy5ThTYLrXSmzxTSohM4qN/AI616B+o5WV7XTBhjlPKSufg==
|
||||||
|
|
||||||
"@reach/alert@0.13.2":
|
"@reach/alert@0.13.2":
|
||||||
version "0.13.2"
|
version "0.13.2"
|
||||||
|
@ -1219,10 +1219,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.6.tgz#040a64d7faf9e5d9e940357125f0963012e66f04"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.6.tgz#040a64d7faf9e5d9e940357125f0963012e66f04"
|
||||||
integrity sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==
|
integrity sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==
|
||||||
|
|
||||||
"@types/node@^14.14.31":
|
"@types/node@^16.10.3":
|
||||||
version "14.17.20"
|
version "16.10.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.20.tgz#74cc80438fd0467dc4377ee5bbad89a886df3c10"
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5"
|
||||||
integrity sha512-gI5Sl30tmhXsqkNvopFydP7ASc4c2cLfGNQrVKN3X90ADFWFsPEsotm/8JHSUJQKTHbwowAHtcJPeyVhtKv0TQ==
|
integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==
|
||||||
|
|
||||||
"@types/normalize-package-data@^2.4.0":
|
"@types/normalize-package-data@^2.4.0":
|
||||||
version "2.4.1"
|
version "2.4.1"
|
||||||
|
@ -4633,12 +4633,12 @@ prism-media@^1.2.9:
|
||||||
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.2.tgz#a1f04423ec15d22f3d62b1987b6a25dc49aad13b"
|
resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.3.2.tgz#a1f04423ec15d22f3d62b1987b6a25dc49aad13b"
|
||||||
integrity sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==
|
integrity sha512-L6UsGHcT6i4wrQhFF1aPK+MNYgjRqR2tUoIqEY+CG1NqVkMjPRKzS37j9f8GiYPlD6wG9ruBj+q5Ax+bH8Ik1g==
|
||||||
|
|
||||||
prisma@^3.1.1:
|
prisma@^3.2.0:
|
||||||
version "3.1.1"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.1.1.tgz#4c13c35dd3a58af9134008c8ed0fdc21a632802c"
|
resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.2.0.tgz#d4247114f1e4e4c67b9c70381c9aea4434882a38"
|
||||||
integrity sha512-+eZtWIL6hnOKUOvqq9WLBzSw2d/EbTmOx1Td1LI8/0XE40ctXMLG2N1p6NK5/+yivGaoNJ9PDpPsPL9lO4nJrQ==
|
integrity sha512-o8+DH0RD5DbP8QTZej2dsY64yvjOwOG3TWOlJyoCHQ+8DH9m4tzxo38j6IF/PqpN4PmAGPpHuNi/nssG1cvYlQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@prisma/engines" "3.1.0-24.c22652b7e418506fab23052d569b85d3aec4883f"
|
"@prisma/engines" "3.2.0-34.afdab2f10860244038c4e32458134112852d4dad"
|
||||||
|
|
||||||
prismjs@^1.22.0:
|
prismjs@^1.22.0:
|
||||||
version "1.25.0"
|
version "1.25.0"
|
||||||
|
|
Loading…
Reference in New Issue