yuzuha 0.3.0 → 0.3.1

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 (138) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +3 -3
  3. package/VERSIONING.md +18 -5
  4. package/dist/commands/arguments.d.ts.map +1 -1
  5. package/dist/commands/arguments.js +40 -13
  6. package/dist/commands/arguments.js.map +1 -1
  7. package/dist/commands/builders.d.ts +1 -0
  8. package/dist/commands/builders.d.ts.map +1 -1
  9. package/dist/commands/builders.js +5 -0
  10. package/dist/commands/builders.js.map +1 -1
  11. package/dist/commands/context-like.d.ts +4 -0
  12. package/dist/commands/context-like.d.ts.map +1 -0
  13. package/dist/commands/context-like.js +2 -0
  14. package/dist/commands/context-like.js.map +1 -0
  15. package/dist/commands/context.d.ts +16 -2
  16. package/dist/commands/context.d.ts.map +1 -1
  17. package/dist/commands/context.js +53 -11
  18. package/dist/commands/context.js.map +1 -1
  19. package/dist/commands/definition.d.ts +1 -0
  20. package/dist/commands/definition.d.ts.map +1 -1
  21. package/dist/commands/definition.js.map +1 -1
  22. package/dist/commands/typed-arguments.js +2 -2
  23. package/dist/commands/typed-arguments.js.map +1 -1
  24. package/dist/domain/cdn.d.ts +23 -0
  25. package/dist/domain/cdn.d.ts.map +1 -0
  26. package/dist/domain/cdn.js +38 -0
  27. package/dist/domain/cdn.js.map +1 -0
  28. package/dist/domain/resolvers.d.ts +60 -0
  29. package/dist/domain/resolvers.d.ts.map +1 -0
  30. package/dist/domain/resolvers.js +31 -0
  31. package/dist/domain/resolvers.js.map +1 -0
  32. package/dist/domain/values.d.ts +2 -0
  33. package/dist/domain/values.d.ts.map +1 -1
  34. package/dist/domain/values.js +26 -1
  35. package/dist/domain/values.js.map +1 -1
  36. package/dist/framework/bot.d.ts +5 -0
  37. package/dist/framework/bot.d.ts.map +1 -1
  38. package/dist/framework/bot.js +44 -9
  39. package/dist/framework/bot.js.map +1 -1
  40. package/dist/framework/logging.d.ts +4 -1
  41. package/dist/framework/logging.d.ts.map +1 -1
  42. package/dist/framework/logging.js.map +1 -1
  43. package/dist/framework/options.d.ts +12 -0
  44. package/dist/framework/options.d.ts.map +1 -1
  45. package/dist/framework/options.js.map +1 -1
  46. package/dist/index.d.ts +11 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +7 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/infrastructure/fluxer/resources/channels.d.ts.map +1 -1
  51. package/dist/infrastructure/fluxer/resources/channels.js +62 -8
  52. package/dist/infrastructure/fluxer/resources/channels.js.map +1 -1
  53. package/dist/infrastructure/fluxer/resources/expressions.d.ts.map +1 -1
  54. package/dist/infrastructure/fluxer/resources/expressions.js +2 -1
  55. package/dist/infrastructure/fluxer/resources/expressions.js.map +1 -1
  56. package/dist/infrastructure/fluxer/resources/messages.d.ts +2 -1
  57. package/dist/infrastructure/fluxer/resources/messages.d.ts.map +1 -1
  58. package/dist/infrastructure/fluxer/resources/messages.js +16 -7
  59. package/dist/infrastructure/fluxer/resources/messages.js.map +1 -1
  60. package/dist/infrastructure/fluxer/resources/users.d.ts +1 -1
  61. package/dist/infrastructure/fluxer/resources/users.d.ts.map +1 -1
  62. package/dist/infrastructure/fluxer/resources/users.js +41 -9
  63. package/dist/infrastructure/fluxer/resources/users.js.map +1 -1
  64. package/dist/infrastructure/fluxer/resources.d.ts +3 -1
  65. package/dist/infrastructure/fluxer/resources.d.ts.map +1 -1
  66. package/dist/infrastructure/fluxer/resources.js +8 -3
  67. package/dist/infrastructure/fluxer/resources.js.map +1 -1
  68. package/dist/infrastructure/fluxer/transport.d.ts +4 -1
  69. package/dist/infrastructure/fluxer/transport.d.ts.map +1 -1
  70. package/dist/infrastructure/fluxer/transport.js +41 -14
  71. package/dist/infrastructure/fluxer/transport.js.map +1 -1
  72. package/dist/ports/resources/channels.d.ts +20 -1
  73. package/dist/ports/resources/channels.d.ts.map +1 -1
  74. package/dist/ports/resources/channels.js.map +1 -1
  75. package/dist/ports/resources/users.d.ts +5 -0
  76. package/dist/ports/resources/users.d.ts.map +1 -1
  77. package/dist/ports/resources/users.js.map +1 -1
  78. package/dist/services/authorization.js +9 -9
  79. package/dist/services/authorization.js.map +1 -1
  80. package/dist/services/members.d.ts +5 -0
  81. package/dist/services/members.d.ts.map +1 -1
  82. package/dist/services/members.js +75 -5
  83. package/dist/services/members.js.map +1 -1
  84. package/dist/services/moderation.js +9 -9
  85. package/dist/services/moderation.js.map +1 -1
  86. package/dist/services/resource-authorization.d.ts.map +1 -1
  87. package/dist/services/resource-authorization.js +31 -17
  88. package/dist/services/resource-authorization.js.map +1 -1
  89. package/dist/services/retry.d.ts +17 -0
  90. package/dist/services/retry.d.ts.map +1 -0
  91. package/dist/services/retry.js +67 -0
  92. package/dist/services/retry.js.map +1 -0
  93. package/dist/shared/errors.d.ts +4 -1
  94. package/dist/shared/errors.d.ts.map +1 -1
  95. package/dist/shared/errors.js +8 -1
  96. package/dist/shared/errors.js.map +1 -1
  97. package/dist/testing.d.ts +8 -0
  98. package/dist/testing.d.ts.map +1 -1
  99. package/dist/testing.js +24 -4
  100. package/dist/testing.js.map +1 -1
  101. package/docs/API.md +11 -0
  102. package/docs/CANVAS.md +1 -1
  103. package/docs/FRAMEWORK.md +13 -0
  104. package/docs/IMAGES.md +9 -0
  105. package/docs/NATIVE.md +49 -1
  106. package/docs/PARITY-MATRIX.md +31 -32
  107. package/docs/QUICKSTART.md +2 -2
  108. package/docs/README.md +1 -1
  109. package/docs/TESTING.md +16 -0
  110. package/package.json +1 -1
  111. package/src/commands/arguments.ts +35 -13
  112. package/src/commands/builders.ts +4 -0
  113. package/src/commands/context-like.ts +7 -0
  114. package/src/commands/context.ts +56 -11
  115. package/src/commands/definition.ts +1 -0
  116. package/src/commands/typed-arguments.ts +2 -2
  117. package/src/domain/cdn.ts +55 -0
  118. package/src/domain/resolvers.ts +42 -0
  119. package/src/domain/values.ts +28 -1
  120. package/src/framework/bot.ts +41 -10
  121. package/src/framework/logging.ts +5 -1
  122. package/src/framework/options.ts +4 -0
  123. package/src/index.ts +13 -0
  124. package/src/infrastructure/fluxer/resources/channels.ts +53 -8
  125. package/src/infrastructure/fluxer/resources/expressions.ts +2 -1
  126. package/src/infrastructure/fluxer/resources/messages.ts +17 -6
  127. package/src/infrastructure/fluxer/resources/users.ts +38 -9
  128. package/src/infrastructure/fluxer/resources.ts +4 -3
  129. package/src/infrastructure/fluxer/transport.ts +42 -13
  130. package/src/ports/resources/channels.ts +11 -1
  131. package/src/ports/resources/users.ts +3 -0
  132. package/src/services/authorization.ts +9 -9
  133. package/src/services/members.ts +70 -5
  134. package/src/services/moderation.ts +9 -9
  135. package/src/services/resource-authorization.ts +31 -17
  136. package/src/services/retry.ts +74 -0
  137. package/src/shared/errors.ts +10 -1
  138. package/src/testing.ts +28 -4
