meocord 1.8.4 → 2.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -1
- package/dist/cjs/testing/index.cjs +39 -4
- package/dist/esm/package.json.js +1 -1
- package/dist/esm/testing/meocord-testing-module.js +7 -1
- package/dist/esm/testing/mock-interaction.js +32 -3
- package/dist/types/decorator/index.d.ts +1 -1
- package/dist/types/interface/index.d.ts +1 -1
- package/dist/types/testing/index.d.ts +38 -6
- package/package.json +20 -17
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
|
|
42
42
|
### Prerequisites
|
|
43
43
|
|
|
44
|
-
- **Runtime**: Node.js
|
|
44
|
+
- **Runtime**: Node.js 22 or newer, or Bun 1.x+
|
|
45
45
|
- **TypeScript**: 5.0+
|
|
46
46
|
- **Package manager**: npm, yarn, pnpm, or bun
|
|
47
47
|
|
|
@@ -410,6 +410,33 @@ interaction.guildId = 'guild-123'
|
|
|
410
410
|
|
|
411
411
|
Works for any discord.js class — interactions, `Message`, `MessageReaction`, and anything else. No per-type maintenance.
|
|
412
412
|
|
|
413
|
+
**Assignable to the real class** — the returned mock can be passed straight to code that expects the discord.js type. No `as unknown as ButtonInteraction` at the call site.
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
const interaction = createMockInteraction(ButtonInteraction)
|
|
417
|
+
|
|
418
|
+
await controller.handleButton(interaction) // takes a real ButtonInteraction
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Property overrides at construction** — pass a second argument to set properties as the mock is built. This is required for anything discord.js declares `readonly` (`ModalSubmitInteraction#customId` and `#fields`, `MessageComponentInteraction#message`, `client`, `guildId` on some classes), since those cannot be assigned afterwards. It is also how you set a property backed by a getter-only prototype accessor, such as `targetUser` or `targetMessage` on a context menu.
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
import { createMockInteraction, createMockUser } from 'meocord/testing'
|
|
425
|
+
import { ModalSubmitInteraction, UserContextMenuCommandInteraction } from 'discord.js'
|
|
426
|
+
|
|
427
|
+
const modal = createMockInteraction(ModalSubmitInteraction, {
|
|
428
|
+
customId: 'wish-import-800000000',
|
|
429
|
+
fields: { getTextInputValue: () => '{"pulls":[]}' } as unknown as ModalSubmitInteraction['fields'],
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
const contextMenu = createMockInteraction(UserContextMenuCommandInteraction, {
|
|
433
|
+
commandName: 'profile',
|
|
434
|
+
targetUser: createMockUser(),
|
|
435
|
+
})
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
The override record is typed as `MockProps<T>`, exported from `meocord/testing`. Every key is optional, and a misspelled property name is a compile error.
|
|
439
|
+
|
|
413
440
|
### `createChatInputOptions`
|
|
414
441
|
|
|
415
442
|
Builds a typed options resolver from a plain record. Type routing mirrors the real `CommandInteractionOptionResolver`: wrong-type access returns `null`, `required=true` throws if the option is absent.
|
|
@@ -502,6 +529,19 @@ const module = MeoCordTestingModule.create({
|
|
|
502
529
|
|
|
503
530
|
`canActivate: () => true` allows the method to run. `() => false` blocks it. Multiple guards chain fluently.
|
|
504
531
|
|
|
532
|
+
### `overrideProvider`
|
|
533
|
+
|
|
534
|
+
Replaces a provider already registered on the module. The value is typed as `Partial<T>`, so a double only has to cover the methods the test exercises — a class with a private member could never be satisfied by a full object literal anyway. A misspelled method name is still a compile error.
|
|
535
|
+
|
|
536
|
+
```typescript
|
|
537
|
+
const module = MeoCordTestingModule.create({
|
|
538
|
+
controllers: [GreetingSlashController],
|
|
539
|
+
providers: [{ provide: GreetingService, useValue: realGreetingService }],
|
|
540
|
+
})
|
|
541
|
+
.overrideProvider(GreetingService).useValue({ buildGreeting: createMockFn() })
|
|
542
|
+
.compile()
|
|
543
|
+
```
|
|
544
|
+
|
|
505
545
|
### Full example
|
|
506
546
|
|
|
507
547
|
```typescript
|
|
@@ -22,7 +22,13 @@ function isValueProvider(p) {
|
|
|
22
22
|
* Builder returned by `MeoCordTestingModule.create()`.
|
|
23
23
|
* Call `.compile()` to get the resolved `TestingModule`.
|
|
24
24
|
*/ class TestingModuleBuilder {
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* A double covers the methods under test, not the whole class — and a class
|
|
27
|
+
* with any private member (a service holding a logger, say) can never be
|
|
28
|
+
* satisfied by an object literal at all. `Partial<T>` still rejects a
|
|
29
|
+
* misspelled method name, which is the check that actually earns its keep.
|
|
30
|
+
* Matches `overrideGuard`, which has always taken `Partial<GuardInterface>`.
|
|
31
|
+
*/ overrideProvider(token) {
|
|
26
32
|
return {
|
|
27
33
|
useValue: (value)=>{
|
|
28
34
|
this.overrides.set(token, {
|
|
@@ -355,8 +361,17 @@ function stubDeep(instance, externalStubs) {
|
|
|
355
361
|
stubs.set(key, stub);
|
|
356
362
|
return stub;
|
|
357
363
|
},
|
|
364
|
+
// defineProperty rather than assignment: many discord.js properties are
|
|
365
|
+
// prototype getters with no setter (targetUser, targetMessage, createdAt),
|
|
366
|
+
// and a plain write against one of those is a silent no-op. Defining an own
|
|
367
|
+
// data property shadows the accessor, which is what test setup means.
|
|
358
368
|
set (target, prop, value) {
|
|
359
|
-
|
|
369
|
+
Object.defineProperty(target, prop, {
|
|
370
|
+
value,
|
|
371
|
+
writable: true,
|
|
372
|
+
enumerable: true,
|
|
373
|
+
configurable: true
|
|
374
|
+
});
|
|
360
375
|
return true;
|
|
361
376
|
}
|
|
362
377
|
});
|
|
@@ -481,7 +496,7 @@ function findPrototypeMethod(instance, name) {
|
|
|
481
496
|
* interaction.replied // → true
|
|
482
497
|
* await interaction.reply({}) // throws — already replied
|
|
483
498
|
* ```
|
|
484
|
-
*/ function createMockInteraction(Class) {
|
|
499
|
+
*/ function createMockInteraction(Class, props) {
|
|
485
500
|
const instance = Object.create(Class.prototype);
|
|
486
501
|
const stubs = new Map();
|
|
487
502
|
// Set type fields so all prototype type-guard methods compute the right value
|
|
@@ -551,6 +566,19 @@ function findPrototypeMethod(instance, name) {
|
|
|
551
566
|
}));
|
|
552
567
|
}
|
|
553
568
|
}
|
|
569
|
+
// Applied last so an explicit prop wins over the type fields and the reply
|
|
570
|
+
// state machine. defineProperty rather than assignment for the same reason the
|
|
571
|
+
// Proxy uses it: several of these shadow a getter-only prototype accessor.
|
|
572
|
+
if (props !== undefined) {
|
|
573
|
+
for (const [key, value] of Object.entries(props)){
|
|
574
|
+
Object.defineProperty(instance, key, {
|
|
575
|
+
value,
|
|
576
|
+
writable: true,
|
|
577
|
+
enumerable: true,
|
|
578
|
+
configurable: true
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
}
|
|
554
582
|
return stubDeep(instance, stubs);
|
|
555
583
|
}
|
|
556
584
|
// ---------------------------------------------------------------------------
|
|
@@ -719,7 +747,14 @@ function createMockMessage() {
|
|
|
719
747
|
* interaction.options.getSubcommand() // → 'notes'
|
|
720
748
|
* interaction.options.getNumber('uid') // → 12345678
|
|
721
749
|
* ```
|
|
722
|
-
*/
|
|
750
|
+
*/ // `any` is the default rather than `CacheType` because TypeScript types a generic
|
|
751
|
+
// class's `prototype` with `any` for its parameters, and createMockInteraction infers
|
|
752
|
+
// T from exactly that — `createMockInteraction(ChatInputCommandInteraction)` produces
|
|
753
|
+
// an interaction whose `options` is `CommandInteractionOptionResolver<any>`. Defaulting
|
|
754
|
+
// to `CacheType` instead makes CacheTypeReducer widen getChannel's return with a `null`
|
|
755
|
+
// the target rejects, and the resolver stops being assignable to the property it exists
|
|
756
|
+
// to fill. Pass Cached explicitly when the interaction under test is pinned.
|
|
757
|
+
function createChatInputOptions(opts = {}) {
|
|
723
758
|
const { subcommandGroup = null, subcommand = null, ...values } = opts;
|
|
724
759
|
function resolveOrThrow(name, value, required) {
|
|
725
760
|
if (value === null) {
|
package/dist/esm/package.json.js
CHANGED
|
@@ -19,7 +19,13 @@ function isValueProvider(p) {
|
|
|
19
19
|
* Builder returned by `MeoCordTestingModule.create()`.
|
|
20
20
|
* Call `.compile()` to get the resolved `TestingModule`.
|
|
21
21
|
*/ class TestingModuleBuilder {
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* A double covers the methods under test, not the whole class — and a class
|
|
24
|
+
* with any private member (a service holding a logger, say) can never be
|
|
25
|
+
* satisfied by an object literal at all. `Partial<T>` still rejects a
|
|
26
|
+
* misspelled method name, which is the check that actually earns its keep.
|
|
27
|
+
* Matches `overrideGuard`, which has always taken `Partial<GuardInterface>`.
|
|
28
|
+
*/ overrideProvider(token) {
|
|
23
29
|
return {
|
|
24
30
|
useValue: (value)=>{
|
|
25
31
|
this.overrides.set(token, {
|
|
@@ -48,8 +48,17 @@ function stubDeep(instance, externalStubs) {
|
|
|
48
48
|
stubs.set(key, stub);
|
|
49
49
|
return stub;
|
|
50
50
|
},
|
|
51
|
+
// defineProperty rather than assignment: many discord.js properties are
|
|
52
|
+
// prototype getters with no setter (targetUser, targetMessage, createdAt),
|
|
53
|
+
// and a plain write against one of those is a silent no-op. Defining an own
|
|
54
|
+
// data property shadows the accessor, which is what test setup means.
|
|
51
55
|
set (target, prop, value) {
|
|
52
|
-
|
|
56
|
+
Object.defineProperty(target, prop, {
|
|
57
|
+
value,
|
|
58
|
+
writable: true,
|
|
59
|
+
enumerable: true,
|
|
60
|
+
configurable: true
|
|
61
|
+
});
|
|
53
62
|
return true;
|
|
54
63
|
}
|
|
55
64
|
});
|
|
@@ -174,7 +183,7 @@ function findPrototypeMethod(instance, name) {
|
|
|
174
183
|
* interaction.replied // → true
|
|
175
184
|
* await interaction.reply({}) // throws — already replied
|
|
176
185
|
* ```
|
|
177
|
-
*/ function createMockInteraction(Class) {
|
|
186
|
+
*/ function createMockInteraction(Class, props) {
|
|
178
187
|
const instance = Object.create(Class.prototype);
|
|
179
188
|
const stubs = new Map();
|
|
180
189
|
// Set type fields so all prototype type-guard methods compute the right value
|
|
@@ -244,6 +253,19 @@ function findPrototypeMethod(instance, name) {
|
|
|
244
253
|
}));
|
|
245
254
|
}
|
|
246
255
|
}
|
|
256
|
+
// Applied last so an explicit prop wins over the type fields and the reply
|
|
257
|
+
// state machine. defineProperty rather than assignment for the same reason the
|
|
258
|
+
// Proxy uses it: several of these shadow a getter-only prototype accessor.
|
|
259
|
+
if (props !== undefined) {
|
|
260
|
+
for (const [key, value] of Object.entries(props)){
|
|
261
|
+
Object.defineProperty(instance, key, {
|
|
262
|
+
value,
|
|
263
|
+
writable: true,
|
|
264
|
+
enumerable: true,
|
|
265
|
+
configurable: true
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
247
269
|
return stubDeep(instance, stubs);
|
|
248
270
|
}
|
|
249
271
|
// ---------------------------------------------------------------------------
|
|
@@ -412,7 +434,14 @@ function createMockMessage() {
|
|
|
412
434
|
* interaction.options.getSubcommand() // → 'notes'
|
|
413
435
|
* interaction.options.getNumber('uid') // → 12345678
|
|
414
436
|
* ```
|
|
415
|
-
*/
|
|
437
|
+
*/ // `any` is the default rather than `CacheType` because TypeScript types a generic
|
|
438
|
+
// class's `prototype` with `any` for its parameters, and createMockInteraction infers
|
|
439
|
+
// T from exactly that — `createMockInteraction(ChatInputCommandInteraction)` produces
|
|
440
|
+
// an interaction whose `options` is `CommandInteractionOptionResolver<any>`. Defaulting
|
|
441
|
+
// to `CacheType` instead makes CacheTypeReducer widen getChannel's return with a `null`
|
|
442
|
+
// the target rejects, and the resolver stops being assignable to the property it exists
|
|
443
|
+
// to fill. Pass Cached explicitly when the interaction under test is pinned.
|
|
444
|
+
function createChatInputOptions(opts = {}) {
|
|
416
445
|
const { subcommandGroup = null, subcommand = null, ...values } = opts;
|
|
417
446
|
function resolveOrThrow(name, value, required) {
|
|
418
447
|
if (value === null) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CommandType } from '../enum/index.js';
|
|
2
2
|
import { SlashCommandBuilder, SlashCommandSubcommandsOnlyBuilder, ContextMenuCommandBuilder, ButtonInteraction, StringSelectMenuInteraction, ChatInputCommandInteraction, UserContextMenuCommandInteraction, MessageContextMenuCommandInteraction, ModalSubmitInteraction, OmitPartialGroupDMChannel, Message, MessageReaction, PartialMessageReaction, ClientOptions, ActivityOptions } from 'discord.js';
|
|
3
3
|
import { ReactionHandlerOptions, GuardInterface } from '../interface/index.js';
|
|
4
4
|
import { ServiceIdentifier } from 'inversify';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { User, PartialUser, BaseInteraction, Message, MessageReaction } from 'discord.js';
|
|
2
2
|
import { Configuration } from 'webpack';
|
|
3
|
-
import {
|
|
3
|
+
import { ReactionHandlerAction } from '../enum/index.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* MeoCord Framework
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ServiceIdentifier, Container } from 'inversify';
|
|
2
2
|
import { GuardInterface } from '../interface/index.js';
|
|
3
|
-
import { CommandInteractionOptionResolver, Channel, Client, Guild, Message, User } from 'discord.js';
|
|
3
|
+
import { CacheType, CommandInteractionOptionResolver, Channel, Client, Guild, Message, User } from 'discord.js';
|
|
4
4
|
import 'webpack';
|
|
5
5
|
import '../controller.enum-QA-IuReF.js';
|
|
6
6
|
|
|
@@ -40,8 +40,15 @@ declare class TestingModuleBuilder {
|
|
|
40
40
|
private readonly overrides;
|
|
41
41
|
private readonly guardOverrides;
|
|
42
42
|
constructor(options: TestingModuleOptions);
|
|
43
|
+
/**
|
|
44
|
+
* A double covers the methods under test, not the whole class — and a class
|
|
45
|
+
* with any private member (a service holding a logger, say) can never be
|
|
46
|
+
* satisfied by an object literal at all. `Partial<T>` still rejects a
|
|
47
|
+
* misspelled method name, which is the check that actually earns its keep.
|
|
48
|
+
* Matches `overrideGuard`, which has always taken `Partial<GuardInterface>`.
|
|
49
|
+
*/
|
|
43
50
|
overrideProvider<T>(token: ServiceIdentifier<T>): {
|
|
44
|
-
useValue: (value: T) => TestingModuleBuilder;
|
|
51
|
+
useValue: (value: Partial<T>) => TestingModuleBuilder;
|
|
45
52
|
};
|
|
46
53
|
overrideGuard(guard: new (...args: any[]) => GuardInterface): {
|
|
47
54
|
useValue: (stub: Partial<GuardInterface>) => TestingModuleBuilder;
|
|
@@ -143,10 +150,35 @@ declare function createMockFn<T extends (...args: any[]) => any = (...args: any[
|
|
|
143
150
|
* Recursively transforms all methods of T into MockedFunction and all
|
|
144
151
|
* nested objects into DeepMocked. Depth cap at 5 prevents infinite recursion
|
|
145
152
|
* on circular discord.js types (e.g. Guild ↔ GuildMember).
|
|
146
|
-
*
|
|
153
|
+
*
|
|
154
|
+
* Intersected with `T` so the mock is accepted wherever the real class is
|
|
155
|
+
* expected. A mapped type alone can never be: it iterates `keyof T`, and the
|
|
156
|
+
* private members classes use as brands — discord.js stamps
|
|
157
|
+
* `private readonly _cacheType` on `BaseInteraction` — are not in `keyof T`.
|
|
158
|
+
* Without the intersection every call site has to launder the mock through
|
|
159
|
+
* `as unknown as T`, which defeats the point of typing it at all.
|
|
160
|
+
*
|
|
161
|
+
* The intersection is honest rather than a convenient lie: the object really is
|
|
162
|
+
* `Object.create(Class.prototype)`, so its prototype chain is the real one, and
|
|
163
|
+
* TypeScript `private` is erased at runtime.
|
|
164
|
+
*
|
|
165
|
+
* `readonly` survives from the `T` side, so properties the class declares
|
|
166
|
+
* readonly cannot be assigned after construction. Pass those to the factory as
|
|
167
|
+
* {@link MockProps} instead.
|
|
147
168
|
*/
|
|
148
169
|
type DeepMocked<T, Depth extends number[] = []> = Depth['length'] extends 5 ? T : {
|
|
149
170
|
-readonly [K in keyof T]: T[K] extends (...args: infer A) => infer R ? MockedFunction<(...args: A) => R> : T[K] extends object ? DeepMocked<T[K], [...Depth, 0]> : T[K];
|
|
171
|
+
} & T;
|
|
172
|
+
/**
|
|
173
|
+
* Property overrides accepted at construction by the mock factories.
|
|
174
|
+
*
|
|
175
|
+
* Setup belongs here rather than in a post-construction assignment: the returned
|
|
176
|
+
* mock is assignable to the real discord.js class, so anything that class declares
|
|
177
|
+
* `readonly` — `ModalSubmitInteraction#customId`, `#fields`, `MessageComponentInteraction#message`
|
|
178
|
+
* — cannot be written afterwards without a cast.
|
|
179
|
+
*/
|
|
180
|
+
type MockProps<T> = {
|
|
181
|
+
-readonly [K in keyof T]?: T[K] extends (...args: any[]) => any ? (...args: any[]) => any : T[K];
|
|
150
182
|
};
|
|
151
183
|
interface InteractionClass<T> {
|
|
152
184
|
prototype: T;
|
|
@@ -179,7 +211,7 @@ interface InteractionClass<T> {
|
|
|
179
211
|
* await interaction.reply({}) // throws — already replied
|
|
180
212
|
* ```
|
|
181
213
|
*/
|
|
182
|
-
declare function createMockInteraction<T extends object>(Class: InteractionClass<T>): DeepMocked<T>;
|
|
214
|
+
declare function createMockInteraction<T extends object>(Class: InteractionClass<T>, props?: MockProps<T>): DeepMocked<T>;
|
|
183
215
|
/** Creates a mock {@link User}. All methods are auto-stubbed as a mock fn. */
|
|
184
216
|
declare const createMockUser: () => DeepMocked<User>;
|
|
185
217
|
/**
|
|
@@ -240,7 +272,7 @@ interface ChatInputOptions {
|
|
|
240
272
|
* interaction.options.getNumber('uid') // → 12345678
|
|
241
273
|
* ```
|
|
242
274
|
*/
|
|
243
|
-
declare function createChatInputOptions(opts?: ChatInputOptions): DeepMocked<CommandInteractionOptionResolver
|
|
275
|
+
declare function createChatInputOptions<Cached extends CacheType = any>(opts?: ChatInputOptions): DeepMocked<CommandInteractionOptionResolver<Cached>>;
|
|
244
276
|
|
|
245
277
|
export { MeoCordTestingModule, TestingModule, TestingModuleBuilder, createChatInputOptions, createMockChannel, createMockClient, createMockFn, createMockGuild, createMockInteraction, createMockMessage, createMockUser, isMockFunction };
|
|
246
|
-
export type { ChatInputOptions, ClassProvider, DeepMocked, Mock, MockInstance, MockResult, MockState, MockedFunction, Provider, TestingModuleOptions, ValueProvider };
|
|
278
|
+
export type { ChatInputOptions, ClassProvider, DeepMocked, Mock, MockInstance, MockProps, MockResult, MockState, MockedFunction, Provider, TestingModuleOptions, ValueProvider };
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "meocord",
|
|
3
3
|
"description": "Decorator-based Discord bot framework built on discord.js. Brings NestJS-style controllers, dependency injection, guards, and testing utilities to bot development — with a full CLI and TypeScript-first design.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0-beta.2",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
10
|
"lint": "eslint --fix . && tsc --noEmit && tsc --noEmit --project tsconfig.test.json",
|
|
8
11
|
"build": "rm -rf ./dist && rollup -c",
|
|
@@ -72,13 +75,13 @@
|
|
|
72
75
|
],
|
|
73
76
|
"dependencies": {
|
|
74
77
|
"@clack/prompts": "^1.7.0",
|
|
75
|
-
"@swc/core": "1.15.
|
|
76
|
-
"chalk": "^
|
|
78
|
+
"@swc/core": "1.15.47",
|
|
79
|
+
"chalk": "^6.0.0",
|
|
77
80
|
"cli-table3": "^0.6.5",
|
|
78
81
|
"commander": "^15.0.0",
|
|
79
82
|
"dayjs": "^1.11.21",
|
|
80
83
|
"dotenv": "^17.4.2",
|
|
81
|
-
"inversify": "^8.
|
|
84
|
+
"inversify": "^8.2.3",
|
|
82
85
|
"jiti": "^2.7.0",
|
|
83
86
|
"lodash-es": "^4.18.1",
|
|
84
87
|
"nodemon": "^3.1.14",
|
|
@@ -87,7 +90,7 @@
|
|
|
87
90
|
"swc-loader": "^0.2.7",
|
|
88
91
|
"terser-webpack-plugin": "^5.6.1",
|
|
89
92
|
"tsconfig-paths-webpack-plugin": "^4.2.0",
|
|
90
|
-
"webpack": "^5.
|
|
93
|
+
"webpack": "^5.109.2",
|
|
91
94
|
"webpack-node-externals": "^3.0.0"
|
|
92
95
|
},
|
|
93
96
|
"devDependencies": {
|
|
@@ -102,27 +105,27 @@
|
|
|
102
105
|
"@semantic-release/release-notes-generator": "^14.1.1",
|
|
103
106
|
"@types/lodash-es": "^4.17.12",
|
|
104
107
|
"@types/webpack-node-externals": "^3.0.4",
|
|
105
|
-
"@typescript-eslint/parser": "^8.
|
|
106
|
-
"discord.js": "^14.
|
|
107
|
-
"eslint": "^10.
|
|
108
|
+
"@typescript-eslint/parser": "^8.67.0",
|
|
109
|
+
"discord.js": "^14.27.0",
|
|
110
|
+
"eslint": "^10.8.1",
|
|
108
111
|
"eslint-config-prettier": "^10.1.8",
|
|
109
112
|
"eslint-plugin-headers": "^1.3.4",
|
|
110
113
|
"eslint-plugin-import-x": "^4.17.1",
|
|
111
114
|
"eslint-plugin-prettier": "^5.5.6",
|
|
112
115
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
113
|
-
"globals": "^17.
|
|
116
|
+
"globals": "^17.11.0",
|
|
114
117
|
"husky": "^9.1.7",
|
|
115
|
-
"prettier": "^3.9.
|
|
116
|
-
"rollup": "^4.62.
|
|
118
|
+
"prettier": "^3.9.6",
|
|
119
|
+
"rollup": "^4.62.4",
|
|
117
120
|
"rollup-plugin-copy": "^3.5.0",
|
|
118
|
-
"rollup-plugin-dts": "^6.
|
|
119
|
-
"semantic-release": "^25.0.
|
|
121
|
+
"rollup-plugin-dts": "^6.5.1",
|
|
122
|
+
"semantic-release": "^25.0.9",
|
|
120
123
|
"ts-node": "^10.9.2",
|
|
121
124
|
"typescript": "^6.0.3",
|
|
122
|
-
"typescript-eslint": "^8.
|
|
123
|
-
"@vitest/coverage-istanbul": "^
|
|
124
|
-
"unplugin-swc": "^1.5.
|
|
125
|
-
"vitest": "^
|
|
125
|
+
"typescript-eslint": "^8.67.0",
|
|
126
|
+
"@vitest/coverage-istanbul": "^4.1.10",
|
|
127
|
+
"unplugin-swc": "^1.5.11",
|
|
128
|
+
"vitest": "^4.1.10"
|
|
126
129
|
},
|
|
127
130
|
"peerDependencies": {
|
|
128
131
|
"discord.js": "^14.26.4",
|