diff --git a/backend/package-lock.json b/backend/package-lock.json index 8d1ae3b5..e673ea0d 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -51,7 +51,7 @@ "tmp": "0.0.33", "tsconfig-paths": "^3.9.0", "twemoji": "^12.1.4", - "typeorm": "^0.2.31", + "typeorm": "^0.3.17", "utf-8-validate": "^5.0.5", "uuid": "^3.3.2", "yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build", @@ -180,6 +180,17 @@ "node": ">=4" } }, + "node_modules/@babel/runtime": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz", + "integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@clinic/bubbleprof": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/@clinic/bubbleprof/-/bubbleprof-9.1.0.tgz", @@ -897,11 +908,6 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "node_modules/@types/zen-observable": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.3.tgz", - "integrity": "sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw==" - }, "node_modules/@vladfrangu/async_event_emitter": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.2.2.tgz", @@ -2964,6 +2970,21 @@ "node": ">=0.10" } }, + "node_modules/date-fns": { + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", + "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", + "dependencies": { + "@babel/runtime": "^7.21.0" + }, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, "node_modules/date-time": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", @@ -7891,6 +7912,11 @@ "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, "node_modules/regexp-tree": { "version": "0.1.27", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", @@ -8204,11 +8230,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, "node_modules/scope-analyzer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/scope-analyzer/-/scope-analyzer-2.1.2.tgz", @@ -9607,52 +9628,60 @@ } }, "node_modules/typeorm": { - "version": "0.2.45", - "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.2.45.tgz", - "integrity": "sha512-c0rCO8VMJ3ER7JQ73xfk0zDnVv0WDjpsP6Q1m6CVKul7DB9iVdWLRjPzc8v2eaeBuomsbZ2+gTaYr8k1gm3bYA==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.17.tgz", + "integrity": "sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==", "dependencies": { - "@sqltools/formatter": "^1.2.2", - "app-root-path": "^3.0.0", + "@sqltools/formatter": "^1.2.5", + "app-root-path": "^3.1.0", "buffer": "^6.0.3", - "chalk": "^4.1.0", + "chalk": "^4.1.2", "cli-highlight": "^2.1.11", - "debug": "^4.3.1", - "dotenv": "^8.2.0", - "glob": "^7.1.6", - "js-yaml": "^4.0.0", - "mkdirp": "^1.0.4", + "date-fns": "^2.29.3", + "debug": "^4.3.4", + "dotenv": "^16.0.3", + "glob": "^8.1.0", + "mkdirp": "^2.1.3", "reflect-metadata": "^0.1.13", "sha.js": "^2.4.11", - "tslib": "^2.1.0", - "uuid": "^8.3.2", - "xml2js": "^0.4.23", - "yargs": "^17.0.1", - "zen-observable-ts": "^1.0.0" + "tslib": "^2.5.0", + "uuid": "^9.0.0", + "yargs": "^17.6.2" }, "bin": { - "typeorm": "cli.js" + "typeorm": "cli.js", + "typeorm-ts-node-commonjs": "cli-ts-node-commonjs.js", + "typeorm-ts-node-esm": "cli-ts-node-esm.js" + }, + "engines": { + "node": ">= 12.9.0" }, "funding": { "url": "https://opencollective.com/typeorm" }, "peerDependencies": { - "@sap/hana-client": "^2.11.14", - "better-sqlite3": "^7.1.2", + "@google-cloud/spanner": "^5.18.0", + "@sap/hana-client": "^2.12.25", + "better-sqlite3": "^7.1.2 || ^8.0.0", "hdb-pool": "^0.1.6", - "ioredis": "^4.28.3", - "mongodb": "^3.6.0", - "mssql": "^6.3.1", - "mysql2": "^2.2.5", + "ioredis": "^5.0.4", + "mongodb": "^5.2.0", + "mssql": "^9.1.1", + "mysql2": "^2.2.5 || ^3.0.1", "oracledb": "^5.1.0", "pg": "^8.5.1", "pg-native": "^3.0.0", "pg-query-stream": "^4.0.0", - "redis": "^3.1.1", + "redis": "^3.1.1 || ^4.0.0", "sql.js": "^1.4.0", - "sqlite3": "^5.0.2", + "sqlite3": "^5.0.3", + "ts-node": "^10.7.0", "typeorm-aurora-data-api-driver": "^2.0.0" }, "peerDependenciesMeta": { + "@google-cloud/spanner": { + "optional": true + }, "@sap/hana-client": { "optional": true }, @@ -9695,15 +9724,21 @@ "sqlite3": { "optional": true }, + "ts-node": { + "optional": true + }, "typeorm-aurora-data-api-driver": { "optional": true } } }, - "node_modules/typeorm/node_modules/argparse": { + "node_modules/typeorm/node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } }, "node_modules/typeorm/node_modules/buffer": { "version": "6.0.3", @@ -9742,28 +9777,63 @@ } }, "node_modules/typeorm/node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/typeorm/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typeorm/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { "node": ">=10" } }, - "node_modules/typeorm/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, + "node_modules/typeorm/node_modules/mkdirp": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-2.1.6.tgz", + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", "bin": { - "js-yaml": "bin/js-yaml.js" + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/typeorm/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { "uuid": "dist/bin/uuid" } @@ -10272,26 +10342,6 @@ "node": ">=8" } }, - "node_modules/xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -10353,20 +10403,6 @@ "yaml-js": "^0.2.3" } }, - "node_modules/zen-observable": { - "version": "0.8.15", - "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz", - "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==" - }, - "node_modules/zen-observable-ts": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz", - "integrity": "sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA==", - "dependencies": { - "@types/zen-observable": "0.8.3", - "zen-observable": "0.8.15" - } - }, "node_modules/zlib-sync": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/zlib-sync/-/zlib-sync-0.1.8.tgz", diff --git a/backend/package.json b/backend/package.json index faab7570..0cf51e48 100644 --- a/backend/package.json +++ b/backend/package.json @@ -18,10 +18,12 @@ "start-api-prod-debug": "NODE_ENV=production DEBUG=true clinic heapprofiler --collect-only --dest .clinic-api -- node -r ./register-tsconfig-paths.js --unhandled-rejections=strict --enable-source-maps --stack-trace-limit=30 dist/backend/src/api/index.js", "watch-api": "cross-env NODE_ENV=development tsc-watch --onSuccess \"npm run start-api-dev\"", "typeorm": "node -r ./register-tsconfig-paths.js ./node_modules/typeorm/cli.js", - "migrate-prod": "cross-env NODE_ENV=production npm run typeorm -- migration:run", - "migrate-dev": "npm run build && npm run typeorm -- migration:run", - "migrate-rollback-prod": "cross-env NODE_ENV=production npm run typeorm -- migration:revert", - "migrate-rollback-dev": "npm run build && npm run typeorm -- migration:revert", + "migrate": "npm run typeorm -- migration:run -d dist/backend/src/data/dataSource.js", + "migrate-prod": "npm run migrate", + "migrate-dev": "npm run build && npm run migrate", + "migrate-rollback": "npm run typeorm -- migration:revert -d dist/backend/src/data/dataSource.js", + "migrate-rollback-prod": "npm run migrate", + "migrate-rollback-dev": "npm run build && npm run migrate", "test": "npm run build && npm run run-tests", "run-tests": "ava", "test-watch": "tsc-watch --onSuccess \"npx ava\"" @@ -70,7 +72,7 @@ "tmp": "0.0.33", "tsconfig-paths": "^3.9.0", "twemoji": "^12.1.4", - "typeorm": "^0.2.31", + "typeorm": "^0.3.17", "utf-8-validate": "^5.0.5", "uuid": "^3.3.2", "yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build", diff --git a/backend/src/data/AllowedGuilds.ts b/backend/src/data/AllowedGuilds.ts index 63941d4b..f942c59a 100644 --- a/backend/src/data/AllowedGuilds.ts +++ b/backend/src/data/AllowedGuilds.ts @@ -1,8 +1,9 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DBDateFormat } from "../utils"; import { ApiPermissionTypes } from "./ApiPermissionAssignments"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { AllowedGuild } from "./entities/AllowedGuild"; export class AllowedGuilds extends BaseRepository { @@ -10,10 +11,10 @@ export class AllowedGuilds extends BaseRepository { constructor() { super(); - this.allowedGuilds = getRepository(AllowedGuild); + this.allowedGuilds = dataSource.getRepository(AllowedGuild); } - async isAllowed(guildId) { + async isAllowed(guildId: string) { const count = await this.allowedGuilds.count({ where: { id: guildId, @@ -22,11 +23,15 @@ export class AllowedGuilds extends BaseRepository { return count !== 0; } - find(guildId) { - return this.allowedGuilds.findOne(guildId); + find(guildId: string) { + return this.allowedGuilds.findOne({ + where: { + id: guildId, + }, + }); } - getForApiUser(userId) { + getForApiUser(userId: string) { return this.allowedGuilds .createQueryBuilder("allowed_guilds") .innerJoin( diff --git a/backend/src/data/ApiAuditLog.ts b/backend/src/data/ApiAuditLog.ts index e6d33999..98ecbe5f 100644 --- a/backend/src/data/ApiAuditLog.ts +++ b/backend/src/data/ApiAuditLog.ts @@ -1,6 +1,7 @@ -import { getRepository, Repository } from "typeorm/index"; -import { AuditLogEventData, AuditLogEventType } from "./apiAuditLogTypes"; +import { Repository } from "typeorm/index"; import { BaseRepository } from "./BaseRepository"; +import { AuditLogEventData, AuditLogEventType } from "./apiAuditLogTypes"; +import { dataSource } from "./dataSource"; import { ApiAuditLogEntry } from "./entities/ApiAuditLogEntry"; export class ApiAuditLog extends BaseRepository { @@ -8,7 +9,7 @@ export class ApiAuditLog extends BaseRepository { constructor() { super(); - this.auditLog = getRepository(ApiAuditLogEntry); + this.auditLog = dataSource.getRepository(ApiAuditLogEntry); } addEntry( diff --git a/backend/src/data/ApiLogins.ts b/backend/src/data/ApiLogins.ts index ae6106fc..da9e6139 100644 --- a/backend/src/data/ApiLogins.ts +++ b/backend/src/data/ApiLogins.ts @@ -1,10 +1,11 @@ import crypto from "crypto"; import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; // tslint:disable-next-line:no-submodule-imports import uuidv4 from "uuid/v4"; import { DAYS, DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { ApiLogin } from "./entities/ApiLogin"; const LOGIN_EXPIRY_TIME = 1 * DAYS; @@ -14,7 +15,7 @@ export class ApiLogins extends BaseRepository { constructor() { super(); - this.apiLogins = getRepository(ApiLogin); + this.apiLogins = dataSource.getRepository(ApiLogin); } async getUserIdByApiKey(apiKey: string): Promise { diff --git a/backend/src/data/ApiPermissionAssignments.ts b/backend/src/data/ApiPermissionAssignments.ts index 03ba7c4f..b3bb63f5 100644 --- a/backend/src/data/ApiPermissionAssignments.ts +++ b/backend/src/data/ApiPermissionAssignments.ts @@ -1,8 +1,9 @@ import { ApiPermissions } from "@shared/apiPermissions"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { ApiAuditLog } from "./ApiAuditLog"; -import { AuditLogEventTypes } from "./apiAuditLogTypes"; import { BaseRepository } from "./BaseRepository"; +import { AuditLogEventTypes } from "./apiAuditLogTypes"; +import { dataSource } from "./dataSource"; import { ApiPermissionAssignment } from "./entities/ApiPermissionAssignment"; export enum ApiPermissionTypes { @@ -16,7 +17,7 @@ export class ApiPermissionAssignments extends BaseRepository { constructor() { super(); - this.apiPermissions = getRepository(ApiPermissionAssignment); + this.apiPermissions = dataSource.getRepository(ApiPermissionAssignment); this.auditLogs = new ApiAuditLog(); } diff --git a/backend/src/data/ApiUserInfo.ts b/backend/src/data/ApiUserInfo.ts index 2ef43f87..1dbc9d45 100644 --- a/backend/src/data/ApiUserInfo.ts +++ b/backend/src/data/ApiUserInfo.ts @@ -1,8 +1,8 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; -import { connection } from "./db"; +import { dataSource } from "./dataSource"; import { ApiUserInfoData, ApiUserInfo as ApiUserInfoEntity } from "./entities/ApiUserInfo"; export class ApiUserInfo extends BaseRepository { @@ -10,7 +10,7 @@ export class ApiUserInfo extends BaseRepository { constructor() { super(); - this.apiUserInfo = getRepository(ApiUserInfoEntity); + this.apiUserInfo = dataSource.getRepository(ApiUserInfoEntity); } get(id) { @@ -22,7 +22,7 @@ export class ApiUserInfo extends BaseRepository { } update(id, data: ApiUserInfoData) { - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const repo = entityManager.getRepository(ApiUserInfoEntity); const existingInfo = await repo.findOne({ where: { id } }); diff --git a/backend/src/data/Archives.ts b/backend/src/data/Archives.ts index b696c33e..0978d861 100644 --- a/backend/src/data/Archives.ts +++ b/backend/src/data/Archives.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { ArchiveEntry } from "./entities/ArchiveEntry"; export class Archives extends BaseRepository { @@ -7,7 +8,7 @@ export class Archives extends BaseRepository { constructor() { super(); - this.archives = getRepository(ArchiveEntry); + this.archives = dataSource.getRepository(ArchiveEntry); } public deleteExpiredArchives() { diff --git a/backend/src/data/BaseRepository.ts b/backend/src/data/BaseRepository.ts index 27b08578..dcba6184 100644 --- a/backend/src/data/BaseRepository.ts +++ b/backend/src/data/BaseRepository.ts @@ -40,7 +40,7 @@ export class BaseRepository { return entity; } - protected async processEntityFromDB(entity: T): Promise { + protected async processEntityFromDB(entity: T): Promise { return this._processEntityFromDB(entity); } diff --git a/backend/src/data/Configs.ts b/backend/src/data/Configs.ts index cbd3c8de..1b9ade22 100644 --- a/backend/src/data/Configs.ts +++ b/backend/src/data/Configs.ts @@ -1,9 +1,9 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { isAPI } from "../globals"; import { HOURS, SECONDS } from "../utils"; import { BaseRepository } from "./BaseRepository"; import { cleanupConfigs } from "./cleanup/configs"; -import { connection } from "./db"; +import { dataSource } from "./dataSource"; import { Config } from "./entities/Config"; const CLEANUP_INTERVAL = 1 * HOURS; @@ -24,7 +24,7 @@ export class Configs extends BaseRepository { constructor() { super(); - this.configs = getRepository(Config); + this.configs = dataSource.getRepository(Config); } getActiveByKey(key) { @@ -37,7 +37,7 @@ export class Configs extends BaseRepository { } async getHighestId(): Promise { - const rows = await connection.query("SELECT MAX(id) AS highest_id FROM configs"); + const rows = await dataSource.query("SELECT MAX(id) AS highest_id FROM configs"); return (rows.length && rows[0].highest_id) || 0; } @@ -62,7 +62,7 @@ export class Configs extends BaseRepository { } async saveNewRevision(key, config, editedBy) { - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const repo = entityManager.getRepository(Config); // Mark all old revisions inactive await repo.update({ key }, { is_active: false }); diff --git a/backend/src/data/GuildAntiraidLevels.ts b/backend/src/data/GuildAntiraidLevels.ts index 5775bc91..0d4eb30c 100644 --- a/backend/src/data/GuildAntiraidLevels.ts +++ b/backend/src/data/GuildAntiraidLevels.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { AntiraidLevel } from "./entities/AntiraidLevel"; export class GuildAntiraidLevels extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildAntiraidLevels extends BaseGuildRepository { constructor(guildId: string) { super(guildId); - this.antiraidLevels = getRepository(AntiraidLevel); + this.antiraidLevels = dataSource.getRepository(AntiraidLevel); } async get() { diff --git a/backend/src/data/GuildArchives.ts b/backend/src/data/GuildArchives.ts index 2ee9116b..de1e9d07 100644 --- a/backend/src/data/GuildArchives.ts +++ b/backend/src/data/GuildArchives.ts @@ -1,12 +1,13 @@ import { Guild, Snowflake } from "discord.js"; import moment from "moment-timezone"; import { isDefaultSticker } from "src/utils/isDefaultSticker"; -import { Repository, getRepository } from "typeorm"; +import { Repository } from "typeorm"; import { TemplateSafeValueContainer, renderTemplate } from "../templateFormatter"; import { renderUsername, trimLines } from "../utils"; import { decrypt, encrypt } from "../utils/crypt"; import { channelToTemplateSafeChannel, guildToTemplateSafeGuild } from "../utils/templateSafeObjects"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { ArchiveEntry } from "./entities/ArchiveEntry"; import { SavedMessage } from "./entities/SavedMessage"; @@ -23,7 +24,7 @@ export class GuildArchives extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.archives = getRepository(ArchiveEntry); + this.archives = dataSource.getRepository(ArchiveEntry); } protected async _processEntityFromDB(entity: ArchiveEntry | undefined) { @@ -42,7 +43,7 @@ export class GuildArchives extends BaseGuildRepository { return entity; } - async find(id: string): Promise { + async find(id: string): Promise { const result = await this.archives.findOne({ where: { id }, relations: this.getRelations(), diff --git a/backend/src/data/GuildAutoReactions.ts b/backend/src/data/GuildAutoReactions.ts index 27fd737d..fcab1a90 100644 --- a/backend/src/data/GuildAutoReactions.ts +++ b/backend/src/data/GuildAutoReactions.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { AutoReaction } from "./entities/AutoReaction"; export class GuildAutoReactions extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildAutoReactions extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.autoReactions = getRepository(AutoReaction); + this.autoReactions = dataSource.getRepository(AutoReaction); } async all(): Promise { @@ -18,7 +19,7 @@ export class GuildAutoReactions extends BaseGuildRepository { }); } - async getForChannel(channelId: string): Promise { + async getForChannel(channelId: string): Promise { return this.autoReactions.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildButtonRoles.ts b/backend/src/data/GuildButtonRoles.ts index 24ee2e59..d493d424 100644 --- a/backend/src/data/GuildButtonRoles.ts +++ b/backend/src/data/GuildButtonRoles.ts @@ -12,15 +12,19 @@ export class GuildButtonRoles extends BaseGuildRepository { async getForButtonId(buttonId: string) { return this.buttonRoles.findOne({ - guild_id: this.guildId, - button_id: buttonId, + where: { + guild_id: this.guildId, + button_id: buttonId, + }, }); } async getAllForMessageId(messageId: string) { return this.buttonRoles.find({ - guild_id: this.guildId, - message_id: messageId, + where: { + guild_id: this.guildId, + message_id: messageId, + }, }); } @@ -40,8 +44,10 @@ export class GuildButtonRoles extends BaseGuildRepository { async getForButtonGroup(buttonGroup: string) { return this.buttonRoles.find({ - guild_id: this.guildId, - button_group: buttonGroup, + where: { + guild_id: this.guildId, + button_group: buttonGroup, + }, }); } diff --git a/backend/src/data/GuildCases.ts b/backend/src/data/GuildCases.ts index 8eb3df95..d0e7778a 100644 --- a/backend/src/data/GuildCases.ts +++ b/backend/src/data/GuildCases.ts @@ -1,9 +1,9 @@ -import { getRepository, In, InsertResult, Repository } from "typeorm"; +import { In, InsertResult, Repository } from "typeorm"; import { Queue } from "../Queue"; import { chunkArray } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { CaseTypes } from "./CaseTypes"; -import { connection } from "./db"; +import { dataSource } from "./dataSource"; import { Case } from "./entities/Case"; import { CaseNote } from "./entities/CaseNote"; @@ -15,8 +15,8 @@ export class GuildCases extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.cases = getRepository(Case); - this.caseNotes = getRepository(CaseNote); + this.cases = dataSource.getRepository(Case); + this.caseNotes = dataSource.getRepository(CaseNote); this.createQueue = new Queue(); } @@ -30,7 +30,7 @@ export class GuildCases extends BaseGuildRepository { }); } - async find(id: number): Promise { + async find(id: number): Promise { return this.cases.findOne({ relations: this.getRelations(), where: { @@ -40,7 +40,7 @@ export class GuildCases extends BaseGuildRepository { }); } - async findByCaseNumber(caseNumber: number): Promise { + async findByCaseNumber(caseNumber: number): Promise { return this.cases.findOne({ relations: this.getRelations(), where: { @@ -50,7 +50,7 @@ export class GuildCases extends BaseGuildRepository { }); } - async findLatestByModId(modId: string): Promise { + async findLatestByModId(modId: string): Promise { return this.cases.findOne({ relations: this.getRelations(), where: { @@ -63,7 +63,7 @@ export class GuildCases extends BaseGuildRepository { }); } - async findByAuditLogId(auditLogId: string): Promise { + async findByAuditLogId(auditLogId: string): Promise { return this.cases.findOne({ relations: this.getRelations(), where: { @@ -88,7 +88,7 @@ export class GuildCases extends BaseGuildRepository { where: { guild_id: this.guildId, mod_id: modId, - is_hidden: 0, + is_hidden: false, }, }); } @@ -99,7 +99,7 @@ export class GuildCases extends BaseGuildRepository { where: { guild_id: this.guildId, mod_id: modId, - is_hidden: 0, + is_hidden: false, }, skip, take: count, @@ -181,7 +181,7 @@ export class GuildCases extends BaseGuildRepository { } async softDelete(id: number, deletedById: string, deletedByName: string, deletedByText: string) { - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const cases = entityManager.getRepository(Case); const caseNotes = entityManager.getRepository(CaseNote); diff --git a/backend/src/data/GuildContextMenuLinks.ts b/backend/src/data/GuildContextMenuLinks.ts index 76afd3da..d82b2dd0 100644 --- a/backend/src/data/GuildContextMenuLinks.ts +++ b/backend/src/data/GuildContextMenuLinks.ts @@ -1,5 +1,6 @@ -import { DeleteResult, getRepository, InsertResult, Repository } from "typeorm"; +import { DeleteResult, InsertResult, Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { ContextMenuLink } from "./entities/ContextMenuLink"; export class GuildContextMenuLinks extends BaseGuildRepository { @@ -7,10 +8,10 @@ export class GuildContextMenuLinks extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.contextLinks = getRepository(ContextMenuLink); + this.contextLinks = dataSource.getRepository(ContextMenuLink); } - async get(id: string): Promise { + async get(id: string): Promise { return this.contextLinks.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildCounters.ts b/backend/src/data/GuildCounters.ts index a87861b1..4e69857b 100644 --- a/backend/src/data/GuildCounters.ts +++ b/backend/src/data/GuildCounters.ts @@ -1,11 +1,11 @@ import moment from "moment-timezone"; -import { FindConditions, getRepository, In, IsNull, Not, Repository } from "typeorm"; +import { FindOptionsWhere, In, IsNull, Not, Repository } from "typeorm"; import { Queue } from "../Queue"; import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; -import { connection } from "./db"; +import { dataSource } from "./dataSource"; import { Counter } from "./entities/Counter"; -import { CounterTrigger, isValidCounterComparisonOp, TriggerComparisonOp } from "./entities/CounterTrigger"; +import { CounterTrigger, TriggerComparisonOp, isValidCounterComparisonOp } from "./entities/CounterTrigger"; import { CounterTriggerState } from "./entities/CounterTriggerState"; import { CounterValue } from "./entities/CounterValue"; @@ -17,11 +17,11 @@ const MAX_COUNTER_VALUE = 2147483647; // 2^31-1, for MySQL INT const decayQueue = new Queue(); async function deleteCountersMarkedToBeDeleted(): Promise { - await getRepository(Counter).createQueryBuilder().where("delete_at <= NOW()").delete().execute(); + await dataSource.getRepository(Counter).createQueryBuilder().where("delete_at <= NOW()").delete().execute(); } async function deleteTriggersMarkedToBeDeleted(): Promise { - await getRepository(CounterTrigger).createQueryBuilder().where("delete_at <= NOW()").delete().execute(); + await dataSource.getRepository(CounterTrigger).createQueryBuilder().where("delete_at <= NOW()").delete().execute(); } setInterval(deleteCountersMarkedToBeDeleted, 1 * HOURS); @@ -38,10 +38,10 @@ export class GuildCounters extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.counters = getRepository(Counter); - this.counterValues = getRepository(CounterValue); - this.counterTriggers = getRepository(CounterTrigger); - this.counterTriggerStates = getRepository(CounterTriggerState); + this.counters = dataSource.getRepository(Counter); + this.counterValues = dataSource.getRepository(CounterValue); + this.counterTriggers = dataSource.getRepository(CounterTrigger); + this.counterTriggerStates = dataSource.getRepository(CounterTriggerState); } async findOrCreateCounter(name: string, perChannel: boolean, perUser: boolean): Promise { @@ -80,7 +80,7 @@ export class GuildCounters extends BaseGuildRepository { } async markUnusedCountersToBeDeleted(idsToKeep: number[]): Promise { - const criteria: FindConditions = { + const criteria: FindOptionsWhere = { guild_id: this.guildId, delete_at: IsNull(), }; @@ -256,10 +256,12 @@ export class GuildCounters extends BaseGuildRepository { throw new Error(`Invalid comparison value: ${reverseComparisonValue}`); } - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const existing = await entityManager.findOne(CounterTrigger, { - counter_id: counterId, - name: triggerName, + where: { + counter_id: counterId, + name: triggerName, + }, }); if (existing) { @@ -308,11 +310,13 @@ export class GuildCounters extends BaseGuildRepository { channelId = channelId || "0"; userId = userId || "0"; - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const previouslyTriggered = await entityManager.findOne(CounterTriggerState, { - trigger_id: counterTrigger.id, - user_id: userId!, - channel_id: channelId!, + where: { + trigger_id: counterTrigger.id, + user_id: userId!, + channel_id: channelId!, + }, }); if (previouslyTriggered) { @@ -356,7 +360,7 @@ export class GuildCounters extends BaseGuildRepository { async checkAllValuesForTrigger( counterTrigger: CounterTrigger, ): Promise> { - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const matchingValues = await entityManager .createQueryBuilder(CounterValue, "cv") .leftJoin( @@ -407,7 +411,7 @@ export class GuildCounters extends BaseGuildRepository { channelId = channelId || "0"; userId = userId || "0"; - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const matchingValue = await entityManager .createQueryBuilder(CounterValue, "cv") .innerJoin( @@ -446,7 +450,7 @@ export class GuildCounters extends BaseGuildRepository { async checkAllValuesForReverseTrigger( counterTrigger: CounterTrigger, ): Promise> { - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const matchingValues: Array<{ id: string; triggerStateId: string; diff --git a/backend/src/data/GuildMemberCache.ts b/backend/src/data/GuildMemberCache.ts index 39ef9b78..d64c532c 100644 --- a/backend/src/data/GuildMemberCache.ts +++ b/backend/src/data/GuildMemberCache.ts @@ -1,8 +1,9 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { Blocker } from "../Blocker"; import { DBDateFormat, MINUTES } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { MemberCacheItem } from "./entities/MemberCacheItem"; const SAVE_PENDING_BLOCKER_KEY = "save-pending" as const; @@ -20,7 +21,7 @@ export class GuildMemberCache extends BaseGuildRepository { constructor(guildId: string) { super(guildId); - this.#memberCache = getRepository(MemberCacheItem); + this.#memberCache = dataSource.getRepository(MemberCacheItem); this.#pendingUpdates = new Map(); this.#blocker = new Blocker(); } diff --git a/backend/src/data/GuildMemberTimezones.ts b/backend/src/data/GuildMemberTimezones.ts index 3f98b9ef..68e1660b 100644 --- a/backend/src/data/GuildMemberTimezones.ts +++ b/backend/src/data/GuildMemberTimezones.ts @@ -1,6 +1,6 @@ -import { getRepository, Repository } from "typeorm/index"; +import { Repository } from "typeorm/index"; import { BaseGuildRepository } from "./BaseGuildRepository"; -import { connection } from "./db"; +import { dataSource } from "./dataSource"; import { MemberTimezone } from "./entities/MemberTimezone"; export class GuildMemberTimezones extends BaseGuildRepository { @@ -8,22 +8,26 @@ export class GuildMemberTimezones extends BaseGuildRepository { constructor(guildId: string) { super(guildId); - this.memberTimezones = getRepository(MemberTimezone); + this.memberTimezones = dataSource.getRepository(MemberTimezone); } get(memberId: string) { return this.memberTimezones.findOne({ - guild_id: this.guildId, - member_id: memberId, + where: { + guild_id: this.guildId, + member_id: memberId, + }, }); } async set(memberId, timezone: string) { - await connection.transaction(async (entityManager) => { + await dataSource.transaction(async (entityManager) => { const repo = entityManager.getRepository(MemberTimezone); const existingRow = await repo.findOne({ - guild_id: this.guildId, - member_id: memberId, + where: { + guild_id: this.guildId, + member_id: memberId, + }, }); if (existingRow) { diff --git a/backend/src/data/GuildMutes.ts b/backend/src/data/GuildMutes.ts index bf0e80d2..54e7e6c0 100644 --- a/backend/src/data/GuildMutes.ts +++ b/backend/src/data/GuildMutes.ts @@ -1,9 +1,10 @@ import moment from "moment-timezone"; -import { Brackets, getRepository, Repository } from "typeorm"; +import { Brackets, Repository } from "typeorm"; import { DBDateFormat } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; -import { Mute } from "./entities/Mute"; import { MuteTypes } from "./MuteTypes"; +import { dataSource } from "./dataSource"; +import { Mute } from "./entities/Mute"; export type AddMuteParams = { userId: Mute["user_id"]; @@ -19,7 +20,7 @@ export class GuildMutes extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.mutes = getRepository(Mute); + this.mutes = dataSource.getRepository(Mute); } async getExpiredMutes(): Promise { @@ -31,7 +32,7 @@ export class GuildMutes extends BaseGuildRepository { .getMany(); } - async findExistingMuteForUserId(userId: string): Promise { + async findExistingMuteForUserId(userId: string): Promise { return this.mutes.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildNicknameHistory.ts b/backend/src/data/GuildNicknameHistory.ts index 5be3b6ae..03f9d838 100644 --- a/backend/src/data/GuildNicknameHistory.ts +++ b/backend/src/data/GuildNicknameHistory.ts @@ -1,8 +1,9 @@ -import { getRepository, In, Repository } from "typeorm"; +import { In, Repository } from "typeorm"; import { isAPI } from "../globals"; import { MINUTES, SECONDS } from "../utils"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { cleanupNicknames } from "./cleanup/nicknames"; +import { dataSource } from "./dataSource"; import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry"; const CLEANUP_INTERVAL = 5 * MINUTES; @@ -25,7 +26,7 @@ export class GuildNicknameHistory extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.nicknameHistory = getRepository(NicknameHistoryEntry); + this.nicknameHistory = dataSource.getRepository(NicknameHistoryEntry); } async getByUserId(userId): Promise { @@ -40,7 +41,7 @@ export class GuildNicknameHistory extends BaseGuildRepository { }); } - getLastEntry(userId): Promise { + getLastEntry(userId): Promise { return this.nicknameHistory.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildPersistedData.ts b/backend/src/data/GuildPersistedData.ts index 22eef70b..f0947cd1 100644 --- a/backend/src/data/GuildPersistedData.ts +++ b/backend/src/data/GuildPersistedData.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { PersistedData } from "./entities/PersistedData"; export class GuildPersistedData extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildPersistedData extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.persistedData = getRepository(PersistedData); + this.persistedData = dataSource.getRepository(PersistedData); } async find(userId: string) { diff --git a/backend/src/data/GuildPingableRoles.ts b/backend/src/data/GuildPingableRoles.ts index c8fd6f05..2f229f54 100644 --- a/backend/src/data/GuildPingableRoles.ts +++ b/backend/src/data/GuildPingableRoles.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { PingableRole } from "./entities/PingableRole"; export class GuildPingableRoles extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildPingableRoles extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.pingableRoles = getRepository(PingableRole); + this.pingableRoles = dataSource.getRepository(PingableRole); } async all(): Promise { @@ -27,7 +28,7 @@ export class GuildPingableRoles extends BaseGuildRepository { }); } - async getByChannelAndRoleId(channelId: string, roleId: string): Promise { + async getByChannelAndRoleId(channelId: string, roleId: string): Promise { return this.pingableRoles.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildReactionRoles.ts b/backend/src/data/GuildReactionRoles.ts index a3d7e30b..c1a01ca0 100644 --- a/backend/src/data/GuildReactionRoles.ts +++ b/backend/src/data/GuildReactionRoles.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { ReactionRole } from "./entities/ReactionRole"; export class GuildReactionRoles extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildReactionRoles extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.reactionRoles = getRepository(ReactionRole); + this.reactionRoles = dataSource.getRepository(ReactionRole); } async all(): Promise { @@ -30,7 +31,7 @@ export class GuildReactionRoles extends BaseGuildRepository { }); } - async getByMessageAndEmoji(messageId: string, emoji: string): Promise { + async getByMessageAndEmoji(messageId: string, emoji: string): Promise { return this.reactionRoles.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildReminders.ts b/backend/src/data/GuildReminders.ts index fac42c0f..31c7babd 100644 --- a/backend/src/data/GuildReminders.ts +++ b/backend/src/data/GuildReminders.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { Reminder } from "./entities/Reminder"; export class GuildReminders extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildReminders extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.reminders = getRepository(Reminder); + this.reminders = dataSource.getRepository(Reminder); } async getDueReminders(): Promise { @@ -28,7 +29,9 @@ export class GuildReminders extends BaseGuildRepository { } find(id: number) { - return this.reminders.findOne({ id }); + return this.reminders.findOne({ + where: { id }, + }); } async delete(id) { diff --git a/backend/src/data/GuildRoleButtons.ts b/backend/src/data/GuildRoleButtons.ts index 833fb775..c12dd2e0 100644 --- a/backend/src/data/GuildRoleButtons.ts +++ b/backend/src/data/GuildRoleButtons.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { RoleButtonsItem } from "./entities/RoleButtonsItem"; export class GuildRoleButtons extends BaseGuildRepository { @@ -7,11 +8,15 @@ export class GuildRoleButtons extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.roleButtons = getRepository(RoleButtonsItem); + this.roleButtons = dataSource.getRepository(RoleButtonsItem); } getSavedRoleButtons(): Promise { - return this.roleButtons.find({ guild_id: this.guildId }); + return this.roleButtons.find({ + where: { + guild_id: this.guildId, + }, + }); } async deleteRoleButtonItem(name: string): Promise { diff --git a/backend/src/data/GuildRoleQueue.ts b/backend/src/data/GuildRoleQueue.ts index 116df838..61172237 100644 --- a/backend/src/data/GuildRoleQueue.ts +++ b/backend/src/data/GuildRoleQueue.ts @@ -1,6 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; -import { connection } from "./db"; +import { dataSource } from "./dataSource"; import { RoleQueueItem } from "./entities/RoleQueueItem"; export class GuildRoleQueue extends BaseGuildRepository { @@ -8,11 +8,11 @@ export class GuildRoleQueue extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.roleQueue = getRepository(RoleQueueItem); + this.roleQueue = dataSource.getRepository(RoleQueueItem); } consumeNextRoleAssignments(count: number): Promise { - return connection.transaction(async (entityManager) => { + return dataSource.transaction(async (entityManager) => { const repository = entityManager.getRepository(RoleQueueItem); const nextAssignments = await repository diff --git a/backend/src/data/GuildSavedMessages.ts b/backend/src/data/GuildSavedMessages.ts index b650be6f..39eb4b7c 100644 --- a/backend/src/data/GuildSavedMessages.ts +++ b/backend/src/data/GuildSavedMessages.ts @@ -1,12 +1,13 @@ import { GuildChannel, Message } from "discord.js"; import moment from "moment-timezone"; -import { Repository, getRepository } from "typeorm"; +import { Repository } from "typeorm"; import { QueuedEventEmitter } from "../QueuedEventEmitter"; import { noop } from "../utils"; import { asyncMap } from "../utils/async"; import { decryptJson, encryptJson } from "../utils/cryptHelpers"; import { BaseGuildRepository } from "./BaseGuildRepository"; import { buildEntity } from "./buildEntity"; +import { dataSource } from "./dataSource"; import { ISavedMessageData, SavedMessage } from "./entities/SavedMessage"; export class GuildSavedMessages extends BaseGuildRepository { @@ -17,7 +18,7 @@ export class GuildSavedMessages extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.messages = getRepository(SavedMessage); + this.messages = dataSource.getRepository(SavedMessage); this.events = new QueuedEventEmitter(); this.toBePermanent = new Set(); @@ -137,7 +138,7 @@ export class GuildSavedMessages extends BaseGuildRepository { return entity; } - async find(id: string, includeDeleted = false): Promise { + async find(id: string, includeDeleted = false): Promise { let query = this.messages .createQueryBuilder() .where("guild_id = :guild_id", { guild_id: this.guildId }) diff --git a/backend/src/data/GuildScheduledPosts.ts b/backend/src/data/GuildScheduledPosts.ts index 3f10b712..eb122861 100644 --- a/backend/src/data/GuildScheduledPosts.ts +++ b/backend/src/data/GuildScheduledPosts.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { ScheduledPost } from "./entities/ScheduledPost"; export class GuildScheduledPosts extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildScheduledPosts extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.scheduledPosts = getRepository(ScheduledPost); + this.scheduledPosts = dataSource.getRepository(ScheduledPost); } all(): Promise { @@ -23,7 +24,11 @@ export class GuildScheduledPosts extends BaseGuildRepository { } find(id: number) { - return this.scheduledPosts.findOne({ id }); + return this.scheduledPosts.findOne({ + where: { + id, + }, + }); } async delete(id) { diff --git a/backend/src/data/GuildSlowmodes.ts b/backend/src/data/GuildSlowmodes.ts index dac92ead..ee92a3f5 100644 --- a/backend/src/data/GuildSlowmodes.ts +++ b/backend/src/data/GuildSlowmodes.ts @@ -1,6 +1,7 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { SlowmodeChannel } from "./entities/SlowmodeChannel"; import { SlowmodeUser } from "./entities/SlowmodeUser"; @@ -10,11 +11,11 @@ export class GuildSlowmodes extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.slowmodeChannels = getRepository(SlowmodeChannel); - this.slowmodeUsers = getRepository(SlowmodeUser); + this.slowmodeChannels = dataSource.getRepository(SlowmodeChannel); + this.slowmodeUsers = dataSource.getRepository(SlowmodeUser); } - async getChannelSlowmode(channelId): Promise { + async getChannelSlowmode(channelId): Promise { return this.slowmodeChannels.findOne({ where: { guild_id: this.guildId, @@ -51,11 +52,13 @@ export class GuildSlowmodes extends BaseGuildRepository { }); } - async getChannelSlowmodeUser(channelId, userId): Promise { + async getChannelSlowmodeUser(channelId, userId): Promise { return this.slowmodeUsers.findOne({ - guild_id: this.guildId, - channel_id: channelId, - user_id: userId, + where: { + guild_id: this.guildId, + channel_id: channelId, + user_id: userId, + }, }); } diff --git a/backend/src/data/GuildStarboardMessages.ts b/backend/src/data/GuildStarboardMessages.ts index 0e932928..d5e56870 100644 --- a/backend/src/data/GuildStarboardMessages.ts +++ b/backend/src/data/GuildStarboardMessages.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { StarboardMessage } from "./entities/StarboardMessage"; export class GuildStarboardMessages extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildStarboardMessages extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.allStarboardMessages = getRepository(StarboardMessage); + this.allStarboardMessages = dataSource.getRepository(StarboardMessage); } async getStarboardMessagesForMessageId(messageId: string) { diff --git a/backend/src/data/GuildStarboardReactions.ts b/backend/src/data/GuildStarboardReactions.ts index 413b7120..9c74d6dd 100644 --- a/backend/src/data/GuildStarboardReactions.ts +++ b/backend/src/data/GuildStarboardReactions.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { StarboardReaction } from "./entities/StarboardReaction"; export class GuildStarboardReactions extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildStarboardReactions extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.allStarboardReactions = getRepository(StarboardReaction); + this.allStarboardReactions = dataSource.getRepository(StarboardReaction); } async getAllReactionsForMessageId(messageId: string) { diff --git a/backend/src/data/GuildStats.ts b/backend/src/data/GuildStats.ts index d70623dd..9a3c0e9a 100644 --- a/backend/src/data/GuildStats.ts +++ b/backend/src/data/GuildStats.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { StatValue } from "./entities/StatValue"; export class GuildStats extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildStats extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.stats = getRepository(StatValue); + this.stats = dataSource.getRepository(StatValue); } async saveValue(source: string, key: string, value: number): Promise { diff --git a/backend/src/data/GuildTags.ts b/backend/src/data/GuildTags.ts index 2d64f8bf..004c4dbe 100644 --- a/backend/src/data/GuildTags.ts +++ b/backend/src/data/GuildTags.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { Tag } from "./entities/Tag"; import { TagResponse } from "./entities/TagResponse"; @@ -9,8 +10,8 @@ export class GuildTags extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.tags = getRepository(Tag); - this.tagResponses = getRepository(TagResponse); + this.tags = dataSource.getRepository(Tag); + this.tagResponses = dataSource.getRepository(TagResponse); } async all(): Promise { @@ -21,7 +22,7 @@ export class GuildTags extends BaseGuildRepository { }); } - async find(tag): Promise { + async find(tag): Promise { return this.tags.findOne({ where: { guild_id: this.guildId, @@ -61,7 +62,7 @@ export class GuildTags extends BaseGuildRepository { }); } - async findResponseByCommandMessageId(messageId: string): Promise { + async findResponseByCommandMessageId(messageId: string): Promise { return this.tagResponses.findOne({ where: { guild_id: this.guildId, @@ -70,7 +71,7 @@ export class GuildTags extends BaseGuildRepository { }); } - async findResponseByResponseMessageId(messageId: string): Promise { + async findResponseByResponseMessageId(messageId: string): Promise { return this.tagResponses.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildTempbans.ts b/backend/src/data/GuildTempbans.ts index 6085a193..e74ba7a0 100644 --- a/backend/src/data/GuildTempbans.ts +++ b/backend/src/data/GuildTempbans.ts @@ -1,6 +1,7 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { Tempban } from "./entities/Tempban"; export class GuildTempbans extends BaseGuildRepository { @@ -8,7 +9,7 @@ export class GuildTempbans extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.tempbans = getRepository(Tempban); + this.tempbans = dataSource.getRepository(Tempban); } async getExpiredTempbans(): Promise { @@ -20,7 +21,7 @@ export class GuildTempbans extends BaseGuildRepository { .getMany(); } - async findExistingTempbanForUserId(userId: string): Promise { + async findExistingTempbanForUserId(userId: string): Promise { return this.tempbans.findOne({ where: { guild_id: this.guildId, diff --git a/backend/src/data/GuildVCAlerts.ts b/backend/src/data/GuildVCAlerts.ts index 210a91c9..104196e2 100644 --- a/backend/src/data/GuildVCAlerts.ts +++ b/backend/src/data/GuildVCAlerts.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseGuildRepository } from "./BaseGuildRepository"; +import { dataSource } from "./dataSource"; import { VCAlert } from "./entities/VCAlert"; export class GuildVCAlerts extends BaseGuildRepository { @@ -7,7 +8,7 @@ export class GuildVCAlerts extends BaseGuildRepository { constructor(guildId) { super(guildId); - this.allAlerts = getRepository(VCAlert); + this.allAlerts = dataSource.getRepository(VCAlert); } async getOutdatedAlerts(): Promise { @@ -41,7 +42,9 @@ export class GuildVCAlerts extends BaseGuildRepository { } find(id: number) { - return this.allAlerts.findOne({ id }); + return this.allAlerts.findOne({ + where: { id }, + }); } async delete(id) { diff --git a/backend/src/data/MemberCache.ts b/backend/src/data/MemberCache.ts index 29cc61aa..b727c66e 100644 --- a/backend/src/data/MemberCache.ts +++ b/backend/src/data/MemberCache.ts @@ -1,7 +1,8 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DAYS } from "../utils"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { MemberCacheItem } from "./entities/MemberCacheItem"; const STALE_PERIOD = 90 * DAYS; @@ -11,7 +12,7 @@ export class MemberCache extends BaseRepository { constructor() { super(); - this.#memberCache = getRepository(MemberCacheItem); + this.#memberCache = dataSource.getRepository(MemberCacheItem); } async deleteStaleData(): Promise { diff --git a/backend/src/data/Mutes.ts b/backend/src/data/Mutes.ts index 5139ce9d..ec7f11cc 100644 --- a/backend/src/data/Mutes.ts +++ b/backend/src/data/Mutes.ts @@ -1,9 +1,10 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DAYS, DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; -import { Mute } from "./entities/Mute"; import { MuteTypes } from "./MuteTypes"; +import { dataSource } from "./dataSource"; +import { Mute } from "./entities/Mute"; const OLD_EXPIRED_MUTE_THRESHOLD = 7 * DAYS; @@ -16,10 +17,10 @@ export class Mutes extends BaseRepository { constructor() { super(); - this.mutes = getRepository(Mute); + this.mutes = dataSource.getRepository(Mute); } - findMute(guildId: string, userId: string): Promise { + findMute(guildId: string, userId: string): Promise { return this.mutes.findOne({ where: { guild_id: guildId, diff --git a/backend/src/data/Phisherman.ts b/backend/src/data/Phisherman.ts index 07b0cdb0..42f1fce9 100644 --- a/backend/src/data/Phisherman.ts +++ b/backend/src/data/Phisherman.ts @@ -1,8 +1,9 @@ import crypto from "crypto"; import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { env } from "../env"; import { DAYS, DBDateFormat, HOURS, MINUTES } from "../utils"; +import { dataSource } from "./dataSource"; import { PhishermanCacheEntry } from "./entities/PhishermanCacheEntry"; import { PhishermanKeyCacheEntry } from "./entities/PhishermanKeyCacheEntry"; import { PhishermanDomainInfo, PhishermanUnknownDomain } from "./types/phisherman"; @@ -39,7 +40,7 @@ const KEY_VALIDITY_LIFETIME = 24 * HOURS; let cacheRepository: Repository | null = null; function getCacheRepository(): Repository { if (cacheRepository == null) { - cacheRepository = getRepository(PhishermanCacheEntry); + cacheRepository = dataSource.getRepository(PhishermanCacheEntry); } return cacheRepository; } @@ -47,7 +48,7 @@ function getCacheRepository(): Repository { let keyCacheRepository: Repository | null = null; function getKeyCacheRepository(): Repository { if (keyCacheRepository == null) { - keyCacheRepository = getRepository(PhishermanKeyCacheEntry); + keyCacheRepository = dataSource.getRepository(PhishermanKeyCacheEntry); } return keyCacheRepository; } @@ -153,7 +154,9 @@ export async function getPhishermanDomainInfo(domain: string): Promise const keyCache = getKeyCacheRepository(); const hash = crypto.createHash("sha256").update(apiKey).digest("hex"); - const entry = await keyCache.findOne({ hash }); + const entry = await keyCache.findOne({ + where: { hash }, + }); if (entry) { return entry.is_valid; } diff --git a/backend/src/data/Reminders.ts b/backend/src/data/Reminders.ts index 0c35c4e2..1e6333d2 100644 --- a/backend/src/data/Reminders.ts +++ b/backend/src/data/Reminders.ts @@ -1,7 +1,8 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { Reminder } from "./entities/Reminder"; export class Reminders extends BaseRepository { @@ -9,7 +10,7 @@ export class Reminders extends BaseRepository { constructor() { super(); - this.reminders = getRepository(Reminder); + this.reminders = dataSource.getRepository(Reminder); } async getRemindersDueSoon(threshold: number): Promise { diff --git a/backend/src/data/ScheduledPosts.ts b/backend/src/data/ScheduledPosts.ts index 1931ce6e..ec5fafe8 100644 --- a/backend/src/data/ScheduledPosts.ts +++ b/backend/src/data/ScheduledPosts.ts @@ -1,7 +1,8 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { ScheduledPost } from "./entities/ScheduledPost"; export class ScheduledPosts extends BaseRepository { @@ -9,7 +10,7 @@ export class ScheduledPosts extends BaseRepository { constructor() { super(); - this.scheduledPosts = getRepository(ScheduledPost); + this.scheduledPosts = dataSource.getRepository(ScheduledPost); } getScheduledPostsDueSoon(threshold: number): Promise { diff --git a/backend/src/data/Supporters.ts b/backend/src/data/Supporters.ts index 58b1b2d3..679d58d1 100644 --- a/backend/src/data/Supporters.ts +++ b/backend/src/data/Supporters.ts @@ -1,5 +1,6 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { Supporter } from "./entities/Supporter"; export class Supporters extends BaseRepository { @@ -7,7 +8,7 @@ export class Supporters extends BaseRepository { constructor() { super(); - this.supporters = getRepository(Supporter); + this.supporters = dataSource.getRepository(Supporter); } getAll() { diff --git a/backend/src/data/Tempbans.ts b/backend/src/data/Tempbans.ts index a24d3fd8..8346b1a1 100644 --- a/backend/src/data/Tempbans.ts +++ b/backend/src/data/Tempbans.ts @@ -1,7 +1,8 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { Tempban } from "./entities/Tempban"; export class Tempbans extends BaseRepository { @@ -9,7 +10,7 @@ export class Tempbans extends BaseRepository { constructor() { super(); - this.tempbans = getRepository(Tempban); + this.tempbans = dataSource.getRepository(Tempban); } getSoonExpiringTempbans(threshold: number): Promise { diff --git a/backend/src/data/UsernameHistory.ts b/backend/src/data/UsernameHistory.ts index 224ba99a..59082ca4 100644 --- a/backend/src/data/UsernameHistory.ts +++ b/backend/src/data/UsernameHistory.ts @@ -1,8 +1,9 @@ -import { getRepository, In, Repository } from "typeorm"; +import { In, Repository } from "typeorm"; import { isAPI } from "../globals"; import { MINUTES, SECONDS } from "../utils"; import { BaseRepository } from "./BaseRepository"; import { cleanupUsernames } from "./cleanup/usernames"; +import { dataSource } from "./dataSource"; import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry"; const CLEANUP_INTERVAL = 5 * MINUTES; @@ -25,7 +26,7 @@ export class UsernameHistory extends BaseRepository { constructor() { super(); - this.usernameHistory = getRepository(UsernameHistoryEntry); + this.usernameHistory = dataSource.getRepository(UsernameHistoryEntry); } async getByUserId(userId): Promise { @@ -40,7 +41,7 @@ export class UsernameHistory extends BaseRepository { }); } - getLastEntry(userId): Promise { + getLastEntry(userId): Promise { return this.usernameHistory.findOne({ where: { user_id: userId, diff --git a/backend/src/data/VCAlerts.ts b/backend/src/data/VCAlerts.ts index 1296b033..d5361f57 100644 --- a/backend/src/data/VCAlerts.ts +++ b/backend/src/data/VCAlerts.ts @@ -1,7 +1,8 @@ import moment from "moment-timezone"; -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { DBDateFormat } from "../utils"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { VCAlert } from "./entities/VCAlert"; export class VCAlerts extends BaseRepository { @@ -9,7 +10,7 @@ export class VCAlerts extends BaseRepository { constructor() { super(); - this.allAlerts = getRepository(VCAlert); + this.allAlerts = dataSource.getRepository(VCAlert); } async getSoonExpiringAlerts(threshold: number): Promise { diff --git a/backend/src/data/Webhooks.ts b/backend/src/data/Webhooks.ts index fb1e92ac..71927984 100644 --- a/backend/src/data/Webhooks.ts +++ b/backend/src/data/Webhooks.ts @@ -1,10 +1,11 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; import { decrypt, encrypt } from "../utils/crypt"; import { BaseRepository } from "./BaseRepository"; +import { dataSource } from "./dataSource"; import { Webhook } from "./entities/Webhook"; export class Webhooks extends BaseRepository { - repository: Repository = getRepository(Webhook); + repository: Repository = dataSource.getRepository(Webhook); protected async _processEntityFromDB(entity) { entity.token = await decrypt(entity.token); diff --git a/backend/src/data/cleanup/configs.ts b/backend/src/data/cleanup/configs.ts index 58c6da24..66f1e657 100644 --- a/backend/src/data/cleanup/configs.ts +++ b/backend/src/data/cleanup/configs.ts @@ -1,13 +1,13 @@ import moment from "moment-timezone"; -import { getRepository, In } from "typeorm"; +import { In } from "typeorm"; import { DBDateFormat } from "../../utils"; -import { connection } from "../db"; +import { dataSource } from "../dataSource"; import { Config } from "../entities/Config"; const CLEAN_PER_LOOP = 50; export async function cleanupConfigs() { - const configRepository = getRepository(Config); + const configRepository = dataSource.getRepository(Config); // FIXME: The query below doesn't work on MySQL 8.0. Pending an update. return; @@ -18,7 +18,7 @@ export async function cleanupConfigs() { // >1 month old: 1 config retained per month const oneMonthCutoff = moment.utc().subtract(30, "days").format(DBDateFormat); do { - rows = await connection.query( + rows = await dataSource.query( ` WITH _configs AS ( @@ -56,7 +56,7 @@ export async function cleanupConfigs() { // >2 weeks old: 1 config retained per day const twoWeekCutoff = moment.utc().subtract(2, "weeks").format(DBDateFormat); do { - rows = await connection.query( + rows = await dataSource.query( ` WITH _configs AS ( diff --git a/backend/src/data/cleanup/messages.ts b/backend/src/data/cleanup/messages.ts index f94b55d3..18d416a0 100644 --- a/backend/src/data/cleanup/messages.ts +++ b/backend/src/data/cleanup/messages.ts @@ -1,7 +1,7 @@ import moment from "moment-timezone"; -import { getRepository, In } from "typeorm"; +import { In } from "typeorm"; import { DAYS, DBDateFormat, MINUTES, SECONDS, sleep } from "../../utils"; -import { connection } from "../db"; +import { dataSource } from "../dataSource"; import { SavedMessage } from "../entities/SavedMessage"; /** @@ -16,7 +16,7 @@ const CLEAN_PER_LOOP = 100; export async function cleanupMessages(): Promise { let cleaned = 0; - const messagesRepository = getRepository(SavedMessage); + const messagesRepository = dataSource.getRepository(SavedMessage); const deletedAtThreshold = moment.utc().subtract(DELETED_MESSAGE_RETENTION_PERIOD, "ms").format(DBDateFormat); const postedAtThreshold = moment.utc().subtract(RETENTION_PERIOD, "ms").format(DBDateFormat); @@ -27,7 +27,7 @@ export async function cleanupMessages(): Promise { // when a message was being inserted at the same time let ids: string[]; do { - const deletedMessageRows = await connection.query( + const deletedMessageRows = await dataSource.query( ` SELECT id FROM messages @@ -40,7 +40,7 @@ export async function cleanupMessages(): Promise { [deletedAtThreshold], ); - const oldPostedRows = await connection.query( + const oldPostedRows = await dataSource.query( ` SELECT id FROM messages @@ -53,7 +53,7 @@ export async function cleanupMessages(): Promise { [postedAtThreshold], ); - const oldBotPostedRows = await connection.query( + const oldBotPostedRows = await dataSource.query( ` SELECT id FROM messages diff --git a/backend/src/data/cleanup/nicknames.ts b/backend/src/data/cleanup/nicknames.ts index addaa347..da3406fd 100644 --- a/backend/src/data/cleanup/nicknames.ts +++ b/backend/src/data/cleanup/nicknames.ts @@ -1,7 +1,7 @@ import moment from "moment-timezone"; -import { getRepository, In } from "typeorm"; +import { In } from "typeorm"; import { DAYS, DBDateFormat } from "../../utils"; -import { connection } from "../db"; +import { dataSource } from "../dataSource"; import { NicknameHistoryEntry } from "../entities/NicknameHistoryEntry"; export const NICKNAME_RETENTION_PERIOD = 30 * DAYS; @@ -10,13 +10,13 @@ const CLEAN_PER_LOOP = 500; export async function cleanupNicknames(): Promise { let cleaned = 0; - const nicknameHistoryRepository = getRepository(NicknameHistoryEntry); + const nicknameHistoryRepository = dataSource.getRepository(NicknameHistoryEntry); const dateThreshold = moment.utc().subtract(NICKNAME_RETENTION_PERIOD, "ms").format(DBDateFormat); // Clean old nicknames (NICKNAME_RETENTION_PERIOD) let rows; do { - rows = await connection.query( + rows = await dataSource.query( ` SELECT id FROM nickname_history diff --git a/backend/src/data/cleanup/usernames.ts b/backend/src/data/cleanup/usernames.ts index 63ac79f8..982e3bfe 100644 --- a/backend/src/data/cleanup/usernames.ts +++ b/backend/src/data/cleanup/usernames.ts @@ -1,7 +1,7 @@ import moment from "moment-timezone"; -import { getRepository, In } from "typeorm"; +import { In } from "typeorm"; import { DAYS, DBDateFormat } from "../../utils"; -import { connection } from "../db"; +import { dataSource } from "../dataSource"; import { UsernameHistoryEntry } from "../entities/UsernameHistoryEntry"; export const USERNAME_RETENTION_PERIOD = 30 * DAYS; @@ -10,13 +10,13 @@ const CLEAN_PER_LOOP = 500; export async function cleanupUsernames(): Promise { let cleaned = 0; - const usernameHistoryRepository = getRepository(UsernameHistoryEntry); + const usernameHistoryRepository = dataSource.getRepository(UsernameHistoryEntry); const dateThreshold = moment.utc().subtract(USERNAME_RETENTION_PERIOD, "ms").format(DBDateFormat); // Clean old usernames (USERNAME_RETENTION_PERIOD) let rows; do { - rows = await connection.query( + rows = await dataSource.query( ` SELECT id FROM username_history diff --git a/backend/ormconfig.js b/backend/src/data/dataSource.ts similarity index 71% rename from backend/ormconfig.js rename to backend/src/data/dataSource.ts index a3a8f122..badbf187 100644 --- a/backend/ormconfig.js +++ b/backend/src/data/dataSource.ts @@ -1,16 +1,15 @@ -const fs = require("fs"); -const path = require("path"); -const { backendDir } = require("./dist/backend/src/paths"); -const { env } = require("./dist/backend/src/env"); +import moment from "moment-timezone"; +import path from "path"; +import { DataSource } from "typeorm"; +import { env } from "../env"; +import { backendDir } from "../paths"; -const moment = require("moment-timezone"); moment.tz.setDefault("UTC"); const entities = path.relative(process.cwd(), path.resolve(backendDir, "dist/backend/src/data/entities/*.js")); const migrations = path.relative(process.cwd(), path.resolve(backendDir, "dist/backend/src/migrations/*.js")); -const migrationsDir = path.relative(process.cwd(), path.resolve(backendDir, "src/migrations")); -module.exports = { +export const dataSource = new DataSource({ type: "mysql", host: env.DB_HOST, port: env.DB_PORT, @@ -43,7 +42,4 @@ module.exports = { // Migrations migrations: [migrations], - cli: { - migrationsDir, - }, -}; +}); diff --git a/backend/src/data/db.ts b/backend/src/data/db.ts index 798b077c..a4f9b88b 100644 --- a/backend/src/data/db.ts +++ b/backend/src/data/db.ts @@ -1,33 +1,15 @@ -import path from "path"; -import { Connection, createConnection } from "typeorm"; import { SimpleError } from "../SimpleError"; -import { backendDir } from "../paths"; -import { QueryLogger } from "./queryLogger"; +import { dataSource } from "./dataSource"; -const ormconfigPath = path.join(backendDir, "ormconfig.js"); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const connectionOptions = require(ormconfigPath); - -let connectionPromise: Promise; - -export let connection: Connection; +let connectionPromise: Promise; export function connect() { if (!connectionPromise) { - connectionPromise = createConnection({ - ...(connectionOptions as any), - logging: ["query", "error"], - logger: new QueryLogger(), - }).then((newConnection) => { - // Verify the DB timezone is set to UTC - return newConnection.query("SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) AS tz").then((r) => { - if (r[0].tz !== "00:00:00") { - throw new SimpleError(`Database timezone must be UTC (detected ${r[0].tz})`); - } - - connection = newConnection; - return newConnection; - }); + connectionPromise = dataSource.initialize().then(async (initializedDataSource) => { + const tzResult = await initializedDataSource.query("SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) AS tz"); + if (tzResult[0].tz !== "00:00:00") { + throw new SimpleError(`Database timezone must be UTC (detected ${tzResult[0].tz})`); + } }); } diff --git a/backend/src/data/getChannelIdFromMessageId.ts b/backend/src/data/getChannelIdFromMessageId.ts index 0558ee69..59095afb 100644 --- a/backend/src/data/getChannelIdFromMessageId.ts +++ b/backend/src/data/getChannelIdFromMessageId.ts @@ -1,14 +1,15 @@ -import { getRepository, Repository } from "typeorm"; +import { Repository } from "typeorm"; +import { dataSource } from "./dataSource"; import { SavedMessage } from "./entities/SavedMessage"; let repository: Repository; export async function getChannelIdFromMessageId(messageId: string): Promise { if (!repository) { - repository = getRepository(SavedMessage); + repository = dataSource.getRepository(SavedMessage); } - const savedMessage = await repository.findOne(messageId); + const savedMessage = await repository.findOne({ where: { id: messageId } }); if (savedMessage) { return savedMessage.channel_id; } diff --git a/backend/src/index.ts b/backend/src/index.ts index 73d99470..2fe16c11 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -25,6 +25,7 @@ import { Configs } from "./data/Configs"; import { GuildLogs } from "./data/GuildLogs"; import { LogType } from "./data/LogType"; import { hasPhishermanMasterAPIKey } from "./data/Phisherman"; +import { dataSource } from "./data/dataSource"; import { connect } from "./data/db"; import { runExpiredArchiveDeletionLoop } from "./data/loops/expiredArchiveDeletionLoop"; import { runExpiredMemberCacheDeletionLoop } from "./data/loops/expiredMemberCacheDeletionLoop"; @@ -445,7 +446,7 @@ connect().then(async (connection) => { // Force exit after 10sec setTimeout(() => process.exit(code), 10 * SECONDS); await bot.stop(); - await connection.close(); + await dataSource.destroy(); logger.info("Done! Exiting now."); process.exit(code); }; diff --git a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts index 7924392b..18c7d0d7 100644 --- a/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts +++ b/backend/src/plugins/BotControl/commands/ListDashboardPermsCmd.ts @@ -20,7 +20,7 @@ export const ListDashboardPermsCmd = botControlCmd({ return; } - let guild: AllowedGuild | undefined; + let guild: AllowedGuild | null = null; if (args.guildId) { guild = await pluginData.state.allowedGuilds.find(args.guildId); if (!guild) { diff --git a/backend/src/plugins/Mutes/functions/muteUser.ts b/backend/src/plugins/Mutes/functions/muteUser.ts index 71081e8c..fc864ada 100644 --- a/backend/src/plugins/Mutes/functions/muteUser.ts +++ b/backend/src/plugins/Mutes/functions/muteUser.ts @@ -208,8 +208,8 @@ export async function muteUser( // Create/update a case const casesPlugin = pluginData.getPlugin(CasesPlugin); - let theCase: Case | undefined = - existingMute && existingMute.case_id ? await pluginData.state.cases.find(existingMute.case_id) : undefined; + let theCase: Case | null = + existingMute && existingMute.case_id ? await pluginData.state.cases.find(existingMute.case_id) : null; if (theCase) { // Update old case diff --git a/backend/src/plugins/Utility/commands/CleanCmd.ts b/backend/src/plugins/Utility/commands/CleanCmd.ts index 11da9129..18d4efa2 100644 --- a/backend/src/plugins/Utility/commands/CleanCmd.ts +++ b/backend/src/plugins/Utility/commands/CleanCmd.ts @@ -6,11 +6,8 @@ import { LogType } from "../../../data/LogType"; import { SavedMessage } from "../../../data/entities/SavedMessage"; import { humanizeDurationShort } from "../../../humanizeDurationShort"; import { getBaseUrl, sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils"; -import { allowTimeout } from "../../../RegExpRunner"; -import { chunkArray, DAYS, getInviteCodesInString, noop, SECONDS } from "../../../utils"; -import { utilityCmd, UtilityPluginType } from "../types"; import { ModActionsPlugin } from "../../../plugins/ModActions/ModActionsPlugin"; -import { DAYS, SECONDS, getInviteCodesInString, noop } from "../../../utils"; +import { DAYS, SECONDS, chunkArray, getInviteCodesInString, noop } from "../../../utils"; import { LogsPlugin } from "../../Logs/LogsPlugin"; import { UtilityPluginType, utilityCmd } from "../types";