meocord 4.2.1 → 4.2.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/cjs/_shared/{controller.decorator-XKMlcUZz.cjs → controller.decorator-U2NBWcoU.cjs} +45 -13
  3. package/dist/cjs/_shared/{providers-BZgJyfZS.cjs → providers-B4MOFBrW.cjs} +58 -15
  4. package/dist/cjs/_shared/{sharded-cooldown-store-CsJJyCZd.cjs → sharded-cooldown-store-HTUb3Ii_.cjs} +1 -1
  5. package/dist/cjs/_shared/{startup-roots-CgfPQrNl.cjs → startup-roots-lA5xkBFq.cjs} +12 -11
  6. package/dist/cjs/_shared/{translate-error-BUAR1WYG.cjs → translate-error-CbBHUu5P.cjs} +1 -1
  7. package/dist/cjs/common/index.cjs +3 -3
  8. package/dist/cjs/core/index.cjs +8 -6
  9. package/dist/cjs/decorator/index.cjs +33 -3
  10. package/dist/cjs/testing/index.cjs +295 -60
  11. package/dist/cli.json +1 -1
  12. package/dist/esm/common/response/response-state.js +5 -5
  13. package/dist/esm/common/translator.js +15 -5
  14. package/dist/esm/core/dispatcher.js +9 -8
  15. package/dist/esm/core/filter-runner.js +2 -2
  16. package/dist/esm/core/handler-pipeline.js +10 -4
  17. package/dist/esm/core/meocord-factory.js +4 -2
  18. package/dist/esm/core/message-help.js +32 -6
  19. package/dist/esm/core/observer-runner.js +2 -1
  20. package/dist/esm/core/providers.js +12 -2
  21. package/dist/esm/core/stage-scope.js +2 -1
  22. package/dist/esm/core/theme-scope.js +4 -1
  23. package/dist/esm/decorator/app.decorator.js +31 -0
  24. package/dist/esm/decorator/filter.decorator.js +2 -2
  25. package/dist/esm/package.json.js +1 -1
  26. package/dist/esm/testing/catalog.js +4 -13
  27. package/dist/esm/testing/discord-defaults.js +21 -1
  28. package/dist/esm/testing/meocord-testing-module.js +24 -16
  29. package/dist/esm/testing/mock-interaction.js +242 -28
  30. package/dist/esm/testing/strict-mocks.js +7 -4
  31. package/dist/esm/util/value.util.js +19 -2
  32. package/dist/types/common/index.d.cts +4 -1
  33. package/dist/types/common/index.d.ts +4 -1
  34. package/dist/types/testing/index.d.cts +28 -14
  35. package/dist/types/testing/index.d.ts +28 -14
  36. package/package.json +1 -1
