mirror of
https://github.com/janderedev/automod.git
synced 2024-12-22 02:35:27 +00:00
minor changes
(added redis and made the bot actually functional again)
This commit is contained in:
parent
f333f2c78d
commit
fc740b1795
|
@ -21,6 +21,7 @@
|
|||
"express": "^4.17.2",
|
||||
"log75": "^2.2.0",
|
||||
"monk": "^7.3.4",
|
||||
"redis": "^4.2.0",
|
||||
"ulid": "^2.3.0",
|
||||
"ws": "^8.4.2"
|
||||
},
|
||||
|
|
|
@ -1,12 +1,17 @@
|
|||
import Monk, { IMonkManager } from 'monk';
|
||||
import Redis from 'redis';
|
||||
import { logger } from '.';
|
||||
|
||||
export default (): IMonkManager => {
|
||||
let dburl = getDBUrl();
|
||||
let db = Monk(dburl);
|
||||
return db;
|
||||
let dburl = getDBUrl();
|
||||
let db = Monk(dburl);
|
||||
return db;
|
||||
};
|
||||
|
||||
const redis = Redis.createClient({ url: process.env.REDIS_URL });
|
||||
|
||||
export { redis }
|
||||
|
||||
// Checks if all required env vars were supplied, and returns the mongo db URL
|
||||
function getDBUrl() {
|
||||
let env = process.env;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { config } from 'dotenv';
|
||||
import Express from "express";
|
||||
import Log75, { LogLevel } from 'log75';
|
||||
import buildDBClient from './db';
|
||||
import buildDBClient, { redis } from './db';
|
||||
|
||||
config();
|
||||
|
||||
|
@ -19,6 +19,8 @@ app.use(Express.json());
|
|||
export { logger, app, db, PORT, SESSION_LIFETIME }
|
||||
|
||||
(async () => {
|
||||
await redis.connect();
|
||||
|
||||
const promises = [
|
||||
import('./middlewares/log'),
|
||||
import('./middlewares/updateTokenExpiry'),
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
import { Request, Response } from "express";
|
||||
import { FindOneResult } from "monk";
|
||||
import { app, db, logger } from "..";
|
||||
|
||||
const ratelimits = db.get('ratelimits');
|
||||
|
||||
type RateLimitObject = {
|
||||
ip: string,
|
||||
requests: { route: string, time: number }[],
|
||||
lastActivity: number,
|
||||
}
|
||||
|
||||
// Might use redis here later, idk
|
||||
// I am also aware that there's better ways to do this
|
||||
import { ulid } from "ulid";
|
||||
import { app, logger } from "..";
|
||||
import { redis } from "../db";
|
||||
|
||||
class RateLimiter {
|
||||
route: string;
|
||||
|
@ -27,25 +17,14 @@ class RateLimiter {
|
|||
async execute(req: Request, res: Response, next: () => void) {
|
||||
try {
|
||||
const ip = req.ip;
|
||||
const now = Date.now();
|
||||
const reqId = ulid();
|
||||
|
||||
const entry: FindOneResult<RateLimitObject> = await ratelimits.findOne({ ip });
|
||||
if (!entry) {
|
||||
logger.debug('Ratelimiter: Request from new IP address, creating new document');
|
||||
next();
|
||||
await ratelimits.insert({
|
||||
ip,
|
||||
lastActivity: now,
|
||||
requests: [{ route: this.route, time: now }],
|
||||
});
|
||||
return;
|
||||
}
|
||||
// ratelimit:ip_address_base64:route_base64
|
||||
const redisKey = `ratelimit:${Buffer.from(ip).toString('base64')}:${Buffer.from(this.route).toString('base64')}`;
|
||||
|
||||
const reqs = entry.requests.filter(
|
||||
r => r.route == this.route && r.time > now - (this.timeframe * 1000)
|
||||
);
|
||||
const reqs = await redis.SCARD(redisKey);
|
||||
|
||||
if (reqs.length >= this.limit) {
|
||||
if (reqs >= this.limit) {
|
||||
logger.debug(`Ratelimiter: IP address exceeded ratelimit for ${this.route} [${this.limit}/${this.timeframe}]`);
|
||||
res
|
||||
.status(429)
|
||||
|
@ -54,56 +33,15 @@ class RateLimiter {
|
|||
limit: this.limit,
|
||||
timeframe: this.timeframe,
|
||||
});
|
||||
} else next();
|
||||
|
||||
// Can't put a $push and $pull into the same query
|
||||
await Promise.all([
|
||||
ratelimits.update({ ip }, {
|
||||
$push: {
|
||||
requests: { route: this.route, time: now }
|
||||
},
|
||||
$set: {
|
||||
lastActivity: now
|
||||
}
|
||||
}),
|
||||
ratelimits.update({ ip }, {
|
||||
$pull: {
|
||||
requests: {
|
||||
route: this.route,
|
||||
time: {
|
||||
$lt: now - (this.timeframe * 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
]);
|
||||
} else {
|
||||
next();
|
||||
await redis.SADD(redisKey, reqId);
|
||||
await redis.sendCommand([ 'EXPIREMEMBER', redisKey, reqId, this.timeframe.toString() ]);
|
||||
}
|
||||
} catch(e) { console.error(e) }
|
||||
}
|
||||
}
|
||||
|
||||
app.use('*', (...args) => (new RateLimiter('*', { limit: 20, timeframe: 1 })).execute(...args));
|
||||
|
||||
// Delete all documents where the last
|
||||
// activity was more than 24 hours ago.
|
||||
// This ensures that we don't store
|
||||
// personally identifying data for longer
|
||||
// than required.
|
||||
|
||||
const cleanDocuments = async () => {
|
||||
try {
|
||||
logger.info('Ratelimiter: Deleting old documents');
|
||||
|
||||
const { deletedCount } = await ratelimits.remove({
|
||||
lastActivity: { $lt: Date.now() - 1000 * 60 * 60 * 24 }
|
||||
}, { multi: true });
|
||||
|
||||
logger.done(`Ratelimiter: Deleted ${deletedCount ?? '??'} documents.`);
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(cleanDocuments, 1000 * 10);
|
||||
setInterval(cleanDocuments, 10000 * 60 * 60);
|
||||
|
||||
export { RateLimiter }
|
||||
|
|
|
@ -5,6 +5,62 @@ __metadata:
|
|||
version: 6
|
||||
cacheKey: 8
|
||||
|
||||
"@redis/bloom@npm:1.0.2":
|
||||
version: 1.0.2
|
||||
resolution: "@redis/bloom@npm:1.0.2"
|
||||
peerDependencies:
|
||||
"@redis/client": ^1.0.0
|
||||
checksum: 4872e7e5e4ff03d63349ca88d3164d487f62805651ada91924de2592995993401c98a01cb93bff8d71e9a2e54985b2485b6cb0e084a7e8b1283e2ebb8bc4b833
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@redis/client@npm:1.2.0":
|
||||
version: 1.2.0
|
||||
resolution: "@redis/client@npm:1.2.0"
|
||||
dependencies:
|
||||
cluster-key-slot: 1.1.0
|
||||
generic-pool: 3.8.2
|
||||
yallist: 4.0.0
|
||||
checksum: 098a550a6728d9d3babb432a1c32f1678cbda5ad7fa3d59316fc334be42ef05d778fc4cf2e3d873a34817447870a5fc0486e62793698a279404b3b086ba7422e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@redis/graph@npm:1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "@redis/graph@npm:1.0.1"
|
||||
peerDependencies:
|
||||
"@redis/client": ^1.0.0
|
||||
checksum: 72e485efa416bdff10420f6e13c9cb4e1e5c70752e5172717adf62fc1d4d9ba12e708229fd87876f3a93270ff74c4bcd4d916987438dc36a94f7f12c9785fa44
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@redis/json@npm:1.0.3":
|
||||
version: 1.0.3
|
||||
resolution: "@redis/json@npm:1.0.3"
|
||||
peerDependencies:
|
||||
"@redis/client": ^1.0.0
|
||||
checksum: 26a7003c2fbacfa5998671e3a301cb2285432bf90f237adedcf76c0be0d379528e6710d469a8ea93c04bbd22951f9c2f41d460dbd79e85856f199248c4a250d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@redis/search@npm:1.0.6":
|
||||
version: 1.0.6
|
||||
resolution: "@redis/search@npm:1.0.6"
|
||||
peerDependencies:
|
||||
"@redis/client": ^1.0.0
|
||||
checksum: 5c776143520b11ae2e49a05e7fe3df514a01460f2be90759b15e4f097bf4a985784c48c2184ac2c275ced3ec5a0c77b208a4d46a50161d1ad6025e3ab2990aa7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@redis/time-series@npm:1.0.3":
|
||||
version: 1.0.3
|
||||
resolution: "@redis/time-series@npm:1.0.3"
|
||||
peerDependencies:
|
||||
"@redis/client": ^1.0.0
|
||||
checksum: 4d11518185dd15f31c5b4a433902e53a3ebc24614a0221080ab12abf4f6fc60b3db00a71a83de7b4b10f11077de611dc1c273274573646d63481d40ca246f82d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/body-parser@npm:*":
|
||||
version: 1.19.2
|
||||
resolution: "@types/body-parser@npm:1.19.2"
|
||||
|
@ -151,6 +207,7 @@ __metadata:
|
|||
express: ^4.17.2
|
||||
log75: ^2.2.0
|
||||
monk: ^7.3.4
|
||||
redis: ^4.2.0
|
||||
typescript: ^4.5.5
|
||||
ulid: ^2.3.0
|
||||
ws: ^8.4.2
|
||||
|
@ -238,6 +295,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cluster-key-slot@npm:1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "cluster-key-slot@npm:1.1.0"
|
||||
checksum: fc953c75209b1ef9088081bab4e40a0b2586491c974ab93460569c014515ca5a2e31c043f185285e177007162fc353d07836d98f570c171dbe055775430e495b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"content-disposition@npm:0.5.4":
|
||||
version: 0.5.4
|
||||
resolution: "content-disposition@npm:0.5.4"
|
||||
|
@ -419,6 +483,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"generic-pool@npm:3.8.2":
|
||||
version: 3.8.2
|
||||
resolution: "generic-pool@npm:3.8.2"
|
||||
checksum: f549077d90265e5e4d32a2410205b357ec61cf73d17861f1013637984390e09fe7bf537129a2c6ed30ae57662a57c8d54194f80046408d3349836330f422dbde
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"http-errors@npm:1.8.1":
|
||||
version: 1.8.1
|
||||
resolution: "http-errors@npm:1.8.1"
|
||||
|
@ -746,6 +817,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redis@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "redis@npm:4.2.0"
|
||||
dependencies:
|
||||
"@redis/bloom": 1.0.2
|
||||
"@redis/client": 1.2.0
|
||||
"@redis/graph": 1.0.1
|
||||
"@redis/json": 1.0.3
|
||||
"@redis/search": 1.0.6
|
||||
"@redis/time-series": 1.0.3
|
||||
checksum: 6c35b56c6b685e82973c5698c5736c07ccbc59f3bc18d8de61e45ead2df4b8fc82062e5618452f4d3f8c23f02ff8c0b847c8d6a681f909c403a0fb96adcc2b98
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"require-at@npm:^1.0.6":
|
||||
version: 1.0.6
|
||||
resolution: "require-at@npm:1.0.6"
|
||||
|
@ -936,3 +1021,10 @@ __metadata:
|
|||
checksum: 4369caaac8d1092a73871f5cf1d87fcbb995dc4183a1bc48e4f451bc2d02d0a8bf7c17edf1da18e2be3c773b09262275356b256d1c55bc7ca096154293ba2a8c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yallist@npm:4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "yallist@npm:4.0.0"
|
||||
checksum: 343617202af32df2a15a3be36a5a8c0c8545208f3d3dfbc6bb7c3e3b7e8c6f8e7485432e4f3b88da3031a6e20afa7c711eded32ddfb122896ac5d914e75848d5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
|
|
@ -3,7 +3,7 @@ import { client, dbs } from "../../..";
|
|||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
||||
import PendingLogin from "automod/types/PendingLogin";
|
||||
import PendingLogin from "automod/dist/types/PendingLogin";
|
||||
import logger from "../../logger";
|
||||
import { DEFAULT_PREFIX } from "../../modules/command_handler";
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import { client, dbs } from "../../..";
|
|||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||
import MessageCommandContext from "../../../struct/MessageCommandContext";
|
||||
import ServerConfig from "automod/types/ServerConfig";
|
||||
import ServerConfig from "automod/dist/types/ServerConfig";
|
||||
import { isBotManager, NO_MANAGER_MSG, parseUser } from "../../util";
|
||||
|
||||
const SYNTAX = '/whitelist add @user; /whitelist remove @user; /whitelist list';
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { ulid } from "ulid";
|
||||
import { client } from "../../../index";
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import InfractionType from "automod/types/antispam/InfractionType";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||
import { fetchUsername, logModAction } from "../../modules/mod_logs";
|
||||
import { storeTempBan } from "../../modules/tempbans";
|
||||
|
|
|
@ -2,8 +2,8 @@ import { User } from "@janderedev/revolt.js";
|
|||
import { SendableEmbed } from "revolt-api";
|
||||
import { ulid } from "ulid";
|
||||
import { client } from "../../../";
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import InfractionType from "automod/types/antispam/InfractionType";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||
import logger from "../../logger";
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||
import { dedupeArray, embed, EmbedColor, generateInfractionDMEmbed, getDmChannel, isModerator, NO_MANAGER_MSG, parseUserOrId, sanitizeMessageContent, storeInfraction } from "../../util";
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import { ulid } from "ulid";
|
||||
import InfractionType from "automod/types/antispam/InfractionType";
|
||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||
import { fetchUsername, logModAction } from "../../modules/mod_logs";
|
||||
import CommandCategory from "../../../struct/commands/CommandCategory";
|
||||
import { SendableEmbed } from "revolt-api";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import SimpleCommand from "../../../struct/commands/SimpleCommand";
|
||||
import { dbs } from "../../..";
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import InfractionType from "automod/types/antispam/InfractionType";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||
import { isModerator, NO_MANAGER_MSG, parseUserOrId, uploadFile } from "../../util";
|
||||
import Day from 'dayjs';
|
||||
import RelativeTime from 'dayjs/plugin/relativeTime';
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
||||
import { ulid } from "ulid";
|
||||
import { dbs } from "../..";
|
||||
import AntispamRule from "automod/types/antispam/AntispamRule";
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import InfractionType from "automod/types/antispam/InfractionType";
|
||||
import ModerationAction from "automod/types/antispam/ModerationAction";
|
||||
import AntispamRule from "automod/dist/types/antispam/AntispamRule";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||
import ModerationAction from "automod/dist/types/antispam/ModerationAction";
|
||||
import logger from "../logger";
|
||||
import { isModerator, storeInfraction } from "../util";
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
||||
import { client, dbs } from "../../..";
|
||||
import ServerConfig from "automod/types/ServerConfig";
|
||||
import ServerConfig from "automod/dist/types/ServerConfig";
|
||||
import { getPermissionLevel } from "../../util";
|
||||
import { wsEvents, WSResponse } from "../api_communication";
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import crypto from 'crypto';
|
|||
import { client as bot, dbs } from '../..';
|
||||
import { EventEmitter } from "events";
|
||||
import { parseUser } from "../util";
|
||||
import PendingLogin from "automod/types/PendingLogin";
|
||||
import PendingLogin from "automod/dist/types/PendingLogin";
|
||||
import { ulid } from "ulid";
|
||||
|
||||
const wsEvents = new EventEmitter();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
||||
import CustomRuleAction from "automod/types/antispam/CustomRuleAction";
|
||||
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
||||
|
||||
async function execute(message: Message, action: CustomRuleAction) {
|
||||
setTimeout(() => message.delete().catch(console.warn), (action.duration ?? 0) * 1000);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
||||
import { client } from "../../../..";
|
||||
import CustomRuleAction from "automod/types/antispam/CustomRuleAction";
|
||||
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
||||
|
||||
async function execute(message: Message, action: CustomRuleAction) {
|
||||
let text = action.text || "Error: No text specified for `sendMessage` action";
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
||||
import CustomRuleAction from "automod/types/antispam/CustomRuleAction";
|
||||
import CustomRuleAction from "automod/dist/types/antispam/CustomRuleAction";
|
||||
import { storeInfraction } from '../../../util';
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import { ulid } from "ulid";
|
||||
import InfractionType from "automod/types/antispam/InfractionType";
|
||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||
|
||||
async function execute(message: Message, action: CustomRuleAction) {
|
||||
let warnMsg = action.text
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
||||
import { client } from "../../..";
|
||||
import CustomRuleTrigger from "automod/types/antispam/CustomRuleTrigger";
|
||||
import CustomRuleTrigger from "automod/dist/types/antispam/CustomRuleTrigger";
|
||||
import VM from 'vm';
|
||||
|
||||
let ruleTimeouts: Map<string, number> = new Map();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { ulid } from "ulid";
|
||||
import crypto from "crypto";
|
||||
import { client, dbs } from "../..";
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import InfractionType from "automod/types/antispam/InfractionType";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import InfractionType from "automod/dist/types/antispam/InfractionType";
|
||||
import { BLACKLIST_BAN_REASON, BLACKLIST_MESSAGE } from "../commands/admin/botadm";
|
||||
import logger from "../logger";
|
||||
import { hasPermForChannel, storeInfraction } from "../util";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
||||
import { Server } from "@janderedev/revolt.js/dist/maps/Servers";
|
||||
import { client, dbs } from "../..";
|
||||
import LogMessage from "automod/types/LogMessage";
|
||||
import LogMessage from "automod/dist/types/LogMessage";
|
||||
import logger from "../logger";
|
||||
import { getAutumnURL, sanitizeMessageContent, sendLogMessage } from "../util";
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { FindResult } from "monk";
|
||||
import { client, dbs } from "../..";
|
||||
import TempBan from "automod/types/TempBan";
|
||||
import TempBan from "automod/dist/types/TempBan";
|
||||
import logger from "../logger";
|
||||
|
||||
// Array of ban IDs which should not get processed in this session
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { Member } from "@janderedev/revolt.js/dist/maps/Members";
|
||||
import { User } from "@janderedev/revolt.js/dist/maps/Users";
|
||||
import { client, dbs } from "..";
|
||||
import Infraction from "automod/types/antispam/Infraction";
|
||||
import Infraction from "automod/dist/types/antispam/Infraction";
|
||||
import FormData from 'form-data';
|
||||
import axios from 'axios';
|
||||
import { Server } from "@janderedev/revolt.js/dist/maps/Servers";
|
||||
import LogConfig from "automod/types/LogConfig";
|
||||
import LogMessage from "automod/types/LogMessage";
|
||||
import LogConfig from "automod/dist/types/LogConfig";
|
||||
import LogMessage from "automod/dist/types/LogMessage";
|
||||
import { ColorResolvable, MessageEmbed } from "discord.js";
|
||||
import logger from "./logger";
|
||||
import { ulid } from "ulid";
|
||||
|
@ -16,7 +16,7 @@ import { Message } from "@janderedev/revolt.js/dist/maps/Messages";
|
|||
import { isSudo } from "./commands/admin/botadm";
|
||||
import { SendableEmbed } from "revolt-api";
|
||||
import MessageCommandContext from "../struct/MessageCommandContext";
|
||||
import ServerConfig from "automod/types/ServerConfig";
|
||||
import ServerConfig from "automod/dist/types/ServerConfig";
|
||||
|
||||
const NO_MANAGER_MSG = '🔒 Missing permission';
|
||||
const ULID_REGEX = /^[0-9A-HJ-KM-NP-TV-Z]{26}$/i;
|
||||
|
|
|
@ -4,15 +4,15 @@ config();
|
|||
import logger from './bot/logger';
|
||||
import AutomodClient, { login } from './struct/AutomodClient';
|
||||
import MongoDB from './bot/db';
|
||||
import DbUser from 'automod/types/DbUser';
|
||||
import ServerConfig from 'automod/types/ServerConfig';
|
||||
import Infraction from 'automod/types/antispam/Infraction';
|
||||
import PendingLogin from 'automod/types/PendingLogin';
|
||||
import TempBan from 'automod/types/TempBan';
|
||||
import DbUser from 'automod/dist/types/DbUser';
|
||||
import ServerConfig from 'automod/dist/types/ServerConfig';
|
||||
import Infraction from 'automod/dist/types/antispam/Infraction';
|
||||
import PendingLogin from 'automod/dist/types/PendingLogin';
|
||||
import TempBan from 'automod/dist/types/TempBan';
|
||||
import { VoteEntry } from './bot/commands/moderation/votekick';
|
||||
import BridgeRequest from 'automod/types/BridgeRequest';
|
||||
import BridgeConfig from 'automod/types/BridgeConfig';
|
||||
import BridgedMessage from 'automod/types/BridgedMessage';
|
||||
import BridgeRequest from 'automod/dist/types/BridgeRequest';
|
||||
import BridgeConfig from 'automod/dist/types/BridgeConfig';
|
||||
import BridgedMessage from 'automod/dist/types/BridgedMessage';
|
||||
|
||||
logger.info('Initializing client');
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import CommandCategory from "./CommandCategory";
|
||||
import MessageCommandContext from "../MessageCommandContext";
|
||||
import ServerConfig from "automod/types/ServerConfig";
|
||||
import ServerConfig from "automod/dist/types/ServerConfig";
|
||||
|
||||
/**
|
||||
* A basic command, consisting of basic attributes
|
||||
|
|
|
@ -200,9 +200,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"automod@portal:../lib::locator=revolt-automod%40workspace%3A.":
|
||||
"automod@link:../lib::locator=revolt-automod%40workspace%3A.":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "automod@portal:../lib::locator=revolt-automod%40workspace%3A."
|
||||
resolution: "automod@link:../lib::locator=revolt-automod%40workspace%3A."
|
||||
languageName: node
|
||||
linkType: soft
|
||||
|
||||
|
@ -874,7 +874,7 @@ __metadata:
|
|||
dependencies:
|
||||
"@janderedev/revolt.js": ^6.0.0-2-patch.1
|
||||
"@types/monk": ^6.0.0
|
||||
automod: ^0.1.0
|
||||
automod: "link:../lib"
|
||||
axios: ^0.22.0
|
||||
dayjs: ^1.10.7
|
||||
discord.js: ^13.3.1
|
||||
|
|
|
@ -44,6 +44,7 @@ services:
|
|||
- DB_USERNAME=mogus
|
||||
- DB_PASS
|
||||
- DB_NAME=admin
|
||||
- REDIS_URL
|
||||
expose:
|
||||
- 9000
|
||||
ports:
|
||||
|
@ -95,3 +96,7 @@ services:
|
|||
volumes:
|
||||
- ./db:/data/db:rw
|
||||
restart: unless-stopped
|
||||
|
||||
redis:
|
||||
image: eqalpha/keydb
|
||||
restart: always
|
||||
|
|
|
@ -3,7 +3,13 @@
|
|||
"name": "automod",
|
||||
"version": "1.0.0",
|
||||
"description": "Shared code for AutoMod",
|
||||
"scripts": {
|
||||
"build": "rm -rf dist && tsc"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.0.4"
|
||||
}
|
||||
}
|
||||
|
|
100
lib/tsconfig.json
Normal file
100
lib/tsconfig.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
|
||||
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
|
||||
/* Modules */
|
||||
"module": "commonjs", /* Specify what module code is generated. */
|
||||
"rootDir": "./src", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
||||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files */
|
||||
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
|
||||
|
||||
/* Emit */
|
||||
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
"declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "./dist", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
|
||||
"strictPropertyInitialization": false, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
|
||||
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
140
lib/yarn.lock
140
lib/yarn.lock
|
@ -2,139 +2,7 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
cross-spawn@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
duplexer@~0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
|
||||
integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
|
||||
|
||||
event-stream@=3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571"
|
||||
integrity sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==
|
||||
dependencies:
|
||||
duplexer "~0.1.1"
|
||||
from "~0"
|
||||
map-stream "~0.1.0"
|
||||
pause-stream "0.0.11"
|
||||
split "0.3"
|
||||
stream-combiner "~0.0.4"
|
||||
through "~2.3.1"
|
||||
|
||||
from@~0:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
|
||||
integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
|
||||
|
||||
map-stream@~0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194"
|
||||
integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==
|
||||
|
||||
node-cleanup@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c"
|
||||
integrity sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==
|
||||
|
||||
path-key@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
pause-stream@0.0.11:
|
||||
version "0.0.11"
|
||||
resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
|
||||
integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==
|
||||
dependencies:
|
||||
through "~2.3"
|
||||
|
||||
ps-tree@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd"
|
||||
integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==
|
||||
dependencies:
|
||||
event-stream "=3.3.4"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
|
||||
dependencies:
|
||||
shebang-regex "^3.0.0"
|
||||
|
||||
shebang-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
split@0.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f"
|
||||
integrity sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==
|
||||
dependencies:
|
||||
through "2"
|
||||
|
||||
stream-combiner@~0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14"
|
||||
integrity sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==
|
||||
dependencies:
|
||||
duplexer "~0.1.1"
|
||||
|
||||
string-argv@^0.1.1:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.1.2.tgz#c5b7bc03fb2b11983ba3a72333dd0559e77e4738"
|
||||
integrity sha512-mBqPGEOMNJKXRo7z0keX0wlAhbBAjilUdPW13nN0PecVryZxdHIeM7TqbsSUA7VYuS00HGC6mojP7DlQzfa9ZA==
|
||||
|
||||
strip-ansi@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
through@2, through@~2.3, through@~2.3.1:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
|
||||
|
||||
tsc-watch@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tsc-watch/-/tsc-watch-5.0.3.tgz#4d0b2bda8f2677c8f9ed36e001c1a86c31701145"
|
||||
integrity sha512-Hz2UawwELMSLOf0xHvAFc7anLeMw62cMVXr1flYmhRuOhOyOljwmb1l/O60ZwRyy1k7N1iC1mrn1QYM2zITfuw==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.3"
|
||||
node-cleanup "^2.1.2"
|
||||
ps-tree "^1.2.0"
|
||||
string-argv "^0.1.1"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
typescript@^4.7.4:
|
||||
version "4.7.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
|
||||
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
|
||||
|
||||
which@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
"@types/node@^18.0.4":
|
||||
version "18.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.4.tgz#48aedbf35efb3af1248e4cd4d792c730290cd5d6"
|
||||
integrity sha512-M0+G6V0Y4YV8cqzHssZpaNCqvYwlCiulmm0PwpNLF55r/+cT8Ol42CHRU1SEaYFH2rTwiiE1aYg/2g2rrtGdPA==
|
||||
|
|
Loading…
Reference in a new issue