Compare commits

...

5 commits

Author SHA1 Message Date
f95cb380c6 Update import to match new database folder
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2023-06-12 17:23:40 +01:00
eaf6838864 Merge branch 'develop' into feature/98-timeout-command 2023-06-12 17:22:19 +01:00
6c334cea81 Update dependency typeorm to v0.3.16 (#237)
Some checks failed
continuous-integration/drone/push Build is failing
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [typeorm](https://typeorm.io) ([source](https://github.com/typeorm/typeorm)) | dependencies | patch | [`0.3.14` -> `0.3.16`](https://renovatebot.com/diffs/npm/typeorm/0.3.14/0.3.16) |

---

### Release Notes

<details>
<summary>typeorm/typeorm</summary>

### [`v0.3.16`](https://github.com/typeorm/typeorm/blob/HEAD/CHANGELOG.md#&#8203;0316-httpsgithubcomtypeormtypeormcompare03150316-2023-05-09)

[Compare Source](https://github.com/typeorm/typeorm/compare/0.3.15...0.3.16)

##### Bug Fixes

-   add `trustServerCertificate` option to `SqlServerConnectionOptions` ([#&#8203;9985](https://github.com/typeorm/typeorm/issues/9985)) ([0305805](03058055df)), closes [#&#8203;8093](https://github.com/typeorm/typeorm/issues/8093)
-   add directConnection options to MongoDB connection ([#&#8203;9955](https://github.com/typeorm/typeorm/issues/9955)) ([e0165e7](e0165e75ee))
-   add onDelete option validation for oracle ([#&#8203;9786](https://github.com/typeorm/typeorm/issues/9786)) ([938f94b](938f94bded)), closes [#&#8203;9189](https://github.com/typeorm/typeorm/issues/9189)
-   added instanceName to options ([#&#8203;9968](https://github.com/typeorm/typeorm/issues/9968)) ([7c5627f](7c5627f272))
-   added transaction retry logic in cockroachdb ([#&#8203;10032](https://github.com/typeorm/typeorm/issues/10032)) ([607d6f9](607d6f9595))
-   allow json as alias for longtext mariadb ([#&#8203;10018](https://github.com/typeorm/typeorm/issues/10018)) ([2a2bb4b](2a2bb4bdc1))
-   convert the join table ID to the referenceColumn ID type ([#&#8203;9887](https://github.com/typeorm/typeorm/issues/9887)) ([9460296](9460296147))
-   correct encode mongodb auth credentials ([#&#8203;10024](https://github.com/typeorm/typeorm/issues/10024)) ([96b7ee4](96b7ee44b2)), closes [#&#8203;9885](https://github.com/typeorm/typeorm/issues/9885)
-   create correct children during cascade saving entities with STI ([#&#8203;9034](https://github.com/typeorm/typeorm/issues/9034)) ([06c1e98](06c1e98ae2)), closes [#&#8203;7758](https://github.com/typeorm/typeorm/issues/7758) [#&#8203;7758](https://github.com/typeorm/typeorm/issues/7758) [#&#8203;9033](https://github.com/typeorm/typeorm/issues/9033) [#&#8203;9033](https://github.com/typeorm/typeorm/issues/9033) [#&#8203;7758](https://github.com/typeorm/typeorm/issues/7758) [#&#8203;7758](https://github.com/typeorm/typeorm/issues/7758)
-   express option bug in init command ([#&#8203;10022](https://github.com/typeorm/typeorm/issues/10022)) ([5be20e2](5be20e2bcd))
-   for running cli-ts-node-esm use exit code from child process ([#&#8203;10030](https://github.com/typeorm/typeorm/issues/10030)) ([a188b1d](a188b1d9f4)), closes [#&#8203;10029](https://github.com/typeorm/typeorm/issues/10029)
-   mongodb typings breaks the browser version ([#&#8203;9962](https://github.com/typeorm/typeorm/issues/9962)) ([99bef49](99bef49128)), closes [#&#8203;9959](https://github.com/typeorm/typeorm/issues/9959)
-   RelationIdLoader has access to queryPlanner when wrapped in transaction ([#&#8203;9990](https://github.com/typeorm/typeorm/issues/9990)) ([21a9d67](21a9d67fcf)), closes [#&#8203;9988](https://github.com/typeorm/typeorm/issues/9988)
-   resolve duplicate subscriber updated columns ([#&#8203;9958](https://github.com/typeorm/typeorm/issues/9958)) ([3d67901](3d67901fde)), closes [#&#8203;9948](https://github.com/typeorm/typeorm/issues/9948)
-   select + addOrderBy broke in 0.3.14 ([#&#8203;9961](https://github.com/typeorm/typeorm/issues/9961)) ([0e56f0f](0e56f0fcf8)), closes [#&#8203;9960](https://github.com/typeorm/typeorm/issues/9960)
-   support More/LessThanOrEqual in relations  ([#&#8203;9978](https://github.com/typeorm/typeorm/issues/9978)) ([8795c86](8795c864e8))

##### Features

-   mariadb uuid inet4 inet6 column data type support ([#&#8203;9845](https://github.com/typeorm/typeorm/issues/9845)) ([d8a2e37](d8a2e3730f))

##### Reverts

-   "refactor: remove date-fns package ([#&#8203;9634](https://github.com/typeorm/typeorm/issues/9634))" ([54f4f89](54f4f8986a))

### [`v0.3.15`](https://github.com/typeorm/typeorm/blob/HEAD/CHANGELOG.md#&#8203;0315-httpsgithubcomtypeormtypeormcompare03140315-2023-04-15)

[Compare Source](https://github.com/typeorm/typeorm/compare/0.3.14...0.3.15)

##### Bug Fixes

-   make cache optional fields optional ([#&#8203;9942](https://github.com/typeorm/typeorm/issues/9942)) ([159c60a](159c60a6e8))
-   prevent unique index identical to primary key (all sql dialects) ([#&#8203;9940](https://github.com/typeorm/typeorm/issues/9940)) ([51eecc2](51eecc2aa0))
-   SelectQueryBuilder builds incorrectly escaped alias in Oracle when used on entity with composite key ([#&#8203;9668](https://github.com/typeorm/typeorm/issues/9668)) ([83c6c0e](83c6c0ed80))

##### Features

-   support for the latest mongodb v5 ([#&#8203;9925](https://github.com/typeorm/typeorm/issues/9925)) ([f6a3ce7](f6a3ce732d)), closes [#&#8203;7907](https://github.com/typeorm/typeorm/issues/7907) [#&#8203;7907](https://github.com/typeorm/typeorm/issues/7907)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9-->

Co-authored-by: Renovate Bot <renovate@vylpes.com>
Co-authored-by: Ethan Lane <ethan@vylpes.com>
Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/237
Co-authored-by: RenovateBot <renovate@vylpes.com>
Co-committed-by: RenovateBot <renovate@vylpes.com>
2023-06-12 17:19:58 +01:00
e6c845e3b2 Switch to TypeORM's DataSource API (#299)
Some checks failed
continuous-integration/drone/push Build is failing
- Switch to TypeORM's DataSource API, rather than using the now deprecated ormconfig.json
- This will fix stage deployment not knowing how to deploy the database migrations

#297

> **NOTE:** This change requires the deployment scripts to be updated, please update them on the server before merging

Co-authored-by: Ethan Lane <ethan@vylpes.com>
Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/299
2023-05-26 17:59:22 +01:00
c2418381ea Update dependency minimatch to v9 (#286)
Some checks failed
continuous-integration/drone/push Build is failing
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [minimatch](https://github.com/isaacs/minimatch) | dependencies | major | [`7.4.6` -> `9.0.1`](https://renovatebot.com/diffs/npm/minimatch/7.4.6/9.0.1) |

---

### Release Notes

<details>
<summary>isaacs/minimatch</summary>

### [`v9.0.1`](https://github.com/isaacs/minimatch/compare/v9.0.0...v9.0.1)

[Compare Source](https://github.com/isaacs/minimatch/compare/v9.0.0...v9.0.1)

### [`v9.0.0`](https://github.com/isaacs/minimatch/compare/v8.0.4...v9.0.0)

[Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.4...v9.0.0)

### [`v8.0.4`](https://github.com/isaacs/minimatch/compare/v8.0.3...v8.0.4)

[Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.3...v8.0.4)

### [`v8.0.3`](https://github.com/isaacs/minimatch/compare/v8.0.2...v8.0.3)

[Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.2...v8.0.3)

### [`v8.0.2`](https://github.com/isaacs/minimatch/compare/v8.0.1...v8.0.2)

[Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.1...v8.0.2)

### [`v8.0.1`](https://github.com/isaacs/minimatch/compare/v8.0.0...v8.0.1)

[Compare Source](https://github.com/isaacs/minimatch/compare/v8.0.0...v8.0.1)

### [`v8.0.0`](https://github.com/isaacs/minimatch/compare/v7.4.6...v8.0.0)

[Compare Source](https://github.com/isaacs/minimatch/compare/v7.4.6...v8.0.0)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC43NC4yIiwidXBkYXRlZEluVmVyIjoiMzQuNzQuMiJ9-->

Co-authored-by: Renovate Bot <renovate@vylpes.com>
Reviewed-on: https://gitea.vylpes.xyz/RabbitLabs/vylbot-app/pulls/286
Co-authored-by: RenovateBot <renovate@vylpes.com>
Co-committed-by: RenovateBot <renovate@vylpes.com>
2023-05-22 18:07:24 +01:00
40 changed files with 166 additions and 182 deletions

View file

@ -15,3 +15,11 @@ BOT_CLIENTID=682942374040961060
ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_FUNDING=https://ko-fi.com/vylpes
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
DB_HOST=127.0.0.1
DB_PORT=3101
DB_NAME=vylbot
DB_AUTH_USER=dev
DB_AUTH_PASS=dev
DB_SYNC=true
DB_LOGGING=true

View file

@ -14,3 +14,11 @@ BOT_CLIENTID=680083120896081954
ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_FUNDING=https://ko-fi.com/vylpes
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
DB_HOST=127.0.0.1
DB_PORT=3121
DB_NAME=vylbot
DB_AUTH_USER=prod
DB_AUTH_PASS=prod
DB_SYNC=false
DB_LOGGING=false

View file

@ -14,3 +14,11 @@ BOT_CLIENTID=1016767908740857949
ABOUT_FUNDING=https://ko-fi.com/vylpes ABOUT_FUNDING=https://ko-fi.com/vylpes
ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app ABOUT_REPO=https://gitea.vylpes.xyz/RabbitLabs/vylbot-app
DB_HOST=127.0.0.1
DB_PORT=3111
DB_NAME=vylbot
DB_AUTH_USER=stage
DB_AUTH_PASS=stage
DB_SYNC=false
DB_LOGGING=false

View file

@ -1,24 +0,0 @@
{
"type": "mysql",
"host": "localhost",
"port": 3101,
"username": "dev",
"password": "dev",
"database": "vylbot",
"synchronize": false,
"logging": false,
"entities": [
"dist/entity/**/*.js"
],
"migrations": [
"dist/migration/**/*.js"
],
"subscribers": [
"dist/subscriber/**/*.js"
],
"cli": {
"entitiesDir": "dist/entity",
"migrationsDir": "dist/migration",
"subscribersDir": "dist/subscriber"
}
}

View file

@ -1,24 +0,0 @@
{
"type": "mysql",
"host": "localhost",
"port": 3121,
"username": "prod",
"password": "prod",
"database": "vylbot",
"synchronize": false,
"logging": false,
"entities": [
"dist/entity/**/*.js"
],
"migrations": [
"dist/migration/**/*.js"
],
"subscribers": [
"dist/subscriber/**/*.js"
],
"cli": {
"entitiesDir": "dist/entity",
"migrationsDir": "dist/migration",
"subscribersDir": "dist/subscriber"
}
}

View file

@ -1,24 +0,0 @@
{
"type": "mysql",
"host": "localhost",
"port": 3111,
"username": "stage",
"password": "stage",
"database": "vylbot",
"synchronize": false,
"logging": false,
"entities": [
"dist/entity/**/*.js"
],
"migrations": [
"dist/migration/**/*.js"
],
"subscribers": [
"dist/subscriber/**/*.js"
],
"cli": {
"entitiesDir": "dist/entity",
"migrationsDir": "dist/migration",
"subscribersDir": "dist/subscriber"
}
}

View file

@ -9,8 +9,8 @@
"build": "tsc", "build": "tsc",
"start": "node ./dist/vylbot", "start": "node ./dist/vylbot",
"test": "jest", "test": "jest",
"db:up": "typeorm migration:run", "db:up": "typeorm migration:run -d dist/database/dataSources/appDataSource.js",
"db:down": "typeorm migration:revert" "db:down": "typeorm migration:revert -d dist/database/dataSources/appDataSource.js"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -33,11 +33,11 @@
"emoji-regex": "^10.0.0", "emoji-regex": "^10.0.0",
"jest": "^29.0.0", "jest": "^29.0.0",
"jest-mock-extended": "^3.0.0", "jest-mock-extended": "^3.0.0",
"minimatch": "7.4.6", "minimatch": "9.0.1",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"random-bunny": "^2.0.5", "random-bunny": "^2.0.5",
"ts-jest": "^29.0.0", "ts-jest": "^29.0.0",
"typeorm": "0.3.14" "typeorm": "0.3.16"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.0.0", "@types/node": "^20.0.0",

View file

@ -13,7 +13,6 @@ cd ~/apps/vylbot/vylbot_prod \
&& (pm2 stop vylbot_prod || true) \ && (pm2 stop vylbot_prod || true) \
&& (pm2 delete vylbot_prod || true) \ && (pm2 delete vylbot_prod || true) \
&& cp .prod.env .env \ && cp .prod.env .env \
&& cp ormconfig.prod.json ormconfig.json \
&& yarn clean \ && yarn clean \
&& yarn install --frozen-lockfile \ && yarn install --frozen-lockfile \
&& yarn build \ && yarn build \

View file

@ -13,7 +13,6 @@ cd ~/apps/vylbot/vylbot_stage \
&& (pm2 stop vylbot_stage || true) \ && (pm2 stop vylbot_stage || true) \
&& (pm2 delete vylbot_stage || true) \ && (pm2 delete vylbot_stage || true) \
&& cp .stage.env .env \ && cp .stage.env .env \
&& cp ormconfig.stage.json ormconfig.json \
&& yarn clean \ && yarn clean \
&& yarn install --frozen-lockfile \ && yarn install --frozen-lockfile \
&& yarn build \ && yarn build \

View file

@ -8,6 +8,7 @@ import { Command } from "../type/command";
import { Events } from "./events"; import { Events } from "./events";
import { Util } from "./util"; import { Util } from "./util";
import AppDataSource from "../database/dataSources/appDataSource";
export class CoreClient extends Client { export class CoreClient extends Client {
private static _commandItems: ICommandItem[]; private static _commandItems: ICommandItem[];
@ -41,10 +42,9 @@ export class CoreClient extends Client {
return; return;
} }
await createConnection().catch(e => { await AppDataSource.initialize()
console.error(e); .then(() => console.log("Data Source Initialized"))
return; .catch((err) => console.error("Error Initialising Data Source", err));
});
super.on("interactionCreate", this._events.onInteractionCreate); super.on("interactionCreate", this._events.onInteractionCreate);
super.on("ready", this._events.onReady); super.on("ready", this._events.onReady);

View file

@ -1,6 +1,6 @@
import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import { Command } from "../../../type/command"; import { Command } from "../../../type/command";
import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby";
export default class AddRole extends Command { export default class AddRole extends Command {
constructor() { constructor() {

View file

@ -1,6 +1,6 @@
import { CacheType, CommandInteraction, EmbedBuilder, GuildBasedChannel, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { CacheType, CommandInteraction, EmbedBuilder, GuildBasedChannel, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import { Command } from "../../../type/command"; import { Command } from "../../../type/command";
import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby";
import EmbedColours from "../../../constants/EmbedColours"; import EmbedColours from "../../../constants/EmbedColours";
export default class ListLobby extends Command { export default class ListLobby extends Command {

View file

@ -1,6 +1,6 @@
import { CommandInteraction, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, SlashCommandBuilder } from "discord.js";
import { Command } from "../../../type/command"; import { Command } from "../../../type/command";
import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby";
export default class Lobby extends Command { export default class Lobby extends Command {
constructor() { constructor() {

View file

@ -1,6 +1,6 @@
import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import { Command } from "../../../type/command"; import { Command } from "../../../type/command";
import { default as eLobby } from "../../../entity/501231711271780357/Lobby"; import { default as eLobby } from "../../../database/entities/501231711271780357/Lobby";
import BaseEntity from "../../../contracts/BaseEntity"; import BaseEntity from "../../../contracts/BaseEntity";
export default class RemoveLobby extends Command { export default class RemoveLobby extends Command {

View file

@ -1,7 +1,7 @@
import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import { Command } from "../../type/command"; import { Command } from "../../type/command";
import { default as eRole } from "../../entity/Role"; import { default as eRole } from "../../database/entities/Role";
import Server from "../../entity/Server"; import Server from "../../database/entities/Server";
export default class ConfigRole extends Command { export default class ConfigRole extends Command {
constructor() { constructor() {

View file

@ -1,6 +1,6 @@
import { CommandInteraction, EmbedBuilder, GuildMemberRoleManager, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, EmbedBuilder, GuildMemberRoleManager, SlashCommandBuilder } from "discord.js";
import { Command } from "../../type/command"; import { Command } from "../../type/command";
import { default as eRole } from "../../entity/Role"; import { default as eRole } from "../../database/entities/Role";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
export default class Role extends Command { export default class Role extends Command {

View file

@ -1,4 +1,4 @@
import Audit from "../entity/Audit"; import Audit from "../database/entities/Audit";
import AuditTools from "../helpers/AuditTools"; import AuditTools from "../helpers/AuditTools";
import { Command } from "../type/command"; import { Command } from "../type/command";
import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuilder } from "discord.js";

View file

@ -1,5 +1,5 @@
import { Command } from "../type/command"; import { Command } from "../type/command";
import Audit from "../entity/Audit"; import Audit from "../database/entities/Audit";
import { AuditType } from "../constants/AuditType"; import { AuditType } from "../constants/AuditType";
import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js";
import EmbedColours from "../constants/EmbedColours"; import EmbedColours from "../constants/EmbedColours";

View file

@ -2,8 +2,8 @@ import { CommandInteraction, EmbedBuilder, PermissionsBitField, SlashCommandBuil
import { readFileSync } from "fs"; import { readFileSync } from "fs";
import DefaultValues from "../constants/DefaultValues"; import DefaultValues from "../constants/DefaultValues";
import EmbedColours from "../constants/EmbedColours"; import EmbedColours from "../constants/EmbedColours";
import Server from "../entity/Server"; import Server from "../database/entities/Server";
import Setting from "../entity/Setting"; import Setting from "../database/entities/Setting";
import { Command } from "../type/command"; import { Command } from "../type/command";
export default class Config extends Command { export default class Config extends Command {

View file

@ -1,5 +1,5 @@
import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import IgnoredChannel from "../entity/IgnoredChannel"; import IgnoredChannel from "../database/entities/IgnoredChannel";
import { Command } from "../type/command"; import { Command } from "../type/command";
export default class Ignore extends Command { export default class Ignore extends Command {

View file

@ -1,5 +1,5 @@
import { Command } from "../type/command"; import { Command } from "../type/command";
import Audit from "../entity/Audit"; import Audit from "../database/entities/Audit";
import { AuditType } from "../constants/AuditType"; import { AuditType } from "../constants/AuditType";
import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js";
import EmbedColours from "../constants/EmbedColours"; import EmbedColours from "../constants/EmbedColours";

View file

@ -1,7 +1,7 @@
import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js";
import { AuditType } from "../constants/AuditType"; import { AuditType } from "../constants/AuditType";
import EmbedColours from "../constants/EmbedColours"; import EmbedColours from "../constants/EmbedColours";
import Audit from "../entity/Audit"; import Audit from "../database/entities/Audit";
import SettingsHelper from "../helpers/SettingsHelper"; import SettingsHelper from "../helpers/SettingsHelper";
import { Command } from "../type/command"; import { Command } from "../type/command";

View file

@ -1,5 +1,5 @@
import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js"; import { CommandInteraction, PermissionsBitField, SlashCommandBuilder } from "discord.js";
import Server from "../entity/Server"; import Server from "../database/entities/Server";
import { Command } from "../type/command"; import { Command } from "../type/command";
export default class Setup extends Command { export default class Setup extends Command {

View file

@ -1,7 +1,7 @@
import { CacheType, CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { CacheType, CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js";
import { AuditType } from "../constants/AuditType"; import { AuditType } from "../constants/AuditType";
import EmbedColours from "../constants/EmbedColours"; import EmbedColours from "../constants/EmbedColours";
import Audit from "../entity/Audit"; import Audit from "../database/entities/Audit";
import SettingsHelper from "../helpers/SettingsHelper"; import SettingsHelper from "../helpers/SettingsHelper";
import TimeLengthInput from "../helpers/TimeLengthInput"; import TimeLengthInput from "../helpers/TimeLengthInput";
import { Command } from "../type/command"; import { Command } from "../type/command";

View file

@ -1,7 +1,7 @@
import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js"; import { CommandInteraction, EmbedBuilder, GuildMember, PermissionsBitField, SlashCommandBuilder, TextChannel } from "discord.js";
import { AuditType } from "../constants/AuditType"; import { AuditType } from "../constants/AuditType";
import EmbedColours from "../constants/EmbedColours"; import EmbedColours from "../constants/EmbedColours";
import Audit from "../entity/Audit"; import Audit from "../database/entities/Audit";
import SettingsHelper from "../helpers/SettingsHelper"; import SettingsHelper from "../helpers/SettingsHelper";
import { Command } from "../type/command"; import { Command } from "../type/command";

View file

@ -1,5 +1,6 @@
import { Column, DeepPartial, EntityTarget, getConnection, PrimaryColumn, ObjectLiteral, FindOptionsWhere } from "typeorm"; import { Column, DeepPartial, EntityTarget, PrimaryColumn, ObjectLiteral, FindOptionsWhere } from "typeorm";
import { v4 } from "uuid"; import { v4 } from "uuid";
import AppDataSource from "../database/dataSources/appDataSource";
export default class BaseEntity { export default class BaseEntity {
constructor() { constructor() {
@ -21,25 +22,19 @@ export default class BaseEntity {
public async Save<T extends BaseEntity>(target: EntityTarget<T>, entity: DeepPartial<T>): Promise<void> { public async Save<T extends BaseEntity>(target: EntityTarget<T>, entity: DeepPartial<T>): Promise<void> {
this.WhenUpdated = new Date(); this.WhenUpdated = new Date();
const connection = getConnection(); const repository = AppDataSource.getRepository<T>(target);
const repository = connection.getRepository<T>(target);
await repository.save(entity); await repository.save(entity);
} }
public static async Remove<T extends BaseEntity>(target: EntityTarget<T>, entity: T): Promise<void> { public static async Remove<T extends BaseEntity>(target: EntityTarget<T>, entity: T): Promise<void> {
const connection = getConnection(); const repository = AppDataSource.getRepository<T>(target);
const repository = connection.getRepository<T>(target);
await repository.remove(entity); await repository.remove(entity);
} }
public static async FetchAll<T extends BaseEntity>(target: EntityTarget<T>, relations?: string[]): Promise<T[]> { public static async FetchAll<T extends BaseEntity>(target: EntityTarget<T>, relations?: string[]): Promise<T[]> {
const connection = getConnection(); const repository = AppDataSource.getRepository<T>(target);
const repository = connection.getRepository<T>(target);
const all = await repository.find({ relations: relations || [] }); const all = await repository.find({ relations: relations || [] });
@ -47,9 +42,7 @@ export default class BaseEntity {
} }
public static async FetchOneById<T extends BaseEntity>(target: EntityTarget<T>, id: string, relations?: string[]): Promise<T | null> { public static async FetchOneById<T extends BaseEntity>(target: EntityTarget<T>, id: string, relations?: string[]): Promise<T | null> {
const connection = getConnection(); const repository = AppDataSource.getRepository<T>(target);
const repository = connection.getRepository<T>(target);
const single = await repository.findOne({ where: ({ Id: id } as FindOptionsWhere<T>), relations: relations || {} }); const single = await repository.findOne({ where: ({ Id: id } as FindOptionsWhere<T>), relations: relations || {} });
@ -57,9 +50,7 @@ export default class BaseEntity {
} }
public static async Any<T extends ObjectLiteral>(target: EntityTarget<T>): Promise<boolean> { public static async Any<T extends ObjectLiteral>(target: EntityTarget<T>): Promise<boolean> {
const connection = getConnection(); const repository = AppDataSource.getRepository<T>(target);
const repository = connection.getRepository<T>(target);
const any = await repository.find(); const any = await repository.find();

View file

@ -0,0 +1,26 @@
import { DataSource } from "typeorm";
import * as dotenv from "dotenv";
dotenv.config();
const AppDataSource = new DataSource({
type: "mysql",
host: process.env.DB_HOST,
port: Number(process.env.DB_PORT),
username: process.env.DB_AUTH_USER,
password: process.env.DB_AUTH_PASS,
database: process.env.DB_NAME,
synchronize: process.env.DB_SYNC == "true",
logging: process.env.DB_LOGGING == "true",
entities: [
"dist/database/entities/**/*.js",
],
migrations: [
"dist/database/migrations/**/*.js",
],
subscribers: [
"dist/database/subscribers/**/*.js",
],
});
export default AppDataSource;

View file

@ -1,5 +1,6 @@
import { Column, Entity, getConnection } from "typeorm"; import { Column, Entity } from "typeorm";
import BaseEntity from "../../contracts/BaseEntity"; import BaseEntity from "../../../contracts/BaseEntity";
import AppDataSource from "../../dataSources/appDataSource";
@Entity() @Entity()
export default class Lobby extends BaseEntity { export default class Lobby extends BaseEntity {
@ -34,9 +35,7 @@ export default class Lobby extends BaseEntity {
} }
public static async FetchOneByChannelId(channelId: string, relations?: string[]): Promise<Lobby | null> { public static async FetchOneByChannelId(channelId: string, relations?: string[]): Promise<Lobby | null> {
const connection = getConnection(); const repository = AppDataSource.getRepository(Lobby);
const repository = connection.getRepository(Lobby);
const single = await repository.findOne({ where: { ChannelId: channelId }, relations: relations || [] }); const single = await repository.findOne({ where: { ChannelId: channelId }, relations: relations || [] });

View file

@ -1,7 +1,8 @@
import { Column, Entity, getConnection } from "typeorm"; import { Column, Entity } from "typeorm";
import { AuditType } from "../constants/AuditType"; import { AuditType } from "../../constants/AuditType";
import BaseEntity from "../contracts/BaseEntity"; import BaseEntity from "../../contracts/BaseEntity";
import StringTools from "../helpers/StringTools"; import StringTools from "../../helpers/StringTools";
import AppDataSource from "../dataSources/appDataSource";
@Entity() @Entity()
export default class Audit extends BaseEntity { export default class Audit extends BaseEntity {
@ -35,9 +36,7 @@ export default class Audit extends BaseEntity {
ServerId: string; ServerId: string;
public static async FetchAuditsByUserId(userId: string, serverId: string): Promise<Audit[] | null> { public static async FetchAuditsByUserId(userId: string, serverId: string): Promise<Audit[] | null> {
const connection = getConnection(); const repository = AppDataSource.getRepository(Audit);
const repository = connection.getRepository(Audit);
const all = await repository.find({ where: { UserId: userId, ServerId: serverId } }); const all = await repository.find({ where: { UserId: userId, ServerId: serverId } });
@ -45,9 +44,7 @@ export default class Audit extends BaseEntity {
} }
public static async FetchAuditByAuditId(auditId: string, serverId: string): Promise<Audit | null> { public static async FetchAuditByAuditId(auditId: string, serverId: string): Promise<Audit | null> {
const connection = getConnection(); const repository = AppDataSource.getRepository(Audit);
const repository = connection.getRepository(Audit);
const single = await repository.findOne({ where: { AuditId: auditId, ServerId: serverId } }); const single = await repository.findOne({ where: { AuditId: auditId, ServerId: serverId } });

View file

@ -1,5 +1,6 @@
import { Entity, getConnection } from "typeorm"; import { Entity } from "typeorm";
import BaseEntity from "../contracts/BaseEntity"; import BaseEntity from "../../contracts/BaseEntity";
import AppDataSource from "../dataSources/appDataSource";
@Entity() @Entity()
export default class IgnoredChannel extends BaseEntity { export default class IgnoredChannel extends BaseEntity {
@ -10,9 +11,7 @@ export default class IgnoredChannel extends BaseEntity {
} }
public static async IsChannelIgnored(channelId: string): Promise<boolean> { public static async IsChannelIgnored(channelId: string): Promise<boolean> {
const connection = getConnection(); const repository = AppDataSource.getRepository(IgnoredChannel);
const repository = connection.getRepository(IgnoredChannel);
const single = await repository.findOne({ where: { Id: channelId } }); const single = await repository.findOne({ where: { Id: channelId } });

View file

@ -1,6 +1,7 @@
import { Column, Entity, getConnection, ManyToOne } from "typeorm"; import { Column, Entity, ManyToOne } from "typeorm";
import BaseEntity from "../contracts/BaseEntity" import BaseEntity from "../../contracts/BaseEntity"
import Server from "./Server"; import Server from "./Server";
import AppDataSource from "../dataSources/appDataSource";
@Entity() @Entity()
export default class Role extends BaseEntity { export default class Role extends BaseEntity {
@ -21,9 +22,7 @@ export default class Role extends BaseEntity {
} }
public static async FetchOneByRoleId(roleId: string, relations?: string[]): Promise<Role | null> { public static async FetchOneByRoleId(roleId: string, relations?: string[]): Promise<Role | null> {
const connection = getConnection(); const repository = AppDataSource.getRepository(Role);
const repository = connection.getRepository(Role);
const single = await repository.findOne({ where: { RoleId: roleId }, relations: relations || []}); const single = await repository.findOne({ where: { RoleId: roleId }, relations: relations || []});
@ -31,9 +30,7 @@ export default class Role extends BaseEntity {
} }
public static async FetchAllByServerId(serverId: string): Promise<Role[]> { public static async FetchAllByServerId(serverId: string): Promise<Role[]> {
const connection = getConnection(); const repository = AppDataSource.getRepository(Server);
const repository = connection.getRepository(Server);
const all = await repository.findOne({ where: { Id: serverId }, relations: [ const all = await repository.findOne({ where: { Id: serverId }, relations: [
"Roles", "Roles",

View file

@ -1,5 +1,5 @@
import { Entity, OneToMany } from "typeorm"; import { Entity, OneToMany } from "typeorm";
import BaseEntity from "../contracts/BaseEntity"; import BaseEntity from "../../contracts/BaseEntity";
import Role from "./Role"; import Role from "./Role";
import Setting from "./Setting"; import Setting from "./Setting";

View file

@ -1,6 +1,7 @@
import { Column, Entity, getConnection, ManyToOne } from "typeorm"; import { Column, Entity, ManyToOne } from "typeorm";
import BaseEntity from "../contracts/BaseEntity"; import BaseEntity from "../../contracts/BaseEntity";
import Server from "./Server"; import Server from "./Server";
import AppDataSource from "../dataSources/appDataSource";
@Entity() @Entity()
export default class Setting extends BaseEntity { export default class Setting extends BaseEntity {
@ -26,9 +27,7 @@ export default class Setting extends BaseEntity {
} }
public static async FetchOneByKey(key: string, relations?: string[]): Promise<Setting | null> { public static async FetchOneByKey(key: string, relations?: string[]): Promise<Setting | null> {
const connection = getConnection(); const repository = AppDataSource.getRepository(Setting);
const repository = connection.getRepository(Setting);
const single = await repository.findOne({ where: { Key: key }, relations: relations || {} }); const single = await repository.findOne({ where: { Key: key }, relations: relations || {} });

View file

@ -1,5 +1,5 @@
import { MigrationInterface, QueryRunner } from "typeorm" import { MigrationInterface, QueryRunner } from "typeorm"
import MigrationHelper from "../../helpers/MigrationHelper" import MigrationHelper from "../../../helpers/MigrationHelper"
export class vylbot1662399171315 implements MigrationInterface { export class vylbot1662399171315 implements MigrationInterface {

View file

@ -1,6 +1,6 @@
import { EmbedBuilder, Message, TextChannel } from "discord.js"; import { EmbedBuilder, Message, TextChannel } from "discord.js";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
import IgnoredChannel from "../../entity/IgnoredChannel"; import IgnoredChannel from "../../database/entities/IgnoredChannel";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
export default async function MessageDelete(message: Message) { export default async function MessageDelete(message: Message) {

View file

@ -1,6 +1,6 @@
import { EmbedBuilder, Message, TextChannel } from "discord.js"; import { EmbedBuilder, Message, TextChannel } from "discord.js";
import EmbedColours from "../../constants/EmbedColours"; import EmbedColours from "../../constants/EmbedColours";
import IgnoredChannel from "../../entity/IgnoredChannel"; import IgnoredChannel from "../../database/entities/IgnoredChannel";
import SettingsHelper from "../../helpers/SettingsHelper"; import SettingsHelper from "../../helpers/SettingsHelper";
export default async function MessageUpdate(oldMessage: Message, newMessage: Message) { export default async function MessageUpdate(oldMessage: Message, newMessage: Message) {

View file

@ -1,6 +1,6 @@
import DefaultValues from "../constants/DefaultValues"; import DefaultValues from "../constants/DefaultValues";
import Server from "../entity/Server"; import Server from "../database/entities/Server";
import Setting from "../entity/Setting"; import Setting from "../database/entities/Setting";
export default class SettingsHelper { export default class SettingsHelper {
public static async GetSetting(key: string, serverId: string): Promise<string | undefined> { public static async GetSetting(key: string, serverId: string): Promise<string | undefined> {

View file

@ -11,6 +11,12 @@ const requiredConfigs: string[] = [
"BOT_AUTHOR", "BOT_AUTHOR",
"BOT_OWNERID", "BOT_OWNERID",
"BOT_CLIENTID", "BOT_CLIENTID",
"DB_HOST",
"DB_PORT",
"DB_AUTH_USER",
"DB_AUTH_PASS",
"DB_SYNC",
"DB_LOGGING",
]; ];
requiredConfigs.forEach(config => { requiredConfigs.forEach(config => {

View file

@ -2,7 +2,7 @@ import { APIEmbed, CacheType, CommandInteraction, CommandInteractionOption, DMCh
import { mock } from "jest-mock-extended"; import { mock } from "jest-mock-extended";
import Timeout from "../../src/commands/timeout"; import Timeout from "../../src/commands/timeout";
import SettingsHelper from "../../src/helpers/SettingsHelper"; import SettingsHelper from "../../src/helpers/SettingsHelper";
import Audit from "../../src/entity/Audit"; import Audit from "../../src/database/entities/Audit";
import EmbedColours from "../../src/constants/EmbedColours"; import EmbedColours from "../../src/constants/EmbedColours";
import { DeepPartial, EntityTarget } from "typeorm"; import { DeepPartial, EntityTarget } from "typeorm";
import BaseEntity from "../../src/contracts/BaseEntity"; import BaseEntity from "../../src/contracts/BaseEntity";

View file

@ -265,6 +265,13 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.20.2" "@babel/helper-plugin-utils" "^7.20.2"
"@babel/runtime@^7.21.0":
version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
dependencies:
regenerator-runtime "^0.13.11"
"@babel/template@^7.20.7", "@babel/template@^7.3.3": "@babel/template@^7.20.7", "@babel/template@^7.3.3":
version "7.20.7" version "7.20.7"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
@ -1166,6 +1173,13 @@ cross-spawn@^7.0.3:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
date-fns@^2.29.3:
version "2.30.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
dependencies:
"@babel/runtime" "^7.21.0"
debug@^4.1.0, debug@^4.1.1, debug@^4.3.4: debug@^4.1.0, debug@^4.1.1, debug@^4.3.4:
version "4.3.4" version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
@ -2154,10 +2168,10 @@ mimic-response@^3.1.0:
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==
minimatch@7.4.6: minimatch@9.0.1:
version "7.4.6" version "9.0.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253"
integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==
dependencies: dependencies:
brace-expansion "^2.0.1" brace-expansion "^2.0.1"
@ -2448,6 +2462,11 @@ reflect-metadata@^0.1.13:
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
require-directory@^2.1.1: require-directory@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@ -2764,16 +2783,17 @@ type-fest@^0.21.3:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
typeorm@0.3.14: typeorm@0.3.16:
version "0.3.14" version "0.3.16"
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.14.tgz#d46bc685aa92d0caf910849f22753ef319822327" resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.16.tgz#a001d77b36cfaaf9ff495e15805dd17883116b7b"
integrity sha512-tEPEN8qmA2a2wmjkaDcWBZ6LsECHofJW2vaCQMklYs+4JRJMAJ5FfbPIWMbhJ3ANJGMtLAmU1GfC8rLFIpbWsg== integrity sha512-wJ4Qy1oqRKNDdZiBTTaVMqwo/XxC52Q7uNPTjltPgLhvIW173bL6Iad0lhptMOsFlpixFPaUu3PNziaRBwX2Zw==
dependencies: dependencies:
"@sqltools/formatter" "^1.2.5" "@sqltools/formatter" "^1.2.5"
app-root-path "^3.1.0" app-root-path "^3.1.0"
buffer "^6.0.3" buffer "^6.0.3"
chalk "^4.1.2" chalk "^4.1.2"
cli-highlight "^2.1.11" cli-highlight "^2.1.11"
date-fns "^2.29.3"
debug "^4.3.4" debug "^4.3.4"
dotenv "^16.0.3" dotenv "^16.0.3"
glob "^8.1.0" glob "^8.1.0"