diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..24983d9bf6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.env +icon_cache +logs +dist \ No newline at end of file diff --git a/.env.test b/.env.test index ed418ae289..d3c4fd9c3c 100644 --- a/.env.test +++ b/.env.test @@ -1,6 +1,5 @@ TZ="UTC" -ROBOCHIMP_DATABASE_URL="postgresql://postgres:postgres@localhost:5435/robochimp_integration_test?connection_limit=500&pool_timeout=0&schema=public" -DATABASE_URL="postgresql://postgres:postgres@localhost:5435/osb_integration_test?connection_limit=500&pool_timeout=0&schema=public" CLIENT_ID=111398433321891634 BOT_TOKEN=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -TEST=true \ No newline at end of file +TEST=true +CI=true \ No newline at end of file diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index d4c0d6b0c9..165927f7c5 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -9,37 +9,15 @@ on: jobs: test: - name: Node v${{ matrix.node_version }} - ${{ matrix.os }} - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest timeout-minutes: 10 - strategy: - matrix: - node_version: [20.15.0] - os: [ubuntu-latest] steps: - - name: Install System Packages - run: sudo apt-get install -y build-essential libpq-dev - - name: Checkout Project uses: actions/checkout@v4 - - run: corepack enable && corepack install - - name: Use Node.js ${{ matrix.node_version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node_version }} - cache: yarn - - name: Restore CI Cache - uses: actions/cache@v4 - with: - path: node_modules - key: ${{ runner.os }}-${{ matrix.node_version }}-${{ hashFiles('**/yarn.lock') }} - - name: Install Dependencies - run: yarn --immutable - - name: Copy Configuration - run: | - pushd src && - cp config.example.ts config.ts && - popd && cp .env.test .env - - name: Test - run: yarn test:integration + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Run Integration Tests + run: docker-compose up --build --abort-on-container-exit diff --git a/docker-compose.yml b/docker-compose.yml index 44cec8fbc4..36de7bd1b2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,27 @@ services: - osb: + db: image: postgres:16-alpine command: -c 'max_connections=1000' restart: always container_name: osb_database ports: - - "5435:3001" + - "5435:5435" environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres - PGPORT: 3001 + PGPORT: 5435 + volumes: + - postgres_data:/var/lib/postgresql/data + + app: + build: + context: . + depends_on: + - db + environment: + ROBOCHIMP_DATABASE_URL: postgresql://postgres:postgres@db:5435/robochimp_integration_test?connection_limit=500&pool_timeout=0&schema=public + DATABASE_URL: postgresql://postgres:postgres@db:5435/osb_integration_test?connection_limit=500&pool_timeout=0&schema=public + WAIT_HOSTS: db:5435 + +volumes: + postgres_data: diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000000..be430354e0 --- /dev/null +++ b/dockerfile @@ -0,0 +1,35 @@ +FROM node:20.15.0-alpine AS base +WORKDIR /usr/src/app +ENV CI=true +RUN apk add --no-cache dumb-init python3 g++ make git +RUN corepack enable + +COPY yarn.lock package.json .yarnrc.yml ./ + +ENTRYPOINT ["dumb-init", "--"] + +FROM base AS dependencies +WORKDIR /usr/src/app +RUN yarn remove zlib-sync && yarn install + +FROM base AS build-run +WORKDIR /usr/src/app +ENV NODE_ENV="development" +ENV NODE_OPTIONS="--enable-source-maps --max_old_space_size=4096" + +COPY --from=dependencies /usr/src/app/node_modules /usr/src/app/node_modules +COPY . . + +ENV CI=true +RUN cp .env.test .env +RUN cp src/config.example.ts src/config.ts + +ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.9.0/wait /wait +RUN chmod +x /wait + +CMD /wait && \ + yarn prisma db push --schema='./prisma/robochimp.prisma' && \ + yarn prisma db push --schema='./prisma/schema.prisma' && \ + yarn run build:esbuild && \ + yarn vitest run --config vitest.integration.config.mts && \ + exit 0 \ No newline at end of file diff --git a/package.json b/package.json index 6771bfd693..9673ae32e9 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "scripts": { + "watch": "nodemon -e ts -w src --exec 'yarn buildandrun'", "build": "tsx ./src/scripts/build.ts", "fix": "tsx ./src/scripts/troubleshooter.ts", "start": "yarn build && node --enable-source-maps dist/", @@ -9,12 +10,15 @@ "build:tsc": "tsc -p src", "wipedist": "node -e \"try { require('fs').rmSync('dist', { recursive: true }) } catch(_){}\"", "dev": "yarn && yarn wipedist && yarn lint && yarn build && yarn test && npm i -g dpdm && dpdm --exit-code circular:1 --progress=false --warning=false --tree=false ./dist/index.js", - "test": "concurrently --timings --raw --kill-others-on-fail \"tsc -p src\" \"yarn test:lint\" \"yarn test:unit\" \"tsc -p tests/integration\" \"tsc -p tests/unit\"", + "test": "concurrently --raw --kill-others-on-fail \"tsc -p src\" \"yarn test:lint\" \"yarn test:unit\" \"tsc -p tests/integration\" \"tsc -p tests/unit\"", "test:lint": "biome check --diagnostic-level=error", "test:unit": "vitest run --coverage --config vitest.unit.config.mts", "test:watch": "vitest --config vitest.unit.config.mts --coverage", "test:integration": "tsx ./src/scripts/integration-tests.ts", - "watch": "tsc -w -p src" + "buildandrun": "yarn build:esbuild && node dist", + "build:esbuild": "concurrently --raw \"yarn build:main\" \"yarn build:workers\"", + "build:main": "esbuild src/index.ts src/lib/workers/index.ts --minify --legal-comments=none --outdir=./dist --log-level=error --bundle --platform=node --loader:.node=file --external:@napi-rs/canvas --external:@prisma/robochimp --external:@prisma/client --external:zlib-sync --external:bufferutil --external:oldschooljs --external:discord.js --external:node-fetch --external:piscina", + "build:workers": "esbuild src/lib/workers/kill.worker.ts src/lib/workers/finish.worker.ts src/lib/workers/casket.worker.ts --log-level=error --bundle --minify --legal-comments=none --outdir=./dist/lib/workers --platform=node --loader:.node=file --external:@napi-rs/canvas --external:@prisma/robochimp --external:@prisma/client --external:zlib-sync --external:bufferutil --external:oldschooljs --external:discord.js --external:node-fetch --external:piscina" }, "dependencies": { "@napi-rs/canvas": "^0.1.53", @@ -51,7 +55,9 @@ "@types/node-fetch": "^2.6.1", "@vitest/coverage-v8": "^1.6.0", "concurrently": "^8.2.2", + "esbuild": "0.21.5", "fast-glob": "^3.3.2", + "nodemon": "^3.1.4", "prettier": "^3.3.2", "prisma": "^5.16.1", "tsx": "^4.16.2", @@ -61,5 +67,8 @@ "engines": { "node": "20.15.0" }, - "packageManager": "yarn@4.3.1" + "packageManager": "yarn@4.3.1", + "resolutions": { + "esbuild": "0.21.5" + } } diff --git a/src/index.ts b/src/index.ts index 739cba5ae4..0601c2fdb3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,9 @@ +import './lib/safeglobals'; import './lib/globals'; -import './lib/data/itemAliases'; -import './lib/data/trophies'; import './lib/crons'; import './lib/MUser'; import './lib/util/transactItemsFromBank'; -import './lib/itemMods'; import './lib/geImage'; -import './lib/util/logger'; import { MahojiClient } from '@oldschoolgg/toolkit'; import { init } from '@sentry/node'; diff --git a/src/lib/bankImage.ts b/src/lib/bankImage.ts index a656fc50e1..ba681b11e5 100644 --- a/src/lib/bankImage.ts +++ b/src/lib/bankImage.ts @@ -11,8 +11,8 @@ import fetch from 'node-fetch'; import { Bank } from 'oldschooljs'; import type { Item } from 'oldschooljs/dist/meta/types'; import { toKMB } from 'oldschooljs/dist/util/util'; - import { resolveItems } from 'oldschooljs/dist/util/util'; + import { BOT_TYPE, BitField, ItemIconPacks, PerkTier, toaPurpleItems } from '../lib/constants'; import { allCLItems } from '../lib/data/Collections'; import { filterableTypes } from '../lib/data/filterables'; diff --git a/src/lib/constants.ts b/src/lib/constants.ts index 2ccc9452a2..5998a1ca5d 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -9,8 +9,6 @@ import * as dotenv from 'dotenv'; import { getItemOrThrow, resolveItems } from 'oldschooljs/dist/util/util'; import { z } from 'zod'; -import './data/itemAliases'; - import { DISCORD_SETTINGS, production } from '../config'; import type { AbstractCommand } from '../mahoji/lib/inhibitors'; import { SkillsEnum } from './skilling/types'; @@ -534,11 +532,12 @@ const globalConfigSchema = z.object({ clientID: z.string().min(10).max(25), geAdminChannelID: z.string().default(''), redisPort: z.coerce.number().int().optional(), - botToken: z.string().min(1) + botToken: z.string().min(1), + isCI: z.coerce.boolean().default(false) }); dotenv.config({ path: path.resolve(process.cwd(), process.env.TEST ? '.env.test' : '.env') }); -if (!process.env.BOT_TOKEN) { +if (!process.env.BOT_TOKEN && !process.env.CI) { throw new Error( `You need to specify the BOT_TOKEN environment variable, copy your bot token from your config.ts and put it in the ".env" file like so:\n\nBOT_TOKEN=your_token_here` ); @@ -548,7 +547,8 @@ export const globalConfig = globalConfigSchema.parse({ clientID: process.env.CLIENT_ID, geAdminChannelID: process.env.GE_ADMIN_CHANNEL_ID, redisPort: process.env.REDIS_PORT, - botToken: process.env.BOT_TOKEN + botToken: process.env.BOT_TOKEN, + isCI: process.env.CI }); export const ONE_TRILLION = 1_000_000_000_000; diff --git a/src/lib/data/itemAliases.ts b/src/lib/data/itemAliases.ts index b0c543562b..33aa46bc96 100644 --- a/src/lib/data/itemAliases.ts +++ b/src/lib/data/itemAliases.ts @@ -1,6 +1,11 @@ +import { modifyItem } from '@oldschoolgg/toolkit'; import { Items } from 'oldschooljs'; +import { allTeamCapes } from 'oldschooljs/dist/data/itemConstants'; import { itemNameMap } from 'oldschooljs/dist/structures/Items'; import { cleanString } from 'oldschooljs/dist/util/cleanString'; +import { resolveItems } from 'oldschooljs/dist/util/util'; + +import { getOSItem } from '../util/getOSItem'; export function setItemAlias(id: number, name: string | string[], rename = true) { const existingItem = Items.get(id); @@ -298,3 +303,90 @@ setItemAlias(25_922, 'Antique lamp (hard ca)'); setItemAlias(25_923, 'Antique lamp (elite ca)'); setItemAlias(25_924, 'Antique lamp (master ca)'); setItemAlias(25_925, 'Antique lamp (grandmaster ca)'); + +/** + * Trophies + */ + +// BSO (Twisted) trophies +setItemAlias(24_372, 'BSO dragon trophy'); +setItemAlias(24_374, 'BSO rune trophy'); +setItemAlias(24_376, 'BSO adamant trophy'); +setItemAlias(24_378, 'BSO mithril trophy'); +setItemAlias(24_380, 'BSO steel trophy'); +setItemAlias(24_382, 'BSO iron trophy'); +setItemAlias(24_384, 'BSO bronze trophy'); + +// Comp. trophies +setItemAlias(25_042, 'Comp. dragon trophy'); +setItemAlias(25_044, 'Comp. rune trophy'); +setItemAlias(25_046, 'Comp. adamant trophy'); +setItemAlias(25_048, 'Comp. mithril trophy'); +setItemAlias(25_050, 'Comp. steel trophy'); +setItemAlias(25_052, 'Comp. iron trophy'); +setItemAlias(25_054, 'Comp. bronze trophy'); + +// Placeholder trophies +setItemAlias(26_515, 'Placeholder dragon trophy'); +setItemAlias(26_513, 'Placeholder rune trophy'); +setItemAlias(26_511, 'Placeholder adamant trophy'); +setItemAlias(26_509, 'Placeholder mithril trophy'); +setItemAlias(26_507, 'Placeholder steel trophy'); +setItemAlias(26_505, 'Placeholder iron trophy'); +setItemAlias(26_503, 'Placeholder bronze trophy'); + +export const allTrophyItems = resolveItems([ + 'BSO dragon trophy', + 'BSO rune trophy', + 'BSO adamant trophy', + 'BSO mithril trophy', + 'BSO steel trophy', + 'BSO iron trophy', + 'BSO bronze trophy', + 'Comp. dragon trophy', + 'Comp. rune trophy', + 'Comp. adamant trophy', + 'Comp. mithril trophy', + 'Comp. steel trophy', + 'Comp. iron trophy', + 'Comp. bronze trophy', + 'Placeholder dragon trophy', + 'Placeholder rune trophy', + 'Placeholder adamant trophy', + 'Placeholder mithril trophy', + 'Placeholder steel trophy', + 'Placeholder iron trophy', + 'Placeholder bronze trophy' +]); + +for (const item of allTrophyItems) { + modifyItem(item, { + tradeable: false, + tradeable_on_ge: false, + customItemData: { + cantBeSacrificed: true + } + }); +} + +/** + * Item modifications + */ + +export interface CustomItemData { + cantBeSacrificed?: true; +} +declare module 'oldschooljs/dist/meta/types' { + interface Item { + customItemData?: CustomItemData; + } +} + +for (const item of allTeamCapes) { + modifyItem(item.id, { + price: 100 + }); + if (getOSItem(item.id).price !== 100) { + throw new Error(`Failed to modify price of item ${item.id}`); + } +} diff --git a/src/lib/data/trophies.ts b/src/lib/data/trophies.ts deleted file mode 100644 index 6a2f192980..0000000000 --- a/src/lib/data/trophies.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { modifyItem } from '@oldschoolgg/toolkit'; - -import { resolveItems } from 'oldschooljs/dist/util/util'; -import { setItemAlias } from './itemAliases'; - -// BSO (Twisted) trophies -setItemAlias(24_372, 'BSO dragon trophy'); -setItemAlias(24_374, 'BSO rune trophy'); -setItemAlias(24_376, 'BSO adamant trophy'); -setItemAlias(24_378, 'BSO mithril trophy'); -setItemAlias(24_380, 'BSO steel trophy'); -setItemAlias(24_382, 'BSO iron trophy'); -setItemAlias(24_384, 'BSO bronze trophy'); - -// Comp. trophies -setItemAlias(25_042, 'Comp. dragon trophy'); -setItemAlias(25_044, 'Comp. rune trophy'); -setItemAlias(25_046, 'Comp. adamant trophy'); -setItemAlias(25_048, 'Comp. mithril trophy'); -setItemAlias(25_050, 'Comp. steel trophy'); -setItemAlias(25_052, 'Comp. iron trophy'); -setItemAlias(25_054, 'Comp. bronze trophy'); - -// Placeholder trophies -setItemAlias(26_515, 'Placeholder dragon trophy'); -setItemAlias(26_513, 'Placeholder rune trophy'); -setItemAlias(26_511, 'Placeholder adamant trophy'); -setItemAlias(26_509, 'Placeholder mithril trophy'); -setItemAlias(26_507, 'Placeholder steel trophy'); -setItemAlias(26_505, 'Placeholder iron trophy'); -setItemAlias(26_503, 'Placeholder bronze trophy'); - -export const allTrophyItems = resolveItems([ - 'BSO dragon trophy', - 'BSO rune trophy', - 'BSO adamant trophy', - 'BSO mithril trophy', - 'BSO steel trophy', - 'BSO iron trophy', - 'BSO bronze trophy', - 'Comp. dragon trophy', - 'Comp. rune trophy', - 'Comp. adamant trophy', - 'Comp. mithril trophy', - 'Comp. steel trophy', - 'Comp. iron trophy', - 'Comp. bronze trophy', - 'Placeholder dragon trophy', - 'Placeholder rune trophy', - 'Placeholder adamant trophy', - 'Placeholder mithril trophy', - 'Placeholder steel trophy', - 'Placeholder iron trophy', - 'Placeholder bronze trophy' -]); - -for (const item of allTrophyItems) { - modifyItem(item, { - tradeable: false, - tradeable_on_ge: false, - customItemData: { - cantBeSacrificed: true - } - }); -} diff --git a/src/lib/globals.ts b/src/lib/globals.ts index 7330120120..8d3529dbd3 100644 --- a/src/lib/globals.ts +++ b/src/lib/globals.ts @@ -1,6 +1,7 @@ import { isMainThread } from 'node:worker_threads'; import { TSRedis } from '@oldschoolgg/toolkit/dist/lib/TSRedis'; import { PrismaClient } from '@prisma/client'; +import { PrismaClient as RobochimpPrismaClient } from '@prisma/robochimp'; import { production } from '../config'; import { globalConfig } from './constants'; @@ -8,6 +9,7 @@ import { globalConfig } from './constants'; declare global { var prisma: PrismaClient; var redis: TSRedis; + var roboChimpClient: RobochimpPrismaClient; } function makePrismaClient(): PrismaClient { @@ -25,9 +27,17 @@ function makePrismaClient(): PrismaClient { ] }); } -// biome-ignore lint/suspicious/noRedeclare: -const prisma = global.prisma || makePrismaClient(); -global.prisma = prisma; +global.prisma = global.prisma || makePrismaClient(); + +function makeRobochimpPrismaClient(): RobochimpPrismaClient { + if (!production && !process.env.TEST) console.log('Making robochimp client...'); + if (!isMainThread && !process.env.TEST) { + throw new Error('Robochimp client should only be created on the main thread.'); + } + + return new RobochimpPrismaClient(); +} +global.roboChimpClient = global.roboChimpClient || makeRobochimpPrismaClient(); function makeRedisClient(): TSRedis { if (!production && !process.env.TEST) console.log('Making Redis client...'); @@ -36,6 +46,4 @@ function makeRedisClient(): TSRedis { } return new TSRedis({ mocked: !globalConfig.redisPort, port: globalConfig.redisPort }); } -// biome-ignore lint/suspicious/noRedeclare: -const redis = global.redis || makeRedisClient(); -global.redis = redis; +global.redis = global.redis || makeRedisClient(); diff --git a/src/lib/itemMods.ts b/src/lib/itemMods.ts deleted file mode 100644 index a70a8ab83b..0000000000 --- a/src/lib/itemMods.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { modifyItem } from '@oldschoolgg/toolkit'; - -import { allTeamCapes } from 'oldschooljs/dist/data/itemConstants'; -import getOSItem from './util/getOSItem'; - -export interface CustomItemData { - cantBeSacrificed?: true; -} -declare module 'oldschooljs/dist/meta/types' { - interface Item { - customItemData?: CustomItemData; - } -} - -for (const item of allTeamCapes) { - modifyItem(item.id, { - price: 100 - }); - if (getOSItem(item.id).price !== 100) { - throw new Error(`Failed to modify price of item ${item.id}`); - } -} diff --git a/src/lib/roboChimp.ts b/src/lib/roboChimp.ts index 2c8deb4935..5c7e51bfcb 100644 --- a/src/lib/roboChimp.ts +++ b/src/lib/roboChimp.ts @@ -1,6 +1,5 @@ import { formatOrdinal } from '@oldschoolgg/toolkit'; import type { TriviaQuestion, User } from '@prisma/robochimp'; -import { PrismaClient } from '@prisma/robochimp'; import { calcWhatPercent, round, sumArr } from 'e'; import deepEqual from 'fast-deep-equal'; @@ -9,14 +8,8 @@ import { getTotalCl } from './data/Collections'; import { calculateMastery } from './mastery'; import { MUserStats } from './structures/MUserStats'; -declare global { - var roboChimpClient: PrismaClient; -} - export type RobochimpUser = User; -global.roboChimpClient = global.roboChimpClient || new PrismaClient(); - export async function getRandomTriviaQuestions(): Promise { const random: TriviaQuestion[] = await roboChimpClient.$queryRaw`SELECT id, question, answers FROM trivia_question diff --git a/src/lib/safeglobals.ts b/src/lib/safeglobals.ts new file mode 100644 index 0000000000..c1ea0174ad --- /dev/null +++ b/src/lib/safeglobals.ts @@ -0,0 +1,2 @@ +import './util/logger'; +import './data/itemAliases'; diff --git a/src/lib/settings/prisma.ts b/src/lib/settings/prisma.ts index 2fc77cb41d..a974743e44 100644 --- a/src/lib/settings/prisma.ts +++ b/src/lib/settings/prisma.ts @@ -1,24 +1,10 @@ -import { isMainThread } from 'node:worker_threads'; import type { Activity, Prisma } from '@prisma/client'; import { activity_type_enum } from '@prisma/client'; -import { production } from '../../config'; import type { ActivityTaskData } from '../types/minions'; -import { sqlLog } from '../util/logger'; export const queryCountStore = { value: 0 }; -if (isMainThread) { - // @ts-ignore ignore - prisma.$on('query' as any, (_query: any) => { - const query = _query as Prisma.QueryEvent; - if (!production) { - sqlLog(query.query); - } - queryCountStore.value++; - }); -} - export function convertStoredActivityToFlatActivity(activity: Activity): ActivityTaskData { return { ...(activity.data as Prisma.JsonObject), diff --git a/src/lib/util/logger.ts b/src/lib/util/logger.ts index 5d4cfb1707..40715f7fa6 100644 --- a/src/lib/util/logger.ts +++ b/src/lib/util/logger.ts @@ -1,14 +1,12 @@ import SonicBoom from 'sonic-boom'; -import { BOT_TYPE } from '../constants'; - const today = new Date(); const year = today.getFullYear(); const month = (today.getMonth() + 1).toString().padStart(2, '0'); const day = today.getDate().toString().padStart(2, '0'); const formattedDate = `${year}-${month}-${day}`; -export const LOG_FILE_NAME = `./logs/${formattedDate}-${today.getHours()}-${today.getMinutes()}-${BOT_TYPE}-debug-logs.log`; +export const LOG_FILE_NAME = `./logs/${formattedDate}-${today.getHours()}-${today.getMinutes()}-debug-logs.log`; export const sonicBoom = new SonicBoom({ fd: LOG_FILE_NAME, diff --git a/src/lib/workers/index.ts b/src/lib/workers/index.ts index 3b384d9570..880417e7eb 100644 --- a/src/lib/workers/index.ts +++ b/src/lib/workers/index.ts @@ -44,16 +44,25 @@ export type FinishWorkerReturn = Promise< const maxThreads = production ? 3 : 1; +let dirName = __dirname.replace('src/lib', 'dist/lib'); +if (dirName.endsWith('dist')) { + dirName = resolve(dirName, 'lib', 'workers'); +} + +const finishWorkerPath = resolve(dirName, 'finish.worker.js'); +const killWorkerPath = resolve(dirName, 'kill.worker.js'); +const casketWorkerPath = resolve(dirName, 'casket.worker.js'); + const finishWorker = new Piscina({ - filename: resolve(__dirname.replace('src', 'dist'), 'finish.worker.js'), + filename: finishWorkerPath, maxThreads }); const killWorker = new Piscina({ - filename: resolve(__dirname.replace('src', 'dist'), 'kill.worker.js'), + filename: killWorkerPath, maxThreads }); const casketWorker = new Piscina({ - filename: resolve(__dirname.replace('src', 'dist'), 'casket.worker.js'), + filename: casketWorkerPath, maxThreads }); diff --git a/src/mahoji/commands/admin.ts b/src/mahoji/commands/admin.ts index 89c626fbfd..e62d8710d0 100644 --- a/src/mahoji/commands/admin.ts +++ b/src/mahoji/commands/admin.ts @@ -32,7 +32,6 @@ import { economyLog } from '../../lib/economyLogs'; import { generateGearImage } from '../../lib/gear/functions/generateGearImage'; import type { GearSetup } from '../../lib/gear/types'; import { GrandExchange } from '../../lib/grandExchange'; -import { runRolesTask } from '../../lib/rolesTask'; import { countUsersWithItemInCl } from '../../lib/settings/prisma'; import { cancelTask, minionActivityCacheDelete } from '../../lib/settings/settings'; import { sorts } from '../../lib/sorts'; @@ -814,17 +813,18 @@ export const adminCommand: OSBMahojiCommand = { return 'Done.'; } if (options.sync_roles) { - try { - const result = await runRolesTask(); - if (result.length < 2000) return result; - return { - content: 'The result was too big! Check the file.', - files: [new AttachmentBuilder(Buffer.from(result), { name: 'roles.txt' })] - }; - } catch (err: any) { - logError(err); - return `Failed to run roles task. ${err.message}`; - } + // try { + // const result = await runRolesTask(); + // if (result.length < 2000) return result; + // return { + // content: 'The result was too big! Check the file.', + // files: [new AttachmentBuilder(Buffer.from(result), { name: 'roles.txt' })] + // }; + // } catch (err: any) { + // logError(err); + // return `Failed to run roles task. ${err.message}`; + // } + return 'The roles task is disabled for now.'; } if (options.badges) { diff --git a/src/mahoji/lib/events.ts b/src/mahoji/lib/events.ts index 175e5ff3a9..db954c8fd4 100644 --- a/src/mahoji/lib/events.ts +++ b/src/mahoji/lib/events.ts @@ -69,9 +69,11 @@ export async function onStartup() { initCrons(); initTickers(); - sendToChannelID(Channel.GeneralChannel, { - content: `I have just turned on! + if (production) { + sendToChannelID(Channel.GeneralChannel, { + content: `I have just turned on! ${META_CONSTANTS.RENDERED_STR}` - }).catch(console.error); + }).catch(console.error); + } } diff --git a/src/scripts/build.ts b/src/scripts/build.ts index 356f307b57..5756d7e67d 100644 --- a/src/scripts/build.ts +++ b/src/scripts/build.ts @@ -1,3 +1,5 @@ +import '../lib/safeglobals'; + import { createHash } from 'node:crypto'; import { existsSync, readFileSync, writeFileSync } from 'node:fs'; import path from 'node:path'; diff --git a/src/scripts/integration-tests.ts b/src/scripts/integration-tests.ts deleted file mode 100644 index fcc536a204..0000000000 --- a/src/scripts/integration-tests.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { execSync } from 'node:child_process'; -import path from 'node:path'; -import { Stopwatch } from '@oldschoolgg/toolkit'; -import { config } from 'dotenv'; - -async function main() { - const stopwatch = new Stopwatch(); - try { - execSync('docker compose up -d --wait', { stdio: 'inherit' }); - stopwatch.check('Docker compose finished.'); - - execSync('npm install -g wait-on', { stdio: 'inherit' }); - execSync('wait-on tcp:5435 -t 10s', { stdio: 'inherit' }); - - const env = { ...process.env, ...config({ path: path.resolve('.env.test') }).parsed }; - execSync('yarn prisma db push --schema="./prisma/schema.prisma"', { stdio: 'inherit', env }); - execSync('yarn prisma db push --schema="./prisma/robochimp.prisma"', { stdio: 'inherit', env }); - stopwatch.check('Finished prisma pushing.'); - - execSync('yarn build:tsc', { stdio: 'inherit' }); - stopwatch.check('Finished building, starting tests.'); - - console.log('Starting tests...'); - const runs = 1; - for (let i = 0; i < runs; i++) { - console.log(`Starting run ${i + 1}/${runs}`); - execSync('vitest run --config vitest.integration.config.mts', { - stdio: 'inherit', - encoding: 'utf-8' - }); - console.log(`Finished run ${i + 1}/${runs}`); - } - } catch (err) { - console.log(execSync('docker-compose logs', { encoding: 'utf-8' })); - console.error(err); - throw new Error(err as any); - } finally { - execSync('docker-compose down', { stdio: 'inherit' }); - stopwatch.check('Finished.'); - } -} - -main(); diff --git a/src/scripts/remove-item.ts b/src/scripts/remove-item.ts index 96c4cdf380..93d8b3264f 100644 --- a/src/scripts/remove-item.ts +++ b/src/scripts/remove-item.ts @@ -1,5 +1,4 @@ -import '../lib/data/itemAliases'; -import '../lib/itemMods'; +import '../lib/safeglobals'; import { writeFileSync } from 'node:fs'; import { EquipmentSlot } from 'oldschooljs/dist/meta/types'; diff --git a/src/scripts/scriptUtil.ts b/src/scripts/scriptUtil.ts index b34317d800..8dd600afc4 100644 --- a/src/scripts/scriptUtil.ts +++ b/src/scripts/scriptUtil.ts @@ -1,17 +1,21 @@ -import { exec as execNonPromise } from 'node:child_process'; +import { type ExecOptions, exec as execNonPromise } from 'node:child_process'; import { promisify } from 'node:util'; import { Stopwatch } from '@oldschoolgg/toolkit'; const rawExecAsync = promisify(execNonPromise); -export async function execAsync(command: string) { +export async function execAsync(command: string | string[], options?: ExecOptions): Promise { try { console.log(' Running command:', command); - const result = await rawExecAsync(command); + const results = Array.isArray(command) + ? await Promise.all(command.map(cmd => rawExecAsync(cmd, options))) + : [await rawExecAsync(command, options)]; - if (result.stderr) { - console.error(result.stderr); + for (const result of results) { + if (result.stderr) { + console.error(result.stderr); + } } } catch (err) { console.error(err); diff --git a/tests/globalSetup.ts b/tests/globalSetup.ts index 0ff7de0329..4512a25c01 100644 --- a/tests/globalSetup.ts +++ b/tests/globalSetup.ts @@ -1,5 +1,4 @@ -import '../src/index'; -import '../src/lib/roboChimp'; +import '../src/lib/safeglobals'; import { Collection } from 'discord.js'; import { vi } from 'vitest'; diff --git a/tests/integration/commands/dice.test.ts b/tests/integration/commands/dice.test.ts index 18881ca164..ab20bbd5ee 100644 --- a/tests/integration/commands/dice.test.ts +++ b/tests/integration/commands/dice.test.ts @@ -27,7 +27,7 @@ describe('Dice Command', async () => { await user.gpMatch(100_000_000); const unmock = mockMathRandom(0.1); const result = await user.runCommand(gambleCommand, { dice: { amount: '100m' } }); - expect(result).toMatchObject(` <@${user.id}> rolled **30** on the percentile dice, and you lost -100m GP.`); + expect(result).toMatchObject(` <@${user.id}> rolled **11** on the percentile dice, and you lost -100m GP.`); await user.gpMatch(0); await user.statsMatch('dice_losses', 1); await user.statsMatch('gp_dice', BigInt(-100_000_000)); @@ -39,7 +39,7 @@ describe('Dice Command', async () => { const unmock = mockMathRandom(0.9); await user.gpMatch(100_000_000); const result = await user.runCommand(gambleCommand, { dice: { amount: '100m' } }); - expect(result).toMatchObject(` <@${user.id}> rolled **67** on the percentile dice, and you won 100m GP.`); + expect(result).toMatchObject(` <@${user.id}> rolled **91** on the percentile dice, and you won 100m GP.`); await user.gpMatch(200_000_000); await user.statsMatch('dice_wins', 1); await user.statsMatch('gp_dice', BigInt(100_000_000)); diff --git a/tests/integration/grandExchange.test.ts b/tests/integration/grandExchange.test.ts index a4fe475ec5..3028fd6efb 100644 --- a/tests/integration/grandExchange.test.ts +++ b/tests/integration/grandExchange.test.ts @@ -13,10 +13,10 @@ import { cancelUsersListings } from '../../src/mahoji/lib/abstracted_commands/ca import type { TestUser } from './util'; import { createTestUser, mockClient } from './util'; -const TICKS_TO_RUN = 100; -const AMOUNT_USERS = 25; +const TICKS_TO_RUN = 50; +const AMOUNT_USERS = 10; const COMMANDS_PER_USER = 3; -const TICKS_PER_EXTENSIVE_VERIFICATION = 100; +const TICKS_PER_EXTENSIVE_VERIFICATION = 20; const itemPool = resolveItems(['Egg', 'Trout', 'Coal']); console.log(`G.E test will make ${itemPool.length * COMMANDS_PER_USER * AMOUNT_USERS} listings.`); @@ -98,14 +98,11 @@ describe('Grand Exchange', async () => { for (let i = 0; i < TICKS_TO_RUN; i++) { await GrandExchange.tick(); if (i % TICKS_PER_EXTENSIVE_VERIFICATION === 0) { - stopwatch.check('Running verification'); await GrandExchange.extensiveVerification(); } } - stopwatch.check('Finished ticking'); await waitForGEToBeEmpty(); - const count = await prisma.gETransaction.count(); stopwatch.check(`Finished ticking ${TICKS_TO_RUN} times, made ${count} transactions`); diff --git a/tests/integration/paymentConflict.test.ts b/tests/integration/paymentConflict.test.ts index e3521972bb..15abc78a3c 100644 --- a/tests/integration/paymentConflict.test.ts +++ b/tests/integration/paymentConflict.test.ts @@ -7,8 +7,8 @@ import type { TestUser } from './util'; import { createTestUser, mockClient } from './util'; describe('Payment conflicts', async () => { - const payerCount = 50; - const iterations = 100; + const payerCount = 20; + const iterations = 20; const addChance = 3; const repeats = 1; diff --git a/tests/integration/rolesTask.test.ts b/tests/integration/rolesTask.test.ts index 3800826edc..df57e5e208 100644 --- a/tests/integration/rolesTask.test.ts +++ b/tests/integration/rolesTask.test.ts @@ -8,7 +8,7 @@ import { Minigames } from '../../src/lib/settings/minigames'; import { userStatsBankUpdate } from '../../src/mahoji/mahojiSettings'; import { createTestUser, mockedId, unMockedCyptoRand } from './util'; -describe('Roles Task', async () => { +describe.skip('Roles Task', async () => { test('Should not throw', async () => { const user = await createTestUser(); await userStatsBankUpdate(user.id, 'sacrificed_bank', new Bank().add('Coal', 10_000)); diff --git a/tests/integration/setup.ts b/tests/integration/setup.ts index f4d4fe745d..d787ece4d5 100644 --- a/tests/integration/setup.ts +++ b/tests/integration/setup.ts @@ -1,12 +1,19 @@ -import './mocks'; import '../globalSetup'; +import '../../src/lib/globals'; +import '../../src/lib/util/transactItemsFromBank'; +import './mocks'; import { Image } from '@napi-rs/canvas'; -import { noOp } from 'e'; -import { afterAll, beforeAll, beforeEach, vi } from 'vitest'; +import { beforeEach, vi } from 'vitest'; +import { PrismaClient } from '@prisma/client'; +import { noOp } from 'e'; import { BankImageTask, bankImageTask } from '../../src/lib/bankImage'; +if (!roboChimpClient) { + throw new Error('Robochimp client not found.'); +} + export function randomMock(random = 0.1) { Math.random = () => random; } @@ -49,6 +56,7 @@ const mockBankImageTask = { fetchAndCacheImage: vi.fn().mockReturnValue(Promise.resolve(new Image())), backgroundImages: [] }; + bankImageTask.fetchAndCacheImage = mockBankImageTask.fetchAndCacheImage; global.bankImageGenerator = mockBankImageTask as any; BankImageTask.prototype.init = mockBankImageTask.init; @@ -57,12 +65,11 @@ BankImageTask.prototype.generateBankImage = mockBankImageTask.generateBankImage; BankImageTask.prototype.getItemImage = mockBankImageTask.getItemImage; BankImageTask.prototype.fetchAndCacheImage = mockBankImageTask.fetchAndCacheImage; -beforeAll(async () => { - await prisma.$connect(); - await prisma.$queryRaw`CREATE EXTENSION IF NOT EXISTS intarray;`.catch(noOp); -}); +const __prismaClient = new PrismaClient(); +__prismaClient.$queryRawUnsafe('CREATE EXTENSION IF NOT EXISTS intarray;').then(noOp).catch(noOp); beforeEach(async () => { + global.prisma = __prismaClient; global.bankImageGenerator = mockBankImageTask as any; BankImageTask.prototype.init = mockBankImageTask.init; BankImageTask.prototype.run = mockBankImageTask.init; @@ -70,7 +77,3 @@ beforeEach(async () => { BankImageTask.prototype.getItemImage = mockBankImageTask.getItemImage; BankImageTask.prototype.fetchAndCacheImage = mockBankImageTask.fetchAndCacheImage; }); - -afterAll(async () => { - await prisma.$disconnect(); -}); diff --git a/tests/unit/setup.ts b/tests/unit/setup.ts index d5f1e92852..a0de646af7 100644 --- a/tests/unit/setup.ts +++ b/tests/unit/setup.ts @@ -1,4 +1,5 @@ import '../globalSetup'; + import { vi } from 'vitest'; import { mockMUser, mockUserMap } from './utils'; diff --git a/tests/unit/trophies.test.ts b/tests/unit/trophies.test.ts index cdab8e36c1..53b5bad019 100644 --- a/tests/unit/trophies.test.ts +++ b/tests/unit/trophies.test.ts @@ -1,6 +1,6 @@ import { expect, test } from 'vitest'; -import { allTrophyItems } from '../../src/lib/data/trophies'; +import { allTrophyItems } from '../../src/lib/data/itemAliases'; import getOSItem from '../../src/lib/util/getOSItem'; import itemIsTradeable from '../../src/lib/util/itemIsTradeable'; diff --git a/vitest.integration.config.mts b/vitest.integration.config.mts index f54929264e..46b6b535fe 100644 --- a/vitest.integration.config.mts +++ b/vitest.integration.config.mts @@ -12,12 +12,12 @@ export default defineConfig({ }, testTimeout: 30_000, bail: 1, - pool: 'threads', - maxConcurrency: 10, + pool: 'forks', + maxConcurrency: 5, poolOptions: { - threads: { - maxThreads: 5, - minThreads: 5 + forks: { + maxForks: 10, + minForks: 10 } } } diff --git a/yarn.lock b/yarn.lock index ee4e8ccddb..aaf16bf1b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -260,13 +260,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/aix-ppc64@npm:0.20.2" - conditions: os=aix & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/aix-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/aix-ppc64@npm:0.21.5" @@ -274,13 +267,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm64@npm:0.20.2" - conditions: os=android & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/android-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm64@npm:0.21.5" @@ -288,13 +274,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-arm@npm:0.20.2" - conditions: os=android & cpu=arm - languageName: node - linkType: hard - "@esbuild/android-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-arm@npm:0.21.5" @@ -302,13 +281,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/android-x64@npm:0.20.2" - conditions: os=android & cpu=x64 - languageName: node - linkType: hard - "@esbuild/android-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/android-x64@npm:0.21.5" @@ -316,13 +288,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-arm64@npm:0.20.2" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/darwin-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-arm64@npm:0.21.5" @@ -330,13 +295,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/darwin-x64@npm:0.20.2" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - "@esbuild/darwin-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/darwin-x64@npm:0.21.5" @@ -344,13 +302,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-arm64@npm:0.20.2" - conditions: os=freebsd & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/freebsd-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-arm64@npm:0.21.5" @@ -358,13 +309,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/freebsd-x64@npm:0.20.2" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/freebsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/freebsd-x64@npm:0.21.5" @@ -372,13 +316,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm64@npm:0.20.2" - conditions: os=linux & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/linux-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm64@npm:0.21.5" @@ -386,13 +323,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-arm@npm:0.20.2" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - "@esbuild/linux-arm@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-arm@npm:0.21.5" @@ -400,13 +330,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ia32@npm:0.20.2" - conditions: os=linux & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/linux-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ia32@npm:0.21.5" @@ -414,13 +337,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-loong64@npm:0.20.2" - conditions: os=linux & cpu=loong64 - languageName: node - linkType: hard - "@esbuild/linux-loong64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-loong64@npm:0.21.5" @@ -428,13 +344,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-mips64el@npm:0.20.2" - conditions: os=linux & cpu=mips64el - languageName: node - linkType: hard - "@esbuild/linux-mips64el@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-mips64el@npm:0.21.5" @@ -442,13 +351,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-ppc64@npm:0.20.2" - conditions: os=linux & cpu=ppc64 - languageName: node - linkType: hard - "@esbuild/linux-ppc64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-ppc64@npm:0.21.5" @@ -456,13 +358,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-riscv64@npm:0.20.2" - conditions: os=linux & cpu=riscv64 - languageName: node - linkType: hard - "@esbuild/linux-riscv64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-riscv64@npm:0.21.5" @@ -470,13 +365,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-s390x@npm:0.20.2" - conditions: os=linux & cpu=s390x - languageName: node - linkType: hard - "@esbuild/linux-s390x@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-s390x@npm:0.21.5" @@ -484,13 +372,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/linux-x64@npm:0.20.2" - conditions: os=linux & cpu=x64 - languageName: node - linkType: hard - "@esbuild/linux-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/linux-x64@npm:0.21.5" @@ -498,13 +379,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/netbsd-x64@npm:0.20.2" - conditions: os=netbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/netbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/netbsd-x64@npm:0.21.5" @@ -512,13 +386,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/openbsd-x64@npm:0.20.2" - conditions: os=openbsd & cpu=x64 - languageName: node - linkType: hard - "@esbuild/openbsd-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/openbsd-x64@npm:0.21.5" @@ -526,13 +393,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/sunos-x64@npm:0.20.2" - conditions: os=sunos & cpu=x64 - languageName: node - linkType: hard - "@esbuild/sunos-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/sunos-x64@npm:0.21.5" @@ -540,13 +400,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-arm64@npm:0.20.2" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@esbuild/win32-arm64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-arm64@npm:0.21.5" @@ -554,13 +407,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-ia32@npm:0.20.2" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - "@esbuild/win32-ia32@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-ia32@npm:0.21.5" @@ -568,13 +414,6 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.20.2": - version: 0.20.2 - resolution: "@esbuild/win32-x64@npm:0.20.2" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - "@esbuild/win32-x64@npm:0.21.5": version: 0.21.5 resolution: "@esbuild/win32-x64@npm:0.21.5" @@ -1984,6 +1823,16 @@ __metadata: languageName: node linkType: hard +"anymatch@npm:~3.1.2": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: "npm:^3.0.0" + picomatch: "npm:^2.0.4" + checksum: 10c0/57b06ae984bc32a0d22592c87384cd88fe4511b1dd7581497831c56d41939c8a001b28e7b853e1450f2bf61992dfcaa8ae2d0d161a0a90c4fb631ef07098fbac + languageName: node + linkType: hard + "ascii-table3@npm:^0.9.0": version: 0.9.0 resolution: "ascii-table3@npm:0.9.0" @@ -2021,6 +1870,13 @@ __metadata: languageName: node linkType: hard +"binary-extensions@npm:^2.0.0": + version: 2.3.0 + resolution: "binary-extensions@npm:2.3.0" + checksum: 10c0/75a59cafc10fb12a11d510e77110c6c7ae3f4ca22463d52487709ca7f18f69d886aa387557cc9864fbdb10153d0bdb4caacabf11541f55e89ed6e18d12ece2b5 + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -2040,7 +1896,7 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.1": +"braces@npm:^3.0.1, braces@npm:~3.0.2": version: 3.0.3 resolution: "braces@npm:3.0.3" dependencies: @@ -2120,6 +1976,25 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^3.5.2": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: "npm:~3.1.2" + braces: "npm:~3.0.2" + fsevents: "npm:~2.3.2" + glob-parent: "npm:~5.1.2" + is-binary-path: "npm:~2.1.0" + is-glob: "npm:~4.0.1" + normalize-path: "npm:~3.0.0" + readdirp: "npm:~3.6.0" + dependenciesMeta: + fsevents: + optional: true + checksum: 10c0/8361dcd013f2ddbe260eacb1f3cb2f2c6f2b0ad118708a343a5ed8158941a39cb8fb1d272e0f389712e74ee90ce8ba864eece9e0e62b9705cb468a2f6d917462 + languageName: node + linkType: hard + "chownr@npm:^2.0.0": version: 2.0.0 resolution: "chownr@npm:2.0.0" @@ -2231,7 +2106,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4": +"debug@npm:4, debug@npm:^4": version: 4.3.5 resolution: "debug@npm:4.3.5" dependencies: @@ -2391,87 +2266,7 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.20.1": - version: 0.20.2 - resolution: "esbuild@npm:0.20.2" - dependencies: - "@esbuild/aix-ppc64": "npm:0.20.2" - "@esbuild/android-arm": "npm:0.20.2" - "@esbuild/android-arm64": "npm:0.20.2" - "@esbuild/android-x64": "npm:0.20.2" - "@esbuild/darwin-arm64": "npm:0.20.2" - "@esbuild/darwin-x64": "npm:0.20.2" - "@esbuild/freebsd-arm64": "npm:0.20.2" - "@esbuild/freebsd-x64": "npm:0.20.2" - "@esbuild/linux-arm": "npm:0.20.2" - "@esbuild/linux-arm64": "npm:0.20.2" - "@esbuild/linux-ia32": "npm:0.20.2" - "@esbuild/linux-loong64": "npm:0.20.2" - "@esbuild/linux-mips64el": "npm:0.20.2" - "@esbuild/linux-ppc64": "npm:0.20.2" - "@esbuild/linux-riscv64": "npm:0.20.2" - "@esbuild/linux-s390x": "npm:0.20.2" - "@esbuild/linux-x64": "npm:0.20.2" - "@esbuild/netbsd-x64": "npm:0.20.2" - "@esbuild/openbsd-x64": "npm:0.20.2" - "@esbuild/sunos-x64": "npm:0.20.2" - "@esbuild/win32-arm64": "npm:0.20.2" - "@esbuild/win32-ia32": "npm:0.20.2" - "@esbuild/win32-x64": "npm:0.20.2" - dependenciesMeta: - "@esbuild/aix-ppc64": - optional: true - "@esbuild/android-arm": - optional: true - "@esbuild/android-arm64": - optional: true - "@esbuild/android-x64": - optional: true - "@esbuild/darwin-arm64": - optional: true - "@esbuild/darwin-x64": - optional: true - "@esbuild/freebsd-arm64": - optional: true - "@esbuild/freebsd-x64": - optional: true - "@esbuild/linux-arm": - optional: true - "@esbuild/linux-arm64": - optional: true - "@esbuild/linux-ia32": - optional: true - "@esbuild/linux-loong64": - optional: true - "@esbuild/linux-mips64el": - optional: true - "@esbuild/linux-ppc64": - optional: true - "@esbuild/linux-riscv64": - optional: true - "@esbuild/linux-s390x": - optional: true - "@esbuild/linux-x64": - optional: true - "@esbuild/netbsd-x64": - optional: true - "@esbuild/openbsd-x64": - optional: true - "@esbuild/sunos-x64": - optional: true - "@esbuild/win32-arm64": - optional: true - "@esbuild/win32-ia32": - optional: true - "@esbuild/win32-x64": - optional: true - bin: - esbuild: bin/esbuild - checksum: 10c0/66398f9fb2c65e456a3e649747b39af8a001e47963b25e86d9c09d2a48d61aa641b27da0ce5cad63df95ad246105e1d83e7fee0e1e22a0663def73b1c5101112 - languageName: node - linkType: hard - -"esbuild@npm:~0.21.5": +"esbuild@npm:0.21.5": version: 0.21.5 resolution: "esbuild@npm:0.21.5" dependencies: @@ -2777,7 +2572,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^5.1.2": +"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" dependencies: @@ -2823,6 +2618,13 @@ __metadata: languageName: node linkType: hard +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + "has-flag@npm:^4.0.0": version: 4.0.0 resolution: "has-flag@npm:4.0.0" @@ -2889,6 +2691,13 @@ __metadata: languageName: node linkType: hard +"ignore-by-default@npm:^1.0.1": + version: 1.0.1 + resolution: "ignore-by-default@npm:1.0.1" + checksum: 10c0/9ab6e70e80f7cc12735def7ecb5527cfa56ab4e1152cd64d294522827f2dcf1f6d85531241537dc3713544e88dd888f65cb3c49c7b2cddb9009087c75274e533 + languageName: node + linkType: hard + "import-in-the-middle@npm:1.4.2": version: 1.4.2 resolution: "import-in-the-middle@npm:1.4.2" @@ -2987,6 +2796,15 @@ __metadata: languageName: node linkType: hard +"is-binary-path@npm:~2.1.0": + version: 2.1.0 + resolution: "is-binary-path@npm:2.1.0" + dependencies: + binary-extensions: "npm:^2.0.0" + checksum: 10c0/a16eaee59ae2b315ba36fad5c5dcaf8e49c3e27318f8ab8fa3cdb8772bf559c8d1ba750a589c2ccb096113bb64497084361a25960899cb6172a6925ab6123d38 + languageName: node + linkType: hard + "is-core-module@npm:^2.13.0": version: 2.14.0 resolution: "is-core-module@npm:2.14.0" @@ -3010,7 +2828,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.1": +"is-glob@npm:^4.0.1, is-glob@npm:~4.0.1": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -3350,7 +3168,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1": +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -3623,6 +3441,26 @@ __metadata: languageName: node linkType: hard +"nodemon@npm:^3.1.4": + version: 3.1.4 + resolution: "nodemon@npm:3.1.4" + dependencies: + chokidar: "npm:^3.5.2" + debug: "npm:^4" + ignore-by-default: "npm:^1.0.1" + minimatch: "npm:^3.1.2" + pstree.remy: "npm:^1.1.8" + semver: "npm:^7.5.3" + simple-update-notifier: "npm:^2.0.0" + supports-color: "npm:^5.5.0" + touch: "npm:^3.1.0" + undefsafe: "npm:^2.0.5" + bin: + nodemon: bin/nodemon.js + checksum: 10c0/be2335396a4c25549f86e9c69bb57e6a21758a9649d74182a359d88b80afbe84f67a1651e293a08c6d77ecdf5c6224d02990de9de225f70d7c659021206c877f + languageName: node + linkType: hard + "nopt@npm:^7.0.0": version: 7.2.1 resolution: "nopt@npm:7.2.1" @@ -3634,6 +3472,13 @@ __metadata: languageName: node linkType: hard +"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0": + version: 3.0.0 + resolution: "normalize-path@npm:3.0.0" + checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046 + languageName: node + linkType: hard + "npm-run-path@npm:^5.1.0": version: 5.3.0 resolution: "npm-run-path@npm:5.3.0" @@ -3863,6 +3708,13 @@ __metadata: languageName: node linkType: hard +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + languageName: node + linkType: hard + "picomatch@npm:^2.2.3": version: 2.3.0 resolution: "picomatch@npm:2.3.0" @@ -4033,6 +3885,13 @@ __metadata: languageName: node linkType: hard +"pstree.remy@npm:^1.1.8": + version: 1.1.8 + resolution: "pstree.remy@npm:1.1.8" + checksum: 10c0/30f78c88ce6393cb3f7834216cb6e282eb83c92ccb227430d4590298ab2811bc4a4745f850a27c5178e79a8f3e316591de0fec87abc19da648c2b3c6eb766d14 + languageName: node + linkType: hard + "pure-rand@npm:^6.1.0": version: 6.1.0 resolution: "pure-rand@npm:6.1.0" @@ -4061,6 +3920,15 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:~3.6.0": + version: 3.6.0 + resolution: "readdirp@npm:3.6.0" + dependencies: + picomatch: "npm:^2.2.1" + checksum: 10c0/6fa848cf63d1b82ab4e985f4cf72bd55b7dcfd8e0a376905804e48c3634b7e749170940ba77b32804d5fe93b3cc521aa95a8d7e7d725f830da6d93f3669ce66b + languageName: node + linkType: hard + "readline-sync@npm:^1.4.9": version: 1.4.10 resolution: "readline-sync@npm:1.4.10" @@ -4238,6 +4106,7 @@ __metadata: discord.js: "npm:^14.15.3" dotenv: "npm:^16.4.5" e: "npm:0.2.33" + esbuild: "npm:0.21.5" fast-deep-equal: "npm:^3.1.3" fast-glob: "npm:^3.3.2" lodash: "npm:^4.17.21" @@ -4245,6 +4114,7 @@ __metadata: murmurhash: "npm:^2.0.1" node-cron: "npm:^3.0.3" node-fetch: "npm:^2.6.7" + nodemon: "npm:^3.1.4" oldschooljs: "npm:^2.5.9" p-queue: "npm:^6.6.2" piscina: "npm:^4.6.1" @@ -4366,6 +4236,15 @@ __metadata: languageName: node linkType: hard +"simple-update-notifier@npm:^2.0.0": + version: 2.0.0 + resolution: "simple-update-notifier@npm:2.0.0" + dependencies: + semver: "npm:^7.5.3" + checksum: 10c0/2a00bd03bfbcbf8a737c47ab230d7920f8bfb92d1159d421bdd194479f6d01ebc995d13fbe13d45dace23066a78a3dc6642999b4e3b38b847e6664191575b20c + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -4517,6 +4396,15 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^5.5.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + "supports-color@npm:^7.1.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" @@ -4613,6 +4501,15 @@ __metadata: languageName: node linkType: hard +"touch@npm:^3.1.0": + version: 3.1.1 + resolution: "touch@npm:3.1.1" + bin: + nodetouch: bin/nodetouch.js + checksum: 10c0/d2e4d269a42c846a22a29065b9af0b263de58effc85a1764bb7a2e8fc4b47700e9e2fcbd7eb1f5bffbb7c73d860f93600cef282b93ddac8f0b62321cb498b36e + languageName: node + linkType: hard + "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -4707,6 +4604,13 @@ __metadata: languageName: node linkType: hard +"undefsafe@npm:^2.0.5": + version: 2.0.5 + resolution: "undefsafe@npm:2.0.5" + checksum: 10c0/96c0466a5fbf395917974a921d5d4eee67bca4b30d3a31ce7e621e0228c479cf893e783a109af6e14329b52fe2f0cb4108665fad2b87b0018c0df6ac771261d5 + languageName: node + linkType: hard + "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5"