@@ -684,7 +684,8 @@ declare class MeoCordTestingModule {
684
684
  * @param app - The class `@MeoCord` decorates.
685
685
  * @param options - Providers that replace the app's by token, extra controllers, and observers.
686
686
  * @returns The builder, whose `override*` methods still apply, for `compile()`.
687
- * @throws TypeError when `app` is not a `@MeoCord` class.
687
+ * @throws TypeError when `app` is not a `@MeoCord` class. After {@link reportAllStartupErrors}, an app whose
688
+ * `@MeoCord` was refused throws the error it was refused for instead.
688
689
  *
689
690
  * @example
690
691
  * ```ts
@@ -796,7 +797,8 @@ interface MockState<T extends (...args: any[]) => any = (...args: any[]) => any>
796
797
  * The mock API of a mock function: what it has recorded, and the methods that change what it does.
797
798
  *
798
799
  * Every mock from `meocord/testing` has it, with the names jest and Vitest use, so a test written for either runner
799
- * reads the same.
800
+ * reads the same. The values it takes and records aren't checked against the function it mocks; see
801
+ * {@link MockedFunction}.
800
802
  *
801
803
  * @group Testing
802
804
  * @category Mocks
@@ -838,9 +840,12 @@ interface MockInstance<T extends (...args: any[]) => any = (...args: any[]) => a
838
840
  /**
839
841
  * A mock function with the signature of `T`, and the mock API of {@link MockInstance}.
840
842
  *
841
- * It takes the place of jest's `MockedFunction<T>` and Vitest's `MockedFunction<T>`. The mock factories type each
842
- * method of a mock with it, so `interaction.reply.mockResolvedValue(...)` type-checks. For an overloaded method, such as
843
- * a manager's `fetch`, the mock API takes what any of its overloads takes or returns.
843
+ * It takes the place of jest's `MockedFunction<T>` and Vitest's `MockedFunction<T>`, and the mock factories type each
844
+ * method of a mock with it. Calling the mock is checked against `T`. The values its mock API takes and records are
845
+ * not, for a plain function as for an overloaded one: `mockReturnValue` and `mockResolvedValue` take any value,
846
+ * `mockImplementation` takes any function, and each of `mock.calls`' arguments and each of `mock.results`' values reads
847
+ * as `any`. So a partial fake, such as `guild.members.fetch.mockResolvedValue({ id })`, type-checks, and so does a
848
+ * value of the wrong type.
844
849
  *
845
850
  * @group Testing
846
851
  * @category Mocks
@@ -1103,7 +1108,10 @@ type NotRaw<T> = T extends {
1103
1108
  * collections of what it picks, each empty unless given. Other data Discord always sends reads as Discord sends it,
1104
1109
  * such as `false` for a flag and `null` for what may be absent; what picks the handler, `commandName` or `customId`, is
1105
1110
  * the test's to give. Replies follow Discord's order, so a second `reply()` rejects, and {@link getResponse} reports
1106
- * every answer the interaction got. Every method is a mock function, and one that returns a promise in discord.js
1111
+ * every answer the interaction got. Under `useStrictMocks()` an answer marks the interaction `replied` or `deferred`
1112
+ * once it resolves, as discord.js does after Discord takes it: an edit or follow-up made before then rejects with
1113
+ * `InteractionNotReplied`, and a second answer sent while the first is in flight is refused with Discord's 40060. In
1114
+ * default mode the mark is made at the call, with a warning where a bot would fail. Every method is a mock function, and one that returns a promise in discord.js
1107
1115
  * resolves. What the mock computes for itself, such as `memberPermissions` and `appPermissions`, calls none of them and
1108
1116
  * caches nothing, so a stub a test sets stays for its own code.
1109
1117
  *
@@ -1295,7 +1303,8 @@ interface MockGuildOverrides {
1295
1303
  channels?: readonly GuildBasedChannel[];
1296
1304
  }
1297
1305
  /**
1298
- * Creates a mock {@link Guild}, with the `members`, `channels`, `roles` and `bans` managers ready to stub.
1306
+ * Creates a mock {@link Guild}, with its `members`, `channels`, `roles`, `bans`, `emojis`, `stickers`, `scheduledEvents`,
1307
+ * `autoModerationRules` and `invites` managers ready to stub.
1299
1308
  *
1300
1309
  * Use it for the server a message or an interaction came from, with the members, roles and channels a handler looks
1301
1310
  * up in it.
@@ -1305,9 +1314,11 @@ interface MockGuildOverrides {
1305
1314
  *
1306
1315
  * @remarks
1307
1316
  * A manager's `fetch(id)` resolves to its cached item with that id, as discord.js looks there first, or to a new one it
1308
- * caches under that id: a member or channel in this guild, a role with that id, or a ban. `members.fetch({ user: ids })`
1309
- * resolves to a collection of each of those members, found or made the same way; `create()` and `edit()` resolve to a
1310
- * mock of its item, and a list fetch to an empty collection. Members, roles and channels given are put in
1317
+ * caches under that id: a member, channel, emoji, sticker, scheduled event or AutoMod rule in this guild, a role with
1318
+ * that id, a ban, or an invite with that code. `members.fetch({ user: ids })` resolves to a collection of each of those
1319
+ * members, found or made the same way; `create()` and `edit()` resolve to a mock of its item, which `create()` caches
1320
+ * as discord.js does, but for an invite, made for the channel given and cached nowhere; a list fetch resolves to an
1321
+ * empty collection. Members, roles and channels given are put in
1311
1322
  * their managers' caches, where dispatch looks first when it resolves a message's typed params; a member
1312
1323
  * {@link createMockMember} made without a server is in this one. Its `roles.everyone` is the role given with the
1313
1324
  * guild's id, or else an @everyone role of its own at position 0 with no permissions, in `roles.cache` as Discord has
@@ -1616,8 +1627,9 @@ declare function createChatInputOptions<Cached extends CacheType = any>(opts?: C
1616
1627
  * and `message.thread` is `null` when the channel caches no thread under the message's id. So do a message's
1617
1628
  * `editedAt`, a member's `presence`, a server's `verified` and `systemChannel` and a channel's `parent`, each `null` or
1618
1629
  * `false` until the test gives what it is computed from. A reaction's `me` is `false`, a message's
1619
- * `mentions.repliedUser` and a modal's `message` are `null`, and a reaction has a whole message of its own, so
1620
- * MeoCord's dispatcher fetches neither. No placeholder warning is logged.
1630
+ * `mentions.repliedUser` and a modal's `message` are `null`, an interaction's `ephemeral` is `null` until `reply()` or
1631
+ * `deferReply()` decides it, and a reaction has a whole message of its own, so MeoCord's dispatcher fetches neither. No
1632
+ * placeholder warning is logged.
1621
1633
  *
1622
1634
  * @remarks
1623
1635
  * Those getters read what a server holds, so strict mocks also have it as Discord sends it: the bot's member is in the
@@ -1630,8 +1642,10 @@ declare function createChatInputOptions<Cached extends CacheType = any>(opts?: C
1630
1642
  * A message the bot sends is its `client.user`'s, and one it sends in a DM is in that DM. Give the bot's member a role
1631
1643
  * to let it do more, such as kick a member its role ranks above. A value the test sets on a mock wins over the computed
1632
1644
  * one. An interaction's answer that discord.js would refuse, such as a second `reply()` after one a test set with
1633
- * `mockResolvedValue`, is refused too, where without it the mock runs it and warns. The next major version (5.0)
1634
- * computes these values, and refuses those answers, without the call.
1645
+ * `mockResolvedValue`, is refused too, where without it the mock runs it and warns. An answer marks the interaction
1646
+ * `replied`, `deferred` or `responded` once it resolves, as discord.js does, so code that doesn't await one fails as it
1647
+ * would on a bot, within one run of the test's code. The next major version (5.0) computes these values, and refuses
1648
+ * those answers, without the call.
1635
1649
  *
1636
1650
  * `invoke` also refuses a call that gives a handler fewer arguments than it declares where it builds none, such as a
1637
1651
  * reaction handler given its reaction without its `ReactionEvent`; without strict mocks, it warns once and calls it.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "meocord",
3
3
  "description": "Decorator-based framework for Discord bots on discord.js, with dependency injection, guards, a CLI and a testing toolkit.",
4
- "version": "4.2.1",
4
+ "version": "4.2.2",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": ">=22.13"