@@ -1 +1 @@
1
- {"version":3,"file":"resource-authorization.js","sourceRoot":"","sources":["../../src/services/resource-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ModerationMember } from '../domain/moderation.js';\nimport { isAbove } from '../domain/moderation.js';\nimport { hasPermission, permission } from '../domain/permissions.js';\nimport { emojiBatch } from '../domain/resource-batches.js';\nimport type { Resources } from '../ports/resources.js';\nimport type { RoleInfo } from '../ports/resources/roles.js';\nimport type { ThreadDefaultsInput, ThreadSelfEditInput } from '../ports/resources/threads.js';\nimport type { Transport } from '../ports/transport.js';\nimport { GuardError, YuzuhaError } from '../shared/errors.js';\nimport { AuthorizationService, requireGuild } from './authorization.js';\nimport type { ActorScope } from './authorization.js';\n\nexport function bindAuthorizedResources(source: Resources, transport: Transport, scope: ActorScope): Resources {\n const authorization = new AuthorizationService(transport, scope);\n const guild = (id: string) => {\n if (id !== requireGuild(scope.guildID)) throw new GuardError('O recurso deve pertencer ao servidor atual.');\n return id;\n };\n const allowed = async (name: string, channelID?: string) => {\n await authorization.requirePermission(name, false, undefined, channelID);\n await authorization.requirePermission(name, true, undefined, channelID);\n };\n const actors = async (): Promise<[ModerationMember, ModerationMember]> => Promise.all([\n transport.member(requireGuild(scope.guildID), scope.authorID),\n transport.member(requireGuild(scope.guildID), transport.botID),\n ]);\n const permissions = async (names: string[] | undefined, channelID?: string) => {\n for (const name of names ?? []) {\n permission(name);\n await allowed(name, channelID);\n }\n };\n const roleHierarchy = async (role: RoleInfo, everyone = false) => {\n if (role.managed !== false || (!everyone && role.id === scope.guildID)) {\n throw new GuardError('Cargos gerenciados e @everyone não podem ser alterados por esta operação.');\n }\n if (everyone && role.id === scope.guildID) return;\n const [author, bot] = await actors();\n const target = { id: role.id, owner: false, rank: role.position, topRoleID: role.id, permissions: 0n };\n if ((!author.owner && !isAbove(author, target)) || !isAbove(bot, target)) {\n throw new GuardError('O cargo deve estar abaixo dos cargos do autor e do bot.');\n }\n };\n const memberHierarchy = async (id: string) => {\n const [author, bot] = await actors();\n const target = await transport.member(requireGuild(scope.guildID), id);\n if (target.owner || (id !== author.id && !author.owner && !isAbove(author, target))\n || (id !== bot.id && !isAbove(bot, target))) {\n throw new GuardError('O membro deve estar abaixo dos cargos do autor e do bot.');\n }\n };\n const role = async (guildID: string, query: string) => {\n guild(guildID);\n await allowed('ManageRoles');\n const target = await source.roles.resolve(guildID, query);\n await roleHierarchy(target);\n return target;\n };\n const channel = async (id: string, flag = 'ManageChannels') => {\n requireGuild(scope.guildID);\n const target = await source.channels.get(id);\n guild(target.guildID ?? '');\n await allowed(flag, id);\n return target;\n };\n const dm = async (id: string) => {\n const target = await source.channels.get(id);\n if (target.guildID !== null || !target.recipientIDs?.includes(scope.authorID)) {\n throw new GuardError('Esta operação exige um canal de DM do qual o autor participe.');\n }\n return target;\n };\n const parent = async (id: string) => {\n const target = await channel(id);\n if (target.type !== 4) throw new GuardError('O canal pai deve ser uma categoria.');\n };\n const webhook = async (id: string) => {\n requireGuild(scope.guildID);\n const target = await source.webhooks.fetch(id);\n guild(target.guildID);\n await channel(target.channelID, 'ManageWebhooks');\n };\n const expressions = async (guildID: string) => {\n guild(guildID);\n await allowed('ManageExpressions');\n };\n return { users: Object.assign(Object.create(source.users), {\n async transferOwnership(guildID: string, userID: string) {\n requireGuild(guildID);\n const [author] = await actors();\n if (!author.owner) throw new GuardError('Apenas o dono do servidor pode transferir a propriedade.');\n const target = await source.users.member(guildID, userID);\n if (target.bot) throw new GuardError('A propriedade não pode ser transferida para um bot.');\n return source.users.transferOwnership(guildID, userID);\n },\n }), messages: Object.assign(Object.create(source.messages), {\n async deleteAttachment(channelID: string, messageID: string, attachmentID: string) {\n const message = await source.messages.fetch(channelID, messageID);\n if (message.authorID !== scope.authorID) await authorization.requirePermission('ManageMessages', false, undefined, channelID);\n if (message.authorID !== transport.botID) await authorization.requirePermission('ManageMessages', true, undefined, channelID);\n return source.messages.deleteAttachment(channelID, messageID, attachmentID);\n },\n async bulkDelete(channelID: string, messageIDs: string[]) {\n await channel(channelID, 'ManageMessages');\n const ids = [...new Set(messageIDs)];\n if (!ids.length) throw new GuardError('Informe ao menos uma mensagem para apagar.');\n if (ids.length > 100) throw new YuzuhaError('BULK_DELETE_LIMIT', 'Exclusão em massa aceita no máximo 100 mensagens por chamada.');\n return source.messages.bulkDelete(channelID, ids);\n },\n async bulkDeleteOwn(channelID: string) { await channel(channelID, 'SendMessages'); return source.messages.bulkDeleteOwn(channelID); },\n async acknowledgePins(channelID: string) { await channel(channelID, 'ReadMessageHistory'); return source.messages.acknowledgePins(channelID); },\n async clearReadState(channelID: string) { await channel(channelID, 'ReadMessageHistory'); return source.messages.clearReadState(channelID); },\n async purgeDM(channelID: string) {\n const channel = await source.channels.get(channelID);\n if (channel.type === 999) {\n throw new GuardError('O canal de anotações pessoais só pode ser esvaziado por bot.resources.messages.purgeDM.');\n }\n await dm(channelID);\n return source.messages.purgeDM(channelID);\n },\n }), collectors: source.collectors,\n threads: Object.assign(Object.create(source.threads), {\n async setLocked(threadID: string, locked: boolean, reason?: string) {\n await channel(threadID);\n return source.threads.setLocked(threadID, locked, reason);\n },\n async editSelf(threadID: string, input: ThreadSelfEditInput) { await channel(threadID, 'ViewChannel'); return source.threads.editSelf(threadID, input); },\n async editDefaults(parentID: string, input: ThreadDefaultsInput) { await channel(parentID); return source.threads.editDefaults(parentID, input); },\n }), invites: source.invites, gateway: source.gateway,\n instance: source.instance, self: source.self, cache: source.cache, expressions: {\n emoji: source.expressions.emoji.bind(source.expressions), emojis: source.expressions.emojis.bind(source.expressions),\n sticker: source.expressions.sticker.bind(source.expressions), stickers: source.expressions.stickers.bind(source.expressions),\n async createEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.createEmoji(...args);\n },\n async editEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.editEmoji(...args);\n },\n async deleteEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.deleteEmoji(...args);\n },\n async createSticker(...args) {\n await expressions(args[0]);\n return source.expressions.createSticker(...args);\n },\n async createStickersBulk(...args) {\n await expressions(args[0]);\n return source.expressions.createStickersBulk(...args);\n },\n async editSticker(...args) {\n await expressions(args[0]);\n return source.expressions.editSticker(...args);\n },\n async deleteSticker(...args) {\n await expressions(args[0]);\n return source.expressions.deleteSticker(...args);\n },\n async cloneEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.cloneEmoji(...args);\n },\n async cloneSticker(...args) {\n await expressions(args[0]);\n return source.expressions.cloneSticker(...args);\n },\n async createEmojisBulk(guildID, inputs) {\n const batch = emojiBatch(inputs);\n await expressions(guildID);\n return source.expressions.createEmojisBulk(guildID, batch);\n },\n }, roles: {\n resolve: source.roles.resolve.bind(source.roles), list: source.roles.list.bind(source.roles),\n has: source.roles.has.bind(source.roles),\n async add(guildID, userID, query) {\n const target = await role(guildID, query);\n await memberHierarchy(userID);\n await permissionsFromRole(target);\n return source.roles.add(guildID, userID, target.id);\n },\n async remove(guildID, userID, query) {\n const target = await role(guildID, query);\n await memberHierarchy(userID);\n return source.roles.remove(guildID, userID, target.id);\n },\n async create(guildID, input) {\n guild(guildID);\n await allowed('ManageRoles');\n await permissions(input.permissions);\n return source.roles.create(guildID, input);\n },\n async edit(guildID, query, input) {\n const target = await role(guildID, query);\n await permissions(input.permissions);\n return source.roles.edit(guildID, target.id, input);\n },\n async delete(guildID, query, reason) {\n const target = await role(guildID, query);\n return source.roles.delete(guildID, target.id, reason);\n },\n async setRoleHoistPositions(guildID: string, updates: { id: string; position: number | null }[]) {\n guild(guildID);\n await allowed('ManageRoles');\n for (const update of updates) await roleHierarchy(await role(guildID, update.id));\n return source.roles.setRoleHoistPositions(guildID, updates);\n },\n async resetRoleHoistPositions(guildID: string) {\n guild(guildID);\n await allowed('ManageRoles');\n return source.roles.resetRoleHoistPositions(guildID);\n },\n async move(guildID, query, position) {\n const target = await role(guildID, query);\n if (!Number.isSafeInteger(position) || position < 1) throw new GuardError('Posição de cargo deve ser um inteiro maior que zero.');\n await roleHierarchy({ ...target, position });\n return source.roles.move(guildID, target.id, position);\n },\n }, channels: {\n get: source.channels.get.bind(source.channels), list: source.channels.list.bind(source.channels),\n permissionsFor: source.channels.permissionsFor.bind(source.channels),\n async create(guildID, input) {\n guild(guildID);\n if (input.parentID) await parent(input.parentID);\n else await allowed('ManageChannels');\n return source.channels.create(guildID, input);\n },\n async edit(id, input) {\n await channel(id);\n if (input.parentID) await parent(input.parentID);\n return source.channels.edit(id, input);\n },\n async delete(id, reason) { await channel(id); return source.channels.delete(id, reason); },\n async addRecipient(id, userID) {\n const target = await dm(id);\n if (!target.ownerID || target.ownerID !== scope.authorID) {\n throw new GuardError('Apenas o dono do grupo pode adicionar participantes.');\n }\n return source.channels.addRecipient(id, userID);\n },\n async removeRecipient(id, userID, options) {\n const target = await dm(id);\n if (userID !== scope.authorID && (!target.ownerID || target.ownerID !== scope.authorID)) {\n throw new GuardError('Apenas o dono do grupo pode remover outros participantes.');\n }\n return source.channels.removeRecipient(id, userID, options);\n },\n async setSlowmode(id, seconds, reason) { await channel(id); return source.channels.setSlowmode(id, seconds, reason); },\n slowmode: source.channels.slowmode.bind(source.channels),\n async sendTyping(id) { await channel(id, 'SendMessages'); return source.channels.sendTyping(id); },\n rtcRegions: source.channels.rtcRegions.bind(source.channels),\n async move(id, position) { await channel(id); return source.channels.move(id, position); },\n async editThreadDefaults(id, input) { await channel(id); return source.channels.editThreadDefaults(id, input); },\n async setDefaultForumLayout(id, layout, reason) { await channel(id); return source.channels.setDefaultForumLayout(id, layout, reason); },\n async setCategory(id, parentID, reason) {\n await channel(id);\n if (parentID) await parent(parentID);\n return source.channels.setCategory(id, parentID, reason);\n },\n async overwrite(id, targetID, input) {\n await channel(id, 'ManageRoles');\n const roles = await source.roles.list(requireGuild(scope.guildID));\n const targetRole = roles.find(candidate => candidate.id === targetID);\n if (input.type === 'role' || (input.type === undefined && targetRole)) {\n if (!targetRole) throw new GuardError('Cargo não encontrado no servidor atual.');\n await roleHierarchy(targetRole, true);\n } else await memberHierarchy(targetID);\n await permissions(input.allow, id);\n await permissions(input.deny, id);\n return source.channels.overwrite(id, targetID, { ...input, type: targetRole && input.type !== 'member' ? 'role' : 'member' });\n },\n }, webhooks: {\n async fetch(id) {\n requireGuild(scope.guildID);\n const target = await source.webhooks.fetch(id);\n guild(target.guildID);\n await channel(target.channelID, 'ManageWebhooks');\n return target;\n },\n async create(id, name, reason) { await channel(id, 'ManageWebhooks'); return source.webhooks.create(id, name, reason); },\n async list(id) { await channel(id, 'ManageWebhooks'); return source.webhooks.list(id); },\n async send(id, token, input) { await webhook(id); return source.webhooks.send(id, token, input); },\n async editMessage(id, token, messageID, input) { await webhook(id); return source.webhooks.editMessage(id, token, messageID, input); },\n async deleteMessage(id, token, messageID) { await webhook(id); return source.webhooks.deleteMessage(id, token, messageID); },\n async edit(id, token, name) { await webhook(id); return source.webhooks.edit(id, token, name); },\n async delete(id, token) { await webhook(id); return source.webhooks.delete(id, token); },\n } };\n\n async function permissionsFromRole(target: RoleInfo) {\n const [author, bot] = await actors();\n const bits = BigInt(target.permissions);\n for (const actor of [author, bot]) {\n if (!hasPermission(actor.permissions, 'Administrator', actor.owner) && (bits & actor.permissions) !== bits) {\n throw new GuardError('O cargo contém permissões que o autor ou o bot não possui.');\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"resource-authorization.js","sourceRoot":"","sources":["../../src/services/resource-authorization.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ModerationMember } from '../domain/moderation.js';\nimport { isAbove } from '../domain/moderation.js';\nimport { hasPermission, permission } from '../domain/permissions.js';\nimport { emojiBatch } from '../domain/resource-batches.js';\nimport type { Resources } from '../ports/resources.js';\nimport type { RoleInfo } from '../ports/resources/roles.js';\nimport type { ThreadDefaultsInput, ThreadSelfEditInput } from '../ports/resources/threads.js';\nimport type { Transport } from '../ports/transport.js';\nimport { GuardError, YuzuhaError } from '../shared/errors.js';\nimport { AuthorizationService, requireGuild } from './authorization.js';\nimport type { ActorScope } from './authorization.js';\n\nexport function bindAuthorizedResources(source: Resources, transport: Transport, scope: ActorScope): Resources {\n const authorization = new AuthorizationService(transport, scope);\n const guild = (id: string) => {\n if (id !== requireGuild(scope.guildID)) throw new GuardError('O recurso deve pertencer ao servidor atual.', 'GENERIC');\n return id;\n };\n const allowed = async (name: string, channelID?: string) => {\n await authorization.requirePermission(name, false, undefined, channelID);\n await authorization.requirePermission(name, true, undefined, channelID);\n };\n const actors = async (): Promise<[ModerationMember, ModerationMember]> => Promise.all([\n transport.member(requireGuild(scope.guildID), scope.authorID),\n transport.member(requireGuild(scope.guildID), transport.botID),\n ]);\n const permissions = async (names: string[] | undefined, channelID?: string) => {\n for (const name of names ?? []) {\n permission(name);\n await allowed(name, channelID);\n }\n };\n const roleHierarchy = async (role: RoleInfo, everyone = false) => {\n if (role.managed !== false || (!everyone && role.id === scope.guildID)) {\n throw new GuardError('Cargos gerenciados e @everyone não podem ser alterados por esta operação.', 'HIERARCHY');\n }\n if (everyone && role.id === scope.guildID) return;\n const [author, bot] = await actors();\n const target = { id: role.id, owner: false, rank: role.position, topRoleID: role.id, permissions: 0n };\n if ((!author.owner && !isAbove(author, target)) || !isAbove(bot, target)) {\n throw new GuardError('O cargo deve estar abaixo dos cargos do autor e do bot.', 'HIERARCHY');\n }\n };\n const memberHierarchy = async (id: string) => {\n const [author, bot] = await actors();\n const target = await transport.member(requireGuild(scope.guildID), id);\n if (target.owner || (id !== author.id && !author.owner && !isAbove(author, target))\n || (id !== bot.id && !isAbove(bot, target))) {\n throw new GuardError('O membro deve estar abaixo dos cargos do autor e do bot.', 'HIERARCHY');\n }\n };\n const role = async (guildID: string, query: string) => {\n guild(guildID);\n await allowed('ManageRoles');\n const target = await source.roles.resolve(guildID, query);\n await roleHierarchy(target);\n return target;\n };\n const channel = async (id: string, flag = 'ManageChannels') => {\n requireGuild(scope.guildID);\n const target = await source.channels.get(id);\n guild(target.guildID ?? '');\n await allowed(flag, id);\n return target;\n };\n const dm = async (id: string) => {\n const target = await source.channels.get(id);\n if (target.guildID !== null || !target.recipientIDs?.includes(scope.authorID)) {\n throw new GuardError('Esta operação exige um canal de DM do qual o autor participe.', 'GENERIC');\n }\n return target;\n };\n const parent = async (id: string) => {\n const target = await channel(id);\n if (target.type !== 4) throw new GuardError('O canal pai deve ser uma categoria.', 'INVALID_ARGUMENT');\n };\n const webhook = async (id: string) => {\n requireGuild(scope.guildID);\n const target = await source.webhooks.fetch(id);\n guild(target.guildID);\n await channel(target.channelID, 'ManageWebhooks');\n };\n const expressions = async (guildID: string) => {\n guild(guildID);\n await allowed('ManageExpressions');\n };\n return { users: Object.assign(Object.create(source.users), {\n async transferOwnership(guildID: string, userID: string) {\n requireGuild(guildID);\n const [author] = await actors();\n if (!author.owner) throw new GuardError('Apenas o dono do servidor pode transferir a propriedade.', 'PERMISSION_MISSING_AUTHOR');\n const target = await source.users.member(guildID, userID);\n if (target.bot) throw new GuardError('A propriedade não pode ser transferida para um bot.', 'BOT_TARGET');\n return source.users.transferOwnership(guildID, userID);\n },\n async resolveBan(guildID: string, query: string) {\n guild(guildID);\n await allowed('BanMembers');\n return source.users.resolveBan(guildID, query);\n },\n }), messages: Object.assign(Object.create(source.messages), {\n async deleteAttachment(channelID: string, messageID: string, attachmentID: string) {\n const message = await source.messages.fetch(channelID, messageID);\n if (message.authorID !== scope.authorID) await authorization.requirePermission('ManageMessages', false, undefined, channelID);\n if (message.authorID !== transport.botID) await authorization.requirePermission('ManageMessages', true, undefined, channelID);\n return source.messages.deleteAttachment(channelID, messageID, attachmentID);\n },\n async bulkDelete(channelID: string, messageIDs: string[]) {\n await channel(channelID, 'ManageMessages');\n const ids = [...new Set(messageIDs)];\n if (!ids.length) throw new GuardError('Informe ao menos uma mensagem para apagar.', 'INVALID_ARGUMENT');\n if (ids.length > 100) throw new YuzuhaError('BULK_DELETE_LIMIT', 'Exclusão em massa aceita no máximo 100 mensagens por chamada.');\n return source.messages.bulkDelete(channelID, ids);\n },\n async bulkDeleteOwn(channelID: string) { await channel(channelID, 'SendMessages'); return source.messages.bulkDeleteOwn(channelID); },\n async acknowledgePins(channelID: string) { await channel(channelID, 'ReadMessageHistory'); return source.messages.acknowledgePins(channelID); },\n async clearReadState(channelID: string) { await channel(channelID, 'ReadMessageHistory'); return source.messages.clearReadState(channelID); },\n async purgeDM(channelID: string) {\n const channel = await source.channels.get(channelID);\n if (channel.type === 999) {\n throw new GuardError('O canal de anotações pessoais só pode ser esvaziado por bot.resources.messages.purgeDM.', 'GENERIC');\n }\n await dm(channelID);\n return source.messages.purgeDM(channelID);\n },\n }), collectors: source.collectors,\n threads: Object.assign(Object.create(source.threads), {\n async setLocked(threadID: string, locked: boolean, reason?: string) {\n await channel(threadID);\n return source.threads.setLocked(threadID, locked, reason);\n },\n async editSelf(threadID: string, input: ThreadSelfEditInput) { await channel(threadID, 'ViewChannel'); return source.threads.editSelf(threadID, input); },\n async editDefaults(parentID: string, input: ThreadDefaultsInput) { await channel(parentID); return source.threads.editDefaults(parentID, input); },\n }), invites: source.invites, gateway: source.gateway,\n instance: source.instance, self: source.self, cache: source.cache, expressions: {\n emoji: source.expressions.emoji.bind(source.expressions), emojis: source.expressions.emojis.bind(source.expressions),\n sticker: source.expressions.sticker.bind(source.expressions), stickers: source.expressions.stickers.bind(source.expressions),\n async createEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.createEmoji(...args);\n },\n async editEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.editEmoji(...args);\n },\n async deleteEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.deleteEmoji(...args);\n },\n async createSticker(...args) {\n await expressions(args[0]);\n return source.expressions.createSticker(...args);\n },\n async createStickersBulk(...args) {\n await expressions(args[0]);\n return source.expressions.createStickersBulk(...args);\n },\n async editSticker(...args) {\n await expressions(args[0]);\n return source.expressions.editSticker(...args);\n },\n async deleteSticker(...args) {\n await expressions(args[0]);\n return source.expressions.deleteSticker(...args);\n },\n async cloneEmoji(...args) {\n await expressions(args[0]);\n return source.expressions.cloneEmoji(...args);\n },\n async cloneSticker(...args) {\n await expressions(args[0]);\n return source.expressions.cloneSticker(...args);\n },\n async createEmojisBulk(guildID, inputs) {\n const batch = emojiBatch(inputs);\n await expressions(guildID);\n return source.expressions.createEmojisBulk(guildID, batch);\n },\n }, roles: {\n resolve: source.roles.resolve.bind(source.roles), list: source.roles.list.bind(source.roles),\n has: source.roles.has.bind(source.roles),\n async add(guildID, userID, query) {\n const target = await role(guildID, query);\n await memberHierarchy(userID);\n await permissionsFromRole(target);\n return source.roles.add(guildID, userID, target.id);\n },\n async remove(guildID, userID, query) {\n const target = await role(guildID, query);\n await memberHierarchy(userID);\n return source.roles.remove(guildID, userID, target.id);\n },\n async create(guildID, input) {\n guild(guildID);\n await allowed('ManageRoles');\n await permissions(input.permissions);\n return source.roles.create(guildID, input);\n },\n async edit(guildID, query, input) {\n const target = await role(guildID, query);\n await permissions(input.permissions);\n return source.roles.edit(guildID, target.id, input);\n },\n async delete(guildID, query, reason) {\n const target = await role(guildID, query);\n return source.roles.delete(guildID, target.id, reason);\n },\n async setRoleHoistPositions(guildID: string, updates: { id: string; position: number | null }[]) {\n guild(guildID);\n await allowed('ManageRoles');\n for (const update of updates) await roleHierarchy(await role(guildID, update.id));\n return source.roles.setRoleHoistPositions(guildID, updates);\n },\n async resetRoleHoistPositions(guildID: string) {\n guild(guildID);\n await allowed('ManageRoles');\n return source.roles.resetRoleHoistPositions(guildID);\n },\n async move(guildID, query, position) {\n const target = await role(guildID, query);\n if (!Number.isSafeInteger(position) || position < 1) throw new GuardError('Posição de cargo deve ser um inteiro maior que zero.', 'INVALID_ARGUMENT');\n await roleHierarchy({ ...target, position });\n return source.roles.move(guildID, target.id, position);\n },\n }, channels: {\n get: source.channels.get.bind(source.channels), list: source.channels.list.bind(source.channels),\n permissionsFor: source.channels.permissionsFor.bind(source.channels),\n async create(guildID, input) {\n guild(guildID);\n if (input.parentID) await parent(input.parentID);\n else await allowed('ManageChannels');\n return source.channels.create(guildID, input);\n },\n async edit(id, input) {\n await channel(id);\n if (input.parentID) await parent(input.parentID);\n return source.channels.edit(id, input);\n },\n async delete(id, reason) { await channel(id); return source.channels.delete(id, reason); },\n async addRecipient(id, userID) {\n const target = await dm(id);\n if (!target.ownerID || target.ownerID !== scope.authorID) {\n throw new GuardError('Apenas o dono do grupo pode adicionar participantes.', 'PERMISSION_MISSING_AUTHOR');\n }\n return source.channels.addRecipient(id, userID);\n },\n async removeRecipient(id, userID, options) {\n const target = await dm(id);\n if (userID !== scope.authorID && (!target.ownerID || target.ownerID !== scope.authorID)) {\n throw new GuardError('Apenas o dono do grupo pode remover outros participantes.', 'PERMISSION_MISSING_AUTHOR');\n }\n return source.channels.removeRecipient(id, userID, options);\n },\n async setSlowmode(id, seconds, reason) { await channel(id); return source.channels.setSlowmode(id, seconds, reason); },\n slowmode: source.channels.slowmode.bind(source.channels),\n async sendTyping(id) { await channel(id, 'SendMessages'); return source.channels.sendTyping(id); },\n rtcRegions: source.channels.rtcRegions.bind(source.channels),\n async move(id, position) { await channel(id); return source.channels.move(id, position); },\n async editThreadDefaults(id, input) { await channel(id); return source.channels.editThreadDefaults(id, input); },\n async setDefaultForumLayout(id, layout, reason) { await channel(id); return source.channels.setDefaultForumLayout(id, layout, reason); },\n async setCategory(id, parentID, reason) {\n await channel(id);\n if (parentID) await parent(parentID);\n return source.channels.setCategory(id, parentID, reason);\n },\n async overwrite(id, targetID, input, options) {\n await channel(id, 'ManageRoles');\n const roles = await source.roles.list(requireGuild(scope.guildID));\n const targetRole = roles.find(candidate => candidate.id === targetID);\n if (input.type === 'role' || (input.type === undefined && targetRole)) {\n if (!targetRole) throw new GuardError('Cargo não encontrado no servidor atual.', 'GENERIC');\n await roleHierarchy(targetRole, true);\n } else await memberHierarchy(targetID);\n await permissions(input.allow, id);\n await permissions(input.deny, id);\n await permissions(input.neutral, id);\n return source.channels.overwrite(id, targetID, { ...input, type: targetRole && input.type !== 'member' ? 'role' : 'member' }, options);\n },\n async lock(id: string, options: { permission?: string; targetID?: string; reason?: string } = {}) {\n await channel(id, 'ManageChannels');\n return source.channels.lock(id, options);\n },\n async unlock(id: string, options: { permission?: string; targetID?: string; reason?: string } = {}) {\n await channel(id, 'ManageChannels');\n return source.channels.unlock(id, options);\n },\n }, webhooks: {\n async fetch(id) {\n requireGuild(scope.guildID);\n const target = await source.webhooks.fetch(id);\n guild(target.guildID);\n await channel(target.channelID, 'ManageWebhooks');\n return target;\n },\n async create(id, name, reason) { await channel(id, 'ManageWebhooks'); return source.webhooks.create(id, name, reason); },\n async list(id) { await channel(id, 'ManageWebhooks'); return source.webhooks.list(id); },\n async send(id, token, input) { await webhook(id); return source.webhooks.send(id, token, input); },\n async editMessage(id, token, messageID, input) { await webhook(id); return source.webhooks.editMessage(id, token, messageID, input); },\n async deleteMessage(id, token, messageID) { await webhook(id); return source.webhooks.deleteMessage(id, token, messageID); },\n async edit(id, token, name) { await webhook(id); return source.webhooks.edit(id, token, name); },\n async delete(id, token) { await webhook(id); return source.webhooks.delete(id, token); },\n } };\n\n async function permissionsFromRole(target: RoleInfo) {\n const [author, bot] = await actors();\n const bits = BigInt(target.permissions);\n for (const actor of [author, bot]) {\n if (!hasPermission(actor.permissions, 'Administrator', actor.owner) && (bits & actor.permissions) !== bits) {\n throw new GuardError('O cargo contém permissões que o autor ou o bot não possui.', 'HIERARCHY');\n }\n }\n }\n}\n"]}
@@ -0,0 +1,17 @@
1
+ export interface RetryPolicy {
2
+ requests?: number;
3
+ delayMs?: number;
4
+ }
5
+ export interface Reliability {
6
+ retry?: false | RetryPolicy;
7
+ signal?: AbortSignal;
8
+ onRetry?: (attempt: number, error: unknown) => void;
9
+ }
10
+ export declare function isTransientError(error: unknown): boolean;
11
+ export declare function isUndeliveredSend(error: unknown): boolean;
12
+ export declare function isNotFound(error: unknown): boolean;
13
+ export declare function isAbortError(error: unknown): boolean;
14
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
15
+ export declare function resolvePolicy(retry: false | RetryPolicy | undefined): Required<RetryPolicy> | false;
16
+ export declare function withRetry<T>(fn: (attempt: number) => Promise<T>, reliability?: Reliability, safe?: (error: unknown) => boolean): Promise<T>;
17
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/services/retry.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAaD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGxD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGzD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGlD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGpD;AAED,wBAAsB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ3E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,KAAK,CAGnG;AAED,wBAAsB,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,GAAE,WAAgB,EACnG,IAAI,GAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAA0B,GAAG,OAAO,CAAC,CAAC,CAAC,CAalE"}
@@ -0,0 +1,67 @@
1
+ import { YuzuhaError } from '../shared/errors.js';
2
+ const TRANSIENT_CODES = new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EAI_AGAIN', 'ENOTFOUND',
3
+ 'EPIPE', 'UND_ERR_SOCKET', 'UND_ERR_CONNECT_TIMEOUT', 'UND_ERR_HEADERS_TIMEOUT']);
4
+ const CONNECT_CODES = new Set(['ECONNREFUSED', 'ENOTFOUND', 'EAI_AGAIN', 'UND_ERR_CONNECT_TIMEOUT']);
5
+ function codeOf(error) {
6
+ const candidate = error;
7
+ if (typeof candidate?.code === 'string')
8
+ return candidate.code;
9
+ if (typeof candidate?.cause?.code === 'string')
10
+ return candidate.cause.code;
11
+ return undefined;
12
+ }
13
+ export function isTransientError(error) {
14
+ const code = codeOf(error);
15
+ return code !== undefined && TRANSIENT_CODES.has(code);
16
+ }
17
+ export function isUndeliveredSend(error) {
18
+ const code = codeOf(error);
19
+ return code !== undefined && CONNECT_CODES.has(code);
20
+ }
21
+ export function isNotFound(error) {
22
+ const candidate = error;
23
+ return candidate?.status === 404 || candidate?.code === 10008 || candidate?.code === 10007;
24
+ }
25
+ export function isAbortError(error) {
26
+ return error instanceof Error && (error.name === 'AbortError' || error.code === 'ABORT_ERR')
27
+ || error instanceof YuzuhaError && error.code === 'EXECUTION_ABORTED';
28
+ }
29
+ export async function sleep(ms, signal) {
30
+ if (!signal) {
31
+ await new Promise(resolve => setTimeout(resolve, ms));
32
+ return;
33
+ }
34
+ await new Promise((resolve, reject) => {
35
+ if (signal.aborted) {
36
+ reject(signal.reason instanceof Error ? signal.reason : new YuzuhaError('EXECUTION_ABORTED', 'Execução abortada.'));
37
+ return;
38
+ }
39
+ const timer = setTimeout(() => { signal.removeEventListener('abort', onAbort); resolve(); }, ms);
40
+ const onAbort = () => { clearTimeout(timer); reject(signal.reason instanceof Error ? signal.reason : new YuzuhaError('EXECUTION_ABORTED', 'Execução abortada.')); };
41
+ signal.addEventListener('abort', onAbort, { once: true });
42
+ });
43
+ }
44
+ export function resolvePolicy(retry) {
45
+ if (retry === false)
46
+ return false;
47
+ return { requests: retry?.requests ?? 1, delayMs: retry?.delayMs ?? 750 };
48
+ }
49
+ export async function withRetry(fn, reliability = {}, safe = isTransientError) {
50
+ const policy = resolvePolicy(reliability.retry);
51
+ if (policy === false)
52
+ return fn(0);
53
+ let attempt = 0;
54
+ for (;;) {
55
+ try {
56
+ return await fn(attempt);
57
+ }
58
+ catch (error) {
59
+ if (reliability.signal?.aborted || isAbortError(error) || attempt >= policy.requests || !safe(error))
60
+ throw error;
61
+ attempt += 1;
62
+ reliability.onRetry?.(attempt, error);
63
+ await sleep(policy.delayMs, reliability.signal);
64
+ }
65
+ }
66
+ }
67
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/services/retry.ts"],"names":[],"mappings":"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","sourcesContent":["import { YuzuhaError } from '../shared/errors.js';\n\nexport interface RetryPolicy {\n requests?: number;\n delayMs?: number;\n}\n\nexport interface Reliability {\n retry?: false | RetryPolicy;\n signal?: AbortSignal;\n onRetry?: (attempt: number, error: unknown) => void;\n}\n\nconst TRANSIENT_CODES = new Set(['ECONNRESET', 'ECONNREFUSED', 'ETIMEDOUT', 'EAI_AGAIN', 'ENOTFOUND',\n 'EPIPE', 'UND_ERR_SOCKET', 'UND_ERR_CONNECT_TIMEOUT', 'UND_ERR_HEADERS_TIMEOUT']);\nconst CONNECT_CODES = new Set(['ECONNREFUSED', 'ENOTFOUND', 'EAI_AGAIN', 'UND_ERR_CONNECT_TIMEOUT']);\n\nfunction codeOf(error: unknown): string | undefined {\n const candidate = error as { code?: unknown; cause?: { code?: unknown } } | null | undefined;\n if (typeof candidate?.code === 'string') return candidate.code;\n if (typeof candidate?.cause?.code === 'string') return candidate.cause.code;\n return undefined;\n}\n\nexport function isTransientError(error: unknown): boolean {\n const code = codeOf(error);\n return code !== undefined && TRANSIENT_CODES.has(code);\n}\n\nexport function isUndeliveredSend(error: unknown): boolean {\n const code = codeOf(error);\n return code !== undefined && CONNECT_CODES.has(code);\n}\n\nexport function isNotFound(error: unknown): boolean {\n const candidate = error as { code?: unknown; status?: unknown } | null | undefined;\n return candidate?.status === 404 || candidate?.code === 10008 || candidate?.code === 10007;\n}\n\nexport function isAbortError(error: unknown): boolean {\n return error instanceof Error && (error.name === 'AbortError' || (error as { code?: unknown }).code === 'ABORT_ERR')\n || error instanceof YuzuhaError && error.code === 'EXECUTION_ABORTED';\n}\n\nexport async function sleep(ms: number, signal?: AbortSignal): Promise<void> {\n if (!signal) { await new Promise(resolve => setTimeout(resolve, ms)); return; }\n await new Promise<void>((resolve, reject) => {\n if (signal.aborted) { reject(signal.reason instanceof Error ? signal.reason : new YuzuhaError('EXECUTION_ABORTED', 'Execução abortada.')); return; }\n const timer = setTimeout(() => { signal.removeEventListener('abort', onAbort); resolve(); }, ms);\n const onAbort = () => { clearTimeout(timer); reject(signal.reason instanceof Error ? signal.reason : new YuzuhaError('EXECUTION_ABORTED', 'Execução abortada.')); };\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nexport function resolvePolicy(retry: false | RetryPolicy | undefined): Required<RetryPolicy> | false {\n if (retry === false) return false;\n return { requests: retry?.requests ?? 1, delayMs: retry?.delayMs ?? 750 };\n}\n\nexport async function withRetry<T>(fn: (attempt: number) => Promise<T>, reliability: Reliability = {},\n safe: (error: unknown) => boolean = isTransientError): Promise<T> {\n const policy = resolvePolicy(reliability.retry);\n if (policy === false) return fn(0);\n let attempt = 0;\n for (;;) {\n try { return await fn(attempt); }\n catch (error) {\n if (reliability.signal?.aborted || isAbortError(error) || attempt >= policy.requests || !safe(error)) throw error;\n attempt += 1;\n reliability.onRetry?.(attempt, error);\n await sleep(policy.delayMs, reliability.signal);\n }\n }\n}\n"]}
@@ -11,9 +11,12 @@ export declare class ScriptError extends YuzuhaError {
11
11
  get column(): number;
12
12
  format(): string;
13
13
  }
14
+ export type GuardReason = 'GENERIC' | 'NOT_IN_GUILD' | 'NO_AUTHOR' | 'PERMISSION_MISSING_AUTHOR' | 'PERMISSION_MISSING_BOT' | 'HIERARCHY' | 'ADMIN_IMMUNE' | 'SELF_TARGET' | 'BOT_TARGET' | 'OWNER_TARGET' | 'MEMBER_NOT_FOUND' | 'NOT_BANNED' | 'INVALID_ARGUMENT' | 'INVALID_REASON' | 'INVALID_DURATION' | 'COOLDOWN';
14
15
  export declare class GuardError extends YuzuhaError {
15
- constructor(message: string);
16
+ readonly reason: GuardReason;
17
+ constructor(message: string, reason?: GuardReason);
16
18
  }
19
+ export declare function isGuardReason(error: unknown, ...reasons: GuardReason[]): error is GuardError;
17
20
  export declare function assert(condition: unknown, message: string): asserts condition;
18
21
  export declare class StopExecution extends Error {
19
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/shared/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;aACR,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIlF;AAED,qBAAa,WAAY,SAAQ,WAAW;aACiB,MAAM,EAAE,MAAM;aACvD,MAAM,EAAE,MAAM;aAAkB,IAAI;gBAD1C,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM,EACvD,MAAM,EAAE,MAAM,EAAkB,IAAI,SAAa,EAAE,OAAO,CAAC,EAAE,YAAY;IAI3F,IAAI,IAAI,IAAI,MAAM,CAAiE;IACnF,IAAI,MAAM,IAAI,MAAM,CAAiG;IACrH,MAAM,IAAI,MAAM;CAIjB;AAED,qBAAa,UAAW,SAAQ,WAAW;gBAC7B,OAAO,EAAE,MAAM;CAC5B;AAED,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAE7E;AACD,qBAAa,aAAc,SAAQ,KAAK;CAAG;AAE3C,qBAAa,sBAAuB,SAAQ,WAAW;aACzB,MAAM,EAAE,MAAM;aAAkB,QAAQ,EAAE,MAAM;gBAAhD,MAAM,EAAE,MAAM,EAAkB,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAG7F"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/shared/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;aACR,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIlF;AAED,qBAAa,WAAY,SAAQ,WAAW;aACiB,MAAM,EAAE,MAAM;aACvD,MAAM,EAAE,MAAM;aAAkB,IAAI;gBAD1C,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAkB,MAAM,EAAE,MAAM,EACvD,MAAM,EAAE,MAAM,EAAkB,IAAI,SAAa,EAAE,OAAO,CAAC,EAAE,YAAY;IAI3F,IAAI,IAAI,IAAI,MAAM,CAAiE;IACnF,IAAI,MAAM,IAAI,MAAM,CAAiG;IACrH,MAAM,IAAI,MAAM;CAIjB;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,cAAc,GAAG,WAAW,GAAG,2BAA2B,GAC5F,wBAAwB,GAAG,WAAW,GAAG,cAAc,GAAG,aAAa,GAAG,YAAY,GACtF,cAAc,GAAG,kBAAkB,GAAG,YAAY,GAAG,kBAAkB,GAAG,gBAAgB,GAC1F,kBAAkB,GAAG,UAAU,CAAC;AAEpC,qBAAa,UAAW,SAAQ,WAAW;aACI,MAAM,EAAE,WAAW;gBAApD,OAAO,EAAE,MAAM,EAAkB,MAAM,GAAE,WAAuB;CAC7E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,WAAW,EAAE,GAAG,KAAK,IAAI,UAAU,CAE5F;AAED,wBAAgB,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAE7E;AACD,qBAAa,aAAc,SAAQ,KAAK;CAAG;AAE3C,qBAAa,sBAAuB,SAAQ,WAAW;aACzB,MAAM,EAAE,MAAM;aAAkB,QAAQ,EAAE,MAAM;gBAAhD,MAAM,EAAE,MAAM,EAAkB,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAG7F"}
@@ -25,7 +25,14 @@ export class ScriptError extends YuzuhaError {
25
25
  }
26
26
  }
27
27
  export class GuardError extends YuzuhaError {
28
- constructor(message) { super('GUARD', message); }
28
+ reason;
29
+ constructor(message, reason = 'GENERIC') {
30
+ super('GUARD', message);
31
+ this.reason = reason;
32
+ }
33
+ }
34
+ export function isGuardReason(error, ...reasons) {
35
+ return error instanceof GuardError && reasons.includes(error.reason);
29
36
  }
30
37
  export function assert(condition, message) {
31
38
  if (!condition)
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/shared/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,WAAY,SAAQ,KAAK;IACR;IAA5B,YAA4B,IAAY,EAAE,OAAe,EAAE,OAAsB;QAC/E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QADE,SAAI,GAAJ,IAAI,CAAQ;QAEtC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,WAAW;IACiB;IACzC;IAAgC;IADlD,YAAY,IAAY,EAAE,OAAe,EAAkB,MAAc,EACvD,MAAc,EAAkB,OAAO,UAAU,EAAE,OAAsB;QACzF,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAF2B,WAAM,GAAN,MAAM,CAAQ;QACvD,WAAM,GAAN,MAAM,CAAQ;QAAkB,SAAI,GAAJ,IAAI,CAAa;QAEjE,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;IACD,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,IAAI,MAAM,KAAa,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrH,MAAM;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,KAAK,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC;IAC7H,CAAC;CACF;AAED,MAAM,OAAO,UAAW,SAAQ,WAAW;IACzC,YAAY,OAAe,IAAI,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC1D;AAED,MAAM,UAAU,MAAM,CAAC,SAAkB,EAAE,OAAe;IACxD,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AAChD,CAAC;AACD,MAAM,OAAO,aAAc,SAAQ,KAAK;CAAG;AAE3C,MAAM,OAAO,sBAAuB,SAAQ,WAAW;IACzB;IAAgC;IAA5D,YAA4B,MAAc,EAAkB,QAAgB,EAAE,KAAc;QAC1F,KAAK,CAAC,oBAAoB,EAAE,UAAU,MAAM,8DAA8D,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAD7F,WAAM,GAAN,MAAM,CAAQ;QAAkB,aAAQ,GAAR,QAAQ,CAAQ;IAE5E,CAAC;CACF","sourcesContent":["export class YuzuhaError extends Error {\n constructor(public readonly code: string, message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'YuzuhaError';\n }\n}\n\nexport class ScriptError extends YuzuhaError {\n constructor(code: string, message: string, public readonly source: string,\n public readonly offset: number, public readonly file = '<script>', options?: ErrorOptions) {\n super(code, message, options);\n this.name = 'ScriptError';\n }\n get line(): number { return this.source.slice(0, this.offset).split('\\n').length; }\n get column(): number { return this.offset === 0 ? 1 : this.offset - this.source.lastIndexOf('\\n', this.offset - 1); }\n format(): string {\n const line = this.source.split('\\n')[this.line - 1] ?? '';\n return `${this.file}:${this.line}:${this.column} [${this.code}] ${this.message}\\n${line}\\n${' '.repeat(this.column - 1)}^`;\n }\n}\n\nexport class GuardError extends YuzuhaError {\n constructor(message: string) { super('GUARD', message); }\n}\n\nexport function assert(condition: unknown, message: string): asserts condition {\n if (!condition) throw new GuardError(message);\n}\nexport class StopExecution extends Error {}\n\nexport class PartialModerationError extends YuzuhaError {\n constructor(public readonly action: string, public readonly targetID: string, cause: unknown) {\n super('MODERATION_PARTIAL', `A ação ${action} foi realizada, mas o caso não foi salvo. Não repita a ação.`, { cause });\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/shared/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,WAAY,SAAQ,KAAK;IACR;IAA5B,YAA4B,IAAY,EAAE,OAAe,EAAE,OAAsB;QAC/E,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QADE,SAAI,GAAJ,IAAI,CAAQ;QAEtC,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,WAAW;IACiB;IACzC;IAAgC;IADlD,YAAY,IAAY,EAAE,OAAe,EAAkB,MAAc,EACvD,MAAc,EAAkB,OAAO,UAAU,EAAE,OAAsB;QACzF,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAF2B,WAAM,GAAN,MAAM,CAAQ;QACvD,WAAM,GAAN,MAAM,CAAQ;QAAkB,SAAI,GAAJ,IAAI,CAAa;QAEjE,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;IACD,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,IAAI,MAAM,KAAa,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrH,MAAM;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,OAAO,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,KAAK,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC;IAC7H,CAAC;CACF;AAOD,MAAM,OAAO,UAAW,SAAQ,WAAW;IACI;IAA7C,YAAY,OAAe,EAAkB,SAAsB,SAAS;QAAI,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAA3D,WAAM,GAAN,MAAM,CAAyB;IAA6B,CAAC;CAC3G;AAED,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,GAAG,OAAsB;IACrE,OAAO,KAAK,YAAY,UAAU,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,SAAkB,EAAE,OAAe;IACxD,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AAChD,CAAC;AACD,MAAM,OAAO,aAAc,SAAQ,KAAK;CAAG;AAE3C,MAAM,OAAO,sBAAuB,SAAQ,WAAW;IACzB;IAAgC;IAA5D,YAA4B,MAAc,EAAkB,QAAgB,EAAE,KAAc;QAC1F,KAAK,CAAC,oBAAoB,EAAE,UAAU,MAAM,8DAA8D,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAD7F,WAAM,GAAN,MAAM,CAAQ;QAAkB,aAAQ,GAAR,QAAQ,CAAQ;IAE5E,CAAC;CACF","sourcesContent":["export class YuzuhaError extends Error {\n constructor(public readonly code: string, message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'YuzuhaError';\n }\n}\n\nexport class ScriptError extends YuzuhaError {\n constructor(code: string, message: string, public readonly source: string,\n public readonly offset: number, public readonly file = '<script>', options?: ErrorOptions) {\n super(code, message, options);\n this.name = 'ScriptError';\n }\n get line(): number { return this.source.slice(0, this.offset).split('\\n').length; }\n get column(): number { return this.offset === 0 ? 1 : this.offset - this.source.lastIndexOf('\\n', this.offset - 1); }\n format(): string {\n const line = this.source.split('\\n')[this.line - 1] ?? '';\n return `${this.file}:${this.line}:${this.column} [${this.code}] ${this.message}\\n${line}\\n${' '.repeat(this.column - 1)}^`;\n }\n}\n\nexport type GuardReason = 'GENERIC' | 'NOT_IN_GUILD' | 'NO_AUTHOR' | 'PERMISSION_MISSING_AUTHOR'\n | 'PERMISSION_MISSING_BOT' | 'HIERARCHY' | 'ADMIN_IMMUNE' | 'SELF_TARGET' | 'BOT_TARGET'\n | 'OWNER_TARGET' | 'MEMBER_NOT_FOUND' | 'NOT_BANNED' | 'INVALID_ARGUMENT' | 'INVALID_REASON'\n | 'INVALID_DURATION' | 'COOLDOWN';\n\nexport class GuardError extends YuzuhaError {\n constructor(message: string, public readonly reason: GuardReason = 'GENERIC') { super('GUARD', message); }\n}\n\nexport function isGuardReason(error: unknown, ...reasons: GuardReason[]): error is GuardError {\n return error instanceof GuardError && reasons.includes(error.reason);\n}\n\nexport function assert(condition: unknown, message: string): asserts condition {\n if (!condition) throw new GuardError(message);\n}\nexport class StopExecution extends Error {}\n\nexport class PartialModerationError extends YuzuhaError {\n constructor(public readonly action: string, public readonly targetID: string, cause: unknown) {\n super('MODERATION_PARTIAL', `A ação ${action} foi realizada, mas o caso não foi salvo. Não repita a ação.`, { cause });\n }\n}\n"]}
package/dist/testing.d.ts CHANGED
@@ -56,13 +56,21 @@ export declare class TestClock {
56
56
  export interface TestBotOptions extends Omit<YuzuhaOptions, 'now' | 'transport' | 'resources'> {
57
57
  commands?: readonly Command[];
58
58
  transport?: MockTransport;
59
+ authorization?: 'on' | 'off';
59
60
  resources?: MockResourceOverrides;
60
61
  message?: Partial<IncomingMessage>;
61
62
  now?: number;
62
63
  }
64
+ export interface FakeTimers {
65
+ setTimeout(fn: () => void, ms: number): unknown;
66
+ clearTimeout(handle: unknown): void;
67
+ advance(ms: number): void;
68
+ }
69
+ export declare function fakeTimers(): FakeTimers;
63
70
  export interface TestBot {
64
71
  readonly bot: Yuzuha;
65
72
  readonly transport: MockTransport;
73
+ readonly timers: FakeTimers;
66
74
  readonly store: Store;
67
75
  readonly clock: TestClock;
68
76
  readonly messages: MockTransport['messages'];
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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"}
package/dist/testing.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { PermissionFlags } from '@fluxerjs/core';
2
- import { YuzuhaError } from './errors.js';
2
+ import { GuardError, YuzuhaError } from './errors.js';
3
3
  import { Yuzuha } from './framework/bot.js';
4
4
  import { reportError } from './framework/reporting.js';
5
5
  import { MemoryStore } from './store.js';
@@ -70,7 +70,7 @@ export class MockTransport {
70
70
  async member(guildID, userID) {
71
71
  const member = this.members.get(JSON.stringify([guildID, userID]));
72
72
  if (!member)
73
- throw new YuzuhaError('MEMBER_NOT_FOUND', 'Membro não encontrado.');
73
+ throw new GuardError('Membro não encontrado.', 'MEMBER_NOT_FOUND');
74
74
  return structuredClone(member);
75
75
  }
76
76
  async moderate(guildID, action, targetID, reason, duration, voice) {
@@ -100,6 +100,23 @@ export class TestClock {
100
100
  return this.time;
101
101
  }
102
102
  }
103
+ export function fakeTimers() {
104
+ const pending = new Map();
105
+ let now = 0;
106
+ let seq = 0;
107
+ return {
108
+ setTimeout: (fn, ms) => { const handle = ++seq; pending.set(handle, { fn, at: now + ms }); return handle; },
109
+ clearTimeout: handle => { pending.delete(handle); },
110
+ advance: ms => {
111
+ now += ms;
112
+ for (const [handle, timer] of [...pending])
113
+ if (timer.at <= now) {
114
+ pending.delete(handle);
115
+ timer.fn();
116
+ }
117
+ },
118
+ };
119
+ }
103
120
  /** Creates an offline bot with isolated state, captured output and a manually advanced clock. */
104
121
  export function createTestBot(options = {}) {
105
122
  const { commands = [], transport = new MockTransport(), resources, message, now, onError, ...botOptions } = options;
@@ -107,7 +124,10 @@ export function createTestBot(options = {}) {
107
124
  const store = options.store ?? new MemoryStore();
108
125
  const errors = [], results = [];
109
126
  const defaults = structuredClone(message ?? {});
110
- const bot = new Yuzuha({ ...botOptions, transport, resources: mockResources(resources), store,
127
+ const timers = (options.timers ?? fakeTimers());
128
+ if (botOptions.authorization === 'off')
129
+ botOptions.unsafeDisableResourceAuthorization = true;
130
+ const bot = new Yuzuha({ timers, ...botOptions, transport, resources: mockResources(resources), store,
111
131
  now: clock.now, http: options.http ?? false,
112
132
  onError: async (error, ctx) => { errors.push(error); await onError?.(error, ctx); },
113
133
  });
@@ -126,7 +146,7 @@ export function createTestBot(options = {}) {
126
146
  return bot.destroy();
127
147
  };
128
148
  return {
129
- bot, transport, store, clock, messages: transport.messages, errors, results,
149
+ bot, transport, store, clock, timers, messages: transport.messages, errors, results,
130
150
  async send(content, overrides) {
131
151
  const outcome = await bot.handle(mockMessage(content, { ...defaults, id: String(++messageID), ...overrides }));
132
152
  results.push(outcome);
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ModerationAction, ModerationMember, Payload, Transport } from './contracts.js';\nimport type { Resources } from './ports/resources.js';\nimport { PermissionFlags } from '@fluxerjs/core';\nimport { YuzuhaError } from './errors.js';\nimport type { VoiceModerationOptions } from './domain/moderation.js';\nimport { Yuzuha } from './framework/bot.js';\nimport type { DispatchResult, YuzuhaOptions } from './framework/options.js';\nimport { reportError } from './framework/reporting.js';\nimport type { Command } from './commands/definition.js';\nimport { MemoryStore } from './store.js';\nimport type { Store } from './ports/store.js';\n\n/**\n * Recursos nativos simulados para testes. Áreas não informadas falham ao ser usadas.\n */\nexport type MockResourceOverrides = { [K in keyof Resources]?: Partial<Resources[K]> };\n\nexport function mockResources(overrides: MockResourceOverrides = {}): Resources {\n const resource = <K extends keyof Resources>(area: K): Resources[K] => new Proxy(overrides[area] ?? {}, {\n get(target, property) {\n if (Reflect.has(target, property)) {\n const value = Reflect.get(target, property, target);\n return typeof value === 'function' ? value.bind(target) : value;\n }\n return () => { throw new YuzuhaError('NATIVE_UNAVAILABLE', `Recurso simulado ausente: ${area}.`); };\n },\n }) as Resources[K];\n return {\n users: resource('users'),\n roles: resource('roles'),\n channels: resource('channels'),\n messages: resource('messages'),\n collectors: resource('collectors'),\n webhooks: resource('webhooks'),\n expressions: resource('expressions'),\n threads: resource('threads'),\n invites: resource('invites'),\n gateway: resource('gateway'),\n instance: resource('instance'),\n self: resource('self'),\n cache: resource('cache'),\n };\n}\n\n\nexport class MockTransport implements Transport {\n private messageSequence = 0;\n botID = '999';\n ping = 12;\n readonly messages: { id: string; channelID: string; replyTo?: string; payload: Payload }[] = [];\n readonly actions: ({ guildID: string; action: ModerationAction; targetID: string; reason: string; duration?: number } & VoiceModerationOptions)[] = [];\n readonly members = new Map<string, ModerationMember>();\n readonly reactions: { channelID: string; messageID: string; emoji: string }[] = [];\n failAction = false;\n constructor() {\n this.setMember('100', { id: '1', owner: true, permissions: PermissionFlags.Administrator, rank: 100 });\n this.setMember('100', { id: this.botID, owner: false, permissions: PermissionFlags.Administrator, rank: 90 });\n this.setMember('100', { id: '2', owner: false, permissions: 0n, rank: 1 });\n }\n setMember(guildID: string, member: ModerationMember): void { this.members.set(JSON.stringify([guildID, member.id]), member); }\n async reply(message: IncomingMessage, payload: Payload): Promise<string> {\n const id = await this.send(message.channelID, payload); this.messages.find(item => item.id === id)!.replyTo = message.id; return id;\n }\n async send(channelID: string, payload: Payload): Promise<string> {\n const id = String(++this.messageSequence);\n this.messages.push({ id, channelID, payload: structuredClone(payload) }); return id;\n }\n async edit(channelID: string, messageID: string, payload: Payload): Promise<void> {\n const message = this.messages.find(m => m.id === messageID && m.channelID === channelID);\n if (!message) throw new YuzuhaError('NOT_FOUND', 'Mensagem não encontrada.');\n message.payload = structuredClone(payload);\n }\n async delete(channelID: string, messageID: string): Promise<void> {\n const i = this.messages.findIndex(m => m.id === messageID && m.channelID === channelID);\n if (i < 0) throw new YuzuhaError('NOT_FOUND', 'Mensagem não encontrada.');\n this.messages.splice(i, 1);\n }\n async react(channelID: string, messageID: string, emoji: string): Promise<void> { this.reactions.push({ channelID, messageID, emoji }); }\n async member(guildID: string, userID: string): Promise<ModerationMember> {\n const member = this.members.get(JSON.stringify([guildID, userID]));\n if (!member) throw new YuzuhaError('MEMBER_NOT_FOUND', 'Membro não encontrado.');\n return structuredClone(member);\n }\n async moderate(guildID: string, action: ModerationAction, targetID: string, reason: string, duration?: number, voice?: VoiceModerationOptions): Promise<void> {\n if (this.failAction) throw new YuzuhaError('API_ERROR', 'Falha simulada.');\n this.actions.push({ guildID, action, targetID, reason, duration, ...voice });\n }\n}\nlet sequence = 0;\nexport function mockMessage(content: string, overrides: Partial<IncomingMessage> = {}): IncomingMessage {\n return { id: String(++sequence), content, authorID: '1', authorName: 'Hory', authorBot: false,\n guildID: '100', channelID: '200', mentions: [...content.matchAll(/<@!?(\\d+)>/g)].map(m => m[1]!), ...overrides };\n}\n\nexport class TestClock {\n private time: number;\n\n constructor(now = Date.now()) {\n if (!Number.isSafeInteger(now) || now < 0) throw new YuzuhaError('TEST_CLOCK', 'O relógio exige um instante inteiro não negativo.');\n this.time = now;\n }\n\n readonly now = (): number => this.time;\n\n advance(milliseconds: number): number {\n if (!Number.isSafeInteger(milliseconds) || milliseconds < 0 || !Number.isSafeInteger(this.time + milliseconds)) {\n throw new YuzuhaError('TEST_CLOCK', 'O avanço exige milissegundos inteiros não negativos dentro do intervalo seguro.');\n }\n this.time += milliseconds;\n return this.time;\n }\n}\n\nexport interface TestBotOptions extends Omit<YuzuhaOptions, 'now' | 'transport' | 'resources'> {\n commands?: readonly Command[];\n transport?: MockTransport;\n resources?: MockResourceOverrides;\n message?: Partial<IncomingMessage>;\n now?: number;\n}\n\nexport interface TestBot {\n readonly bot: Yuzuha;\n readonly transport: MockTransport;\n readonly store: Store;\n readonly clock: TestClock;\n readonly messages: MockTransport['messages'];\n readonly errors: unknown[];\n readonly results: DispatchResult[];\n send(content: string, overrides?: Partial<IncomingMessage>): Promise<DispatchResult>;\n /** Advances the clock and awaits one scheduler pass, including scheduled handlers. */\n tick(milliseconds?: number): Promise<void>;\n destroy(): Promise<void>;\n close(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Creates an offline bot with isolated state, captured output and a manually advanced clock. */\nexport function createTestBot(options: TestBotOptions = {}): TestBot {\n const { commands = [], transport = new MockTransport(), resources, message, now,\n onError, ...botOptions } = options;\n const clock = new TestClock(now);\n const store = options.store ?? new MemoryStore();\n const errors: unknown[] = [], results: DispatchResult[] = [];\n const defaults = structuredClone(message ?? {});\n const bot = new Yuzuha({ ...botOptions, transport, resources: mockResources(resources), store,\n now: clock.now, http: options.http ?? false,\n onError: async (error, ctx) => { errors.push(error); await onError?.(error, ctx); },\n });\n try { for (const command of commands) bot.command(command); }\n catch (error) {\n void bot.destroy().catch(failure => reportError(bot.options, failure));\n throw error;\n }\n let messageID = 0;\n let closing = false;\n const destroy = (): Promise<void> => {\n closing = true;\n return bot.destroy();\n };\n return {\n bot, transport, store, clock, messages: transport.messages, errors, results,\n async send(content, overrides) {\n const outcome = await bot.handle(mockMessage(content, { ...defaults, id: String(++messageID), ...overrides }));\n results.push(outcome);\n return outcome;\n },\n async tick(milliseconds = 0) {\n if (closing || bot.signal.aborted) throw new YuzuhaError('BOT_CLOSED', 'O bot está encerrado.');\n clock.advance(milliseconds);\n await bot.scheduler?.tick();\n },\n destroy, close: destroy, [Symbol.asyncDispose]: destroy,\n };\n}\nexport { MockMusicBackend, mockTrack } from './testing/music.js';\n"]}
1
+ {"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage, ModerationAction, ModerationMember, Payload, Transport } from './contracts.js';\nimport type { Resources } from './ports/resources.js';\nimport { PermissionFlags } from '@fluxerjs/core';\nimport { GuardError, YuzuhaError } from './errors.js';\nimport type { VoiceModerationOptions } from './domain/moderation.js';\nimport { Yuzuha } from './framework/bot.js';\nimport type { DispatchResult, YuzuhaOptions } from './framework/options.js';\nimport { reportError } from './framework/reporting.js';\nimport type { Command } from './commands/definition.js';\nimport { MemoryStore } from './store.js';\nimport type { Store } from './ports/store.js';\n\n/**\n * Recursos nativos simulados para testes. Áreas não informadas falham ao ser usadas.\n */\nexport type MockResourceOverrides = { [K in keyof Resources]?: Partial<Resources[K]> };\n\nexport function mockResources(overrides: MockResourceOverrides = {}): Resources {\n const resource = <K extends keyof Resources>(area: K): Resources[K] => new Proxy(overrides[area] ?? {}, {\n get(target, property) {\n if (Reflect.has(target, property)) {\n const value = Reflect.get(target, property, target);\n return typeof value === 'function' ? value.bind(target) : value;\n }\n return () => { throw new YuzuhaError('NATIVE_UNAVAILABLE', `Recurso simulado ausente: ${area}.`); };\n },\n }) as Resources[K];\n return {\n users: resource('users'),\n roles: resource('roles'),\n channels: resource('channels'),\n messages: resource('messages'),\n collectors: resource('collectors'),\n webhooks: resource('webhooks'),\n expressions: resource('expressions'),\n threads: resource('threads'),\n invites: resource('invites'),\n gateway: resource('gateway'),\n instance: resource('instance'),\n self: resource('self'),\n cache: resource('cache'),\n };\n}\n\n\nexport class MockTransport implements Transport {\n private messageSequence = 0;\n botID = '999';\n ping = 12;\n readonly messages: { id: string; channelID: string; replyTo?: string; payload: Payload }[] = [];\n readonly actions: ({ guildID: string; action: ModerationAction; targetID: string; reason: string; duration?: number } & VoiceModerationOptions)[] = [];\n readonly members = new Map<string, ModerationMember>();\n readonly reactions: { channelID: string; messageID: string; emoji: string }[] = [];\n failAction = false;\n constructor() {\n this.setMember('100', { id: '1', owner: true, permissions: PermissionFlags.Administrator, rank: 100 });\n this.setMember('100', { id: this.botID, owner: false, permissions: PermissionFlags.Administrator, rank: 90 });\n this.setMember('100', { id: '2', owner: false, permissions: 0n, rank: 1 });\n }\n setMember(guildID: string, member: ModerationMember): void { this.members.set(JSON.stringify([guildID, member.id]), member); }\n async reply(message: IncomingMessage, payload: Payload): Promise<string> {\n const id = await this.send(message.channelID, payload); this.messages.find(item => item.id === id)!.replyTo = message.id; return id;\n }\n async send(channelID: string, payload: Payload): Promise<string> {\n const id = String(++this.messageSequence);\n this.messages.push({ id, channelID, payload: structuredClone(payload) }); return id;\n }\n async edit(channelID: string, messageID: string, payload: Payload): Promise<void> {\n const message = this.messages.find(m => m.id === messageID && m.channelID === channelID);\n if (!message) throw new YuzuhaError('NOT_FOUND', 'Mensagem não encontrada.');\n message.payload = structuredClone(payload);\n }\n async delete(channelID: string, messageID: string): Promise<void> {\n const i = this.messages.findIndex(m => m.id === messageID && m.channelID === channelID);\n if (i < 0) throw new YuzuhaError('NOT_FOUND', 'Mensagem não encontrada.');\n this.messages.splice(i, 1);\n }\n async react(channelID: string, messageID: string, emoji: string): Promise<void> { this.reactions.push({ channelID, messageID, emoji }); }\n async member(guildID: string, userID: string): Promise<ModerationMember> {\n const member = this.members.get(JSON.stringify([guildID, userID]));\n if (!member) throw new GuardError('Membro não encontrado.', 'MEMBER_NOT_FOUND');\n return structuredClone(member);\n }\n async moderate(guildID: string, action: ModerationAction, targetID: string, reason: string, duration?: number, voice?: VoiceModerationOptions): Promise<void> {\n if (this.failAction) throw new YuzuhaError('API_ERROR', 'Falha simulada.');\n this.actions.push({ guildID, action, targetID, reason, duration, ...voice });\n }\n}\nlet sequence = 0;\nexport function mockMessage(content: string, overrides: Partial<IncomingMessage> = {}): IncomingMessage {\n return { id: String(++sequence), content, authorID: '1', authorName: 'Hory', authorBot: false,\n guildID: '100', channelID: '200', mentions: [...content.matchAll(/<@!?(\\d+)>/g)].map(m => m[1]!), ...overrides };\n}\n\nexport class TestClock {\n private time: number;\n\n constructor(now = Date.now()) {\n if (!Number.isSafeInteger(now) || now < 0) throw new YuzuhaError('TEST_CLOCK', 'O relógio exige um instante inteiro não negativo.');\n this.time = now;\n }\n\n readonly now = (): number => this.time;\n\n advance(milliseconds: number): number {\n if (!Number.isSafeInteger(milliseconds) || milliseconds < 0 || !Number.isSafeInteger(this.time + milliseconds)) {\n throw new YuzuhaError('TEST_CLOCK', 'O avanço exige milissegundos inteiros não negativos dentro do intervalo seguro.');\n }\n this.time += milliseconds;\n return this.time;\n }\n}\n\nexport interface TestBotOptions extends Omit<YuzuhaOptions, 'now' | 'transport' | 'resources'> {\n commands?: readonly Command[];\n transport?: MockTransport;\n authorization?: 'on' | 'off';\n resources?: MockResourceOverrides;\n message?: Partial<IncomingMessage>;\n now?: number;\n}\n\nexport interface FakeTimers {\n setTimeout(fn: () => void, ms: number): unknown;\n clearTimeout(handle: unknown): void;\n advance(ms: number): void;\n}\n\nexport function fakeTimers(): FakeTimers {\n const pending = new Map<unknown, { fn: () => void; at: number }>();\n let now = 0;\n let seq = 0;\n return {\n setTimeout: (fn, ms) => { const handle = ++seq; pending.set(handle, { fn, at: now + ms }); return handle; },\n clearTimeout: handle => { pending.delete(handle); },\n advance: ms => {\n now += ms;\n for (const [handle, timer] of [...pending]) if (timer.at <= now) { pending.delete(handle); timer.fn(); }\n },\n };\n}\n\nexport interface TestBot {\n readonly bot: Yuzuha;\n readonly transport: MockTransport;\n readonly timers: FakeTimers;\n readonly store: Store;\n readonly clock: TestClock;\n readonly messages: MockTransport['messages'];\n readonly errors: unknown[];\n readonly results: DispatchResult[];\n send(content: string, overrides?: Partial<IncomingMessage>): Promise<DispatchResult>;\n /** Advances the clock and awaits one scheduler pass, including scheduled handlers. */\n tick(milliseconds?: number): Promise<void>;\n destroy(): Promise<void>;\n close(): Promise<void>;\n [Symbol.asyncDispose](): Promise<void>;\n}\n\n/** Creates an offline bot with isolated state, captured output and a manually advanced clock. */\nexport function createTestBot(options: TestBotOptions = {}): TestBot {\n const { commands = [], transport = new MockTransport(), resources, message, now,\n onError, ...botOptions } = options;\n const clock = new TestClock(now);\n const store = options.store ?? new MemoryStore();\n const errors: unknown[] = [], results: DispatchResult[] = [];\n const defaults = structuredClone(message ?? {});\n const timers = (options.timers ?? fakeTimers()) as FakeTimers;\n if (botOptions.authorization === 'off') (botOptions as { unsafeDisableResourceAuthorization?: boolean }).unsafeDisableResourceAuthorization = true;\n const bot = new Yuzuha({ timers, ...botOptions, transport, resources: mockResources(resources), store,\n now: clock.now, http: options.http ?? false,\n onError: async (error, ctx) => { errors.push(error); await onError?.(error, ctx); },\n });\n try { for (const command of commands) bot.command(command); }\n catch (error) {\n void bot.destroy().catch(failure => reportError(bot.options, failure));\n throw error;\n }\n let messageID = 0;\n let closing = false;\n const destroy = (): Promise<void> => {\n closing = true;\n return bot.destroy();\n };\n return {\n bot, transport, store, clock, timers, messages: transport.messages, errors, results,\n async send(content, overrides) {\n const outcome = await bot.handle(mockMessage(content, { ...defaults, id: String(++messageID), ...overrides }));\n results.push(outcome);\n return outcome;\n },\n async tick(milliseconds = 0) {\n if (closing || bot.signal.aborted) throw new YuzuhaError('BOT_CLOSED', 'O bot está encerrado.');\n clock.advance(milliseconds);\n await bot.scheduler?.tick();\n },\n destroy, close: destroy, [Symbol.asyncDispose]: destroy,\n };\n}\nexport { MockMusicBackend, mockTrack } from './testing/music.js';\n"]}
package/docs/API.md CHANGED
@@ -362,3 +362,14 @@ Para compor cartões, consulte [CANVAS.md](CANVAS.md) e os subpaths opcionais
362
362
  `yuzuha/images` exporta `transformImage`, `ImageTransform`, `ImageOptions` e
363
363
  `ImageResult`. A raiz não importa Sharp. Não há funções de imagem registradas
364
364
  implicitamente no function mode.
365
+
366
+
367
+ ## Resolvers e motivos
368
+
369
+ `cleanReason(texto, { maxLength? })` limpa menções e trunca (512 por
370
+ padrão). `cdn`/`ctx.cdn` monta URLs do CDN (`avatar`, `banner`,
371
+ `guildIcon`, `memberBanner`, `emoji`, `sticker`, `asset(url, { size,
372
+ format })`); `users.bannerURL(userID, guildID?)` resolve o banner pelo
373
+ perfil. A base é configurável por `YuzuhaOptions.cdn.mediaBase`. `ctx.members.resolve`/`resolveUser`/`resolveBan` resolvem texto
374
+ livre em alvos com `status` `found`/`ambiguous`/`missing`; veja
375
+ docs/NATIVE.md para a forma do resultado.
package/docs/CANVAS.md CHANGED
@@ -13,7 +13,7 @@ quiser transformá-la com Sharp.
13
13
  O backend é um peer opcional. Instale-o somente nos bots que renderizam Canvas:
14
14
 
15
15
  ```sh
16
- npm install yuzuha@0.3.0 @napi-rs/canvas@^1.0.13
16
+ npm install yuzuha@0.3.1 @napi-rs/canvas@^1.0.13
17
17
  ```
18
18
 
19
19
  Os imports `yuzuha`, `yuzuha/functions` e `yuzuha/canvas/card` continuam
package/docs/FRAMEWORK.md CHANGED
@@ -219,3 +219,16 @@ await bot.destroy();
219
219
 
220
220
  O mock usa IDs `1` para autor/dono, `2` para alvo, `999` para bot, `100` para
221
221
  servidor e `200` para canal. Configure outros membros com `setMember`.
222
+
223
+
224
+ ## Emojis personalizados
225
+
226
+ Não feche sobre valores de emoji capturados no load do módulo: comandos
227
+ são reimportados por `reload(dir)`, e o cache de emojis do SDK muda em
228
+ runtime. Resolva em tempo de chamada — por exemplo um getter de módulo
229
+ que lê `bot.client.guilds` → `guild.emojis` quando o comando executa.
230
+
231
+ ```ts
232
+ const emoji = (guildID: string, name: string) =>
233
+ [...bot.client.guilds.resolve(guildID).emojis.values()].find(e => e.name === name);
234
+ ```
package/docs/IMAGES.md CHANGED
@@ -108,3 +108,12 @@ refere-se à leitura, não ao upload do SDK. Depois de iniciar o envio, o métod
108
108
  aguarda a confirmação ou falha do transporte; não devolve cancelamento como se
109
109
  uma mensagem já enviada pudesse ser desfeita. `ATTACHMENT_TIMEOUT` identifica
110
110
  prazo de leitura e `EXECUTION_LIMIT` identifica bytes/chunks excessivos.
111
+
112
+
113
+ ## URLs do CDN
114
+
115
+ `cdn`/`ctx.cdn` (`avatar`, `banner`, `guildIcon`, `guildBanner`,
116
+ `guildSplash`, `memberAvatar`, `memberBanner`, `emoji`, `sticker`,
117
+ `asset(url, { size?, format? })`) monta URLs sem depender do cliente;
118
+ hashes `a_*` produzem `.gif`. `users.bannerURL` resolve o banner pelo
119
+ endpoint de perfil. Base configurável por `YuzuhaOptions.cdn.mediaBase`.