@erinjs/core 1.0.0
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/core/.changeset/README.md +8 -0
- package/core/.changeset/community-bootstrap-release.md +17 -0
- package/core/.changeset/config.json +11 -0
- package/core/.changeset/no-changelog.js +16 -0
- package/core/.changeset/pre.json +17 -0
- package/core/.editorconfig +13 -0
- package/core/.gitattributes +2 -0
- package/core/.github/CODE_OF_CONDUCT.md +23 -0
- package/core/.github/FUNDING.yml +7 -0
- package/core/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- package/core/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- package/core/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- package/core/.github/dependabot.yml +16 -0
- package/core/.github/workflows/autoapp.yml +16 -0
- package/core/.github/workflows/ci.yml +187 -0
- package/core/.github/workflows/codeql.yml +30 -0
- package/core/.github/workflows/deploy-docs.yml +54 -0
- package/core/.github/workflows/publish.yml +43 -0
- package/core/.lintstagedrc.json +4 -0
- package/core/.nvmrc +1 -0
- package/core/.prettierignore +8 -0
- package/core/.prettierrc +11 -0
- package/core/CONTRIBUTING.md +70 -0
- package/core/LICENSE +203 -0
- package/core/README.md +61 -0
- package/core/SECURITY.md +21 -0
- package/core/apps/docs/index.html +28 -0
- package/core/apps/docs/middleware.ts +21 -0
- package/core/apps/docs/package.json +33 -0
- package/core/apps/docs/public/@flux.png +0 -0
- package/core/apps/docs/public/docs/latest/guides.json +1420 -0
- package/core/apps/docs/public/docs/latest/main.json +14981 -0
- package/core/apps/docs/public/docs/latest/rag-index.json +1 -0
- package/core/apps/docs/public/docs/v1.0.5/guides.json +226 -0
- package/core/apps/docs/public/docs/v1.0.5/main.json +7920 -0
- package/core/apps/docs/public/docs/v1.0.6/guides.json +226 -0
- package/core/apps/docs/public/docs/v1.0.6/main.json +7920 -0
- package/core/apps/docs/public/docs/v1.0.7/guides.json +259 -0
- package/core/apps/docs/public/docs/v1.0.7/main.json +8652 -0
- package/core/apps/docs/public/docs/v1.0.8/guides.json +313 -0
- package/core/apps/docs/public/docs/v1.0.8/main.json +9618 -0
- package/core/apps/docs/public/docs/v1.0.9/guides.json +319 -0
- package/core/apps/docs/public/docs/v1.0.9/main.json +10694 -0
- package/core/apps/docs/public/docs/v1.1.0/guides.json +589 -0
- package/core/apps/docs/public/docs/v1.1.0/main.json +12576 -0
- package/core/apps/docs/public/docs/v1.1.2/guides.json +650 -0
- package/core/apps/docs/public/docs/v1.1.2/main.json +13239 -0
- package/core/apps/docs/public/docs/v1.1.3/guides.json +650 -0
- package/core/apps/docs/public/docs/v1.1.3/main.json +13239 -0
- package/core/apps/docs/public/docs/v1.1.4/guides.json +708 -0
- package/core/apps/docs/public/docs/v1.1.4/main.json +13231 -0
- package/core/apps/docs/public/docs/v1.1.5/guides.json +1035 -0
- package/core/apps/docs/public/docs/v1.1.5/main.json +13838 -0
- package/core/apps/docs/public/docs/v1.1.6/guides.json +1041 -0
- package/core/apps/docs/public/docs/v1.1.6/main.json +14313 -0
- package/core/apps/docs/public/docs/v1.1.8/guides.json +1047 -0
- package/core/apps/docs/public/docs/v1.1.8/main.json +14421 -0
- package/core/apps/docs/public/docs/v1.1.9/guides.json +1047 -0
- package/core/apps/docs/public/docs/v1.1.9/main.json +14421 -0
- package/core/apps/docs/public/docs/v1.2.0/guides.json +1212 -0
- package/core/apps/docs/public/docs/v1.2.0/main.json +14663 -0
- package/core/apps/docs/public/docs/v1.2.1/guides.json +1293 -0
- package/core/apps/docs/public/docs/v1.2.1/main.json +14828 -0
- package/core/apps/docs/public/docs/v1.2.2/guides.json +1293 -0
- package/core/apps/docs/public/docs/v1.2.2/main.json +15025 -0
- package/core/apps/docs/public/docs/v1.2.3/guides.json +1420 -0
- package/core/apps/docs/public/docs/v1.2.3/main.json +14954 -0
- package/core/apps/docs/public/docs/v1.2.4/guides.json +1420 -0
- package/core/apps/docs/public/docs/v1.2.4/main.json +14981 -0
- package/core/apps/docs/public/docs/versions.json +24 -0
- package/core/apps/docs/public/flux.png +0 -0
- package/core/apps/docs/public/locales/en.json +50 -0
- package/core/apps/docs/public/locales/guides-en.json +512 -0
- package/core/apps/docs/public/robots.txt +4 -0
- package/core/apps/docs/public/sitemap.xml +33 -0
- package/core/apps/docs/src/App.vue +538 -0
- package/core/apps/docs/src/components/ApiCategorySection.vue +42 -0
- package/core/apps/docs/src/components/ApiDiscordCompat.vue +65 -0
- package/core/apps/docs/src/components/ApiEndpointCard.vue +313 -0
- package/core/apps/docs/src/components/ApiSchemaBlock.vue +131 -0
- package/core/apps/docs/src/components/CodeBlock.vue +177 -0
- package/core/apps/docs/src/components/CommunityCallout.vue +90 -0
- package/core/apps/docs/src/components/ConstructorSection.vue +82 -0
- package/core/apps/docs/src/components/DocDescription.vue +40 -0
- package/core/apps/docs/src/components/FluxerLogo.vue +3 -0
- package/core/apps/docs/src/components/Footer.vue +106 -0
- package/core/apps/docs/src/components/GuideCodeBlock.vue +102 -0
- package/core/apps/docs/src/components/GuideDiscordCompat.vue +77 -0
- package/core/apps/docs/src/components/GuideDiscordCompatCallout.vue +83 -0
- package/core/apps/docs/src/components/GuideTable.vue +77 -0
- package/core/apps/docs/src/components/GuideTip.vue +38 -0
- package/core/apps/docs/src/components/MethodsSection.vue +195 -0
- package/core/apps/docs/src/components/ParamsTable.vue +70 -0
- package/core/apps/docs/src/components/PropertiesSection.vue +143 -0
- package/core/apps/docs/src/components/SearchBar.vue +76 -0
- package/core/apps/docs/src/components/SearchModal.vue +361 -0
- package/core/apps/docs/src/components/SidebarNav.vue +225 -0
- package/core/apps/docs/src/components/SponsorBanner.vue +153 -0
- package/core/apps/docs/src/components/TypeSignature.vue +187 -0
- package/core/apps/docs/src/components/VersionPicker.vue +191 -0
- package/core/apps/docs/src/composables/useSearchIndex.ts +144 -0
- package/core/apps/docs/src/composables/useVersionedPath.ts +20 -0
- package/core/apps/docs/src/data/apiEndpoints.ts +1073 -0
- package/core/apps/docs/src/data/changelog.ts +717 -0
- package/core/apps/docs/src/data/guides.ts +2362 -0
- package/core/apps/docs/src/env.d.ts +7 -0
- package/core/apps/docs/src/locales/guides-en.json +512 -0
- package/core/apps/docs/src/main.ts +27 -0
- package/core/apps/docs/src/pages/ApiReferenceLayout.vue +175 -0
- package/core/apps/docs/src/pages/ApiReferencePage.vue +128 -0
- package/core/apps/docs/src/pages/Changelog.vue +288 -0
- package/core/apps/docs/src/pages/ClassPage.vue +319 -0
- package/core/apps/docs/src/pages/ClassesList.vue +100 -0
- package/core/apps/docs/src/pages/DocsLayout.vue +127 -0
- package/core/apps/docs/src/pages/GuidePage.vue +279 -0
- package/core/apps/docs/src/pages/GuidesIndex.vue +166 -0
- package/core/apps/docs/src/pages/GuidesLayout.vue +245 -0
- package/core/apps/docs/src/pages/Home.vue +125 -0
- package/core/apps/docs/src/pages/NotFound.vue +57 -0
- package/core/apps/docs/src/pages/TypedefPage.vue +230 -0
- package/core/apps/docs/src/pages/TypedefsList.vue +168 -0
- package/core/apps/docs/src/pages/VersionLayout.vue +15 -0
- package/core/apps/docs/src/router.ts +73 -0
- package/core/apps/docs/src/stores/docs.ts +54 -0
- package/core/apps/docs/src/stores/guides.ts +53 -0
- package/core/apps/docs/src/stores/version.ts +67 -0
- package/core/apps/docs/src/styles/main.css +278 -0
- package/core/apps/docs/src/styles/prism.css +95 -0
- package/core/apps/docs/src/types/doc-schema.ts +112 -0
- package/core/apps/docs/tsconfig.json +17 -0
- package/core/apps/docs/tsconfig.node.json +10 -0
- package/core/apps/docs/vite.config.d.ts +2 -0
- package/core/apps/docs/vite.config.js +26 -0
- package/core/apps/docs/vite.config.ts +28 -0
- package/core/apps/docs-vitepress/.vitepress/config.ts +141 -0
- package/core/apps/docs-vitepress/api-data/latest/main.json +15035 -0
- package/core/apps/docs-vitepress/api-data/v1.2.4/main.json +15035 -0
- package/core/apps/docs-vitepress/api-data/versions.json +6 -0
- package/core/apps/docs-vitepress/index.md +15 -0
- package/core/apps/docs-vitepress/package-lock.json +2924 -0
- package/core/apps/docs-vitepress/package.json +20 -0
- package/core/apps/docs-vitepress/public/CNAME +1 -0
- package/core/apps/docs-vitepress/scripts/generate-api.ts +243 -0
- package/core/apps/docs-vitepress/scripts/migrate-guides.ts +129 -0
- package/core/apps/docs-vitepress/tsconfig.json +11 -0
- package/core/apps/docs-vitepress/v/latest/guides/attachments-by-url.md +57 -0
- package/core/apps/docs-vitepress/v/latest/guides/attachments.md +62 -0
- package/core/apps/docs-vitepress/v/latest/guides/basic-bot.md +49 -0
- package/core/apps/docs-vitepress/v/latest/guides/channels.md +180 -0
- package/core/apps/docs-vitepress/v/latest/guides/deprecated-apis.md +58 -0
- package/core/apps/docs-vitepress/v/latest/guides/discord-js-compatibility.md +42 -0
- package/core/apps/docs-vitepress/v/latest/guides/editing-embeds.md +65 -0
- package/core/apps/docs-vitepress/v/latest/guides/embed-media.md +87 -0
- package/core/apps/docs-vitepress/v/latest/guides/embeds.md +166 -0
- package/core/apps/docs-vitepress/v/latest/guides/emojis.md +77 -0
- package/core/apps/docs-vitepress/v/latest/guides/events.md +202 -0
- package/core/apps/docs-vitepress/v/latest/guides/gifs.md +47 -0
- package/core/apps/docs-vitepress/v/latest/guides/installation.md +10 -0
- package/core/apps/docs-vitepress/v/latest/guides/moderation.md +89 -0
- package/core/apps/docs-vitepress/v/latest/guides/permissions.md +130 -0
- package/core/apps/docs-vitepress/v/latest/guides/prefix-commands.md +41 -0
- package/core/apps/docs-vitepress/v/latest/guides/profile-urls.md +58 -0
- package/core/apps/docs-vitepress/v/latest/guides/reactions.md +69 -0
- package/core/apps/docs-vitepress/v/latest/guides/roles.md +130 -0
- package/core/apps/docs-vitepress/v/latest/guides/sending-without-reply.md +172 -0
- package/core/apps/docs-vitepress/v/latest/guides/voice.md +109 -0
- package/core/apps/docs-vitepress/v/latest/guides/wait-for-guilds.md +37 -0
- package/core/apps/docs-vitepress/v/latest/guides/webhook-attachments-embeds.md +73 -0
- package/core/apps/docs-vitepress/v/latest/guides/webhooks.md +131 -0
- package/core/eslint.config.js +80 -0
- package/core/examples/.env.example +22 -0
- package/core/examples/README.md +68 -0
- package/core/examples/first-steps-bot.js +118 -0
- package/core/examples/minimal-bot.js +17 -0
- package/core/examples/moderation-bot.js +209 -0
- package/core/examples/package.json +14 -0
- package/core/examples/ping-bot.js +1146 -0
- package/core/examples/reaction-bot.js +70 -0
- package/core/examples/reaction-roles-bot.js +140 -0
- package/core/examples/webhook-bot.js +239 -0
- package/core/flux.png +0 -0
- package/core/package.json +78 -0
- package/core/packages/builders/package.json +51 -0
- package/core/packages/builders/src/index.ts +13 -0
- package/core/packages/builders/src/messages/AttachmentBuilder.test.ts +79 -0
- package/core/packages/builders/src/messages/AttachmentBuilder.ts +69 -0
- package/core/packages/builders/src/messages/EmbedBuilder.test.ts +266 -0
- package/core/packages/builders/src/messages/EmbedBuilder.ts +239 -0
- package/core/packages/builders/src/messages/MessagePayload.test.ts +118 -0
- package/core/packages/builders/src/messages/MessagePayload.ts +122 -0
- package/core/packages/builders/tsconfig.json +9 -0
- package/core/packages/builders/tsup.config.ts +9 -0
- package/core/packages/builders/vitest.config.ts +9 -0
- package/core/packages/collection/package.json +47 -0
- package/core/packages/collection/src/Collection.test.ts +232 -0
- package/core/packages/collection/src/Collection.ts +196 -0
- package/core/packages/collection/src/index.ts +1 -0
- package/core/packages/collection/tsconfig.json +9 -0
- package/core/packages/collection/tsup.config.ts +9 -0
- package/core/packages/collection/vitest.config.ts +9 -0
- package/core/packages/docgen/package.json +26 -0
- package/core/packages/docgen/src/extract.ts +262 -0
- package/core/packages/docgen/src/formatType.ts +24 -0
- package/core/packages/docgen/src/index.ts +103 -0
- package/core/packages/docgen/src/schema.ts +100 -0
- package/core/packages/docgen/src/visitor.ts +147 -0
- package/core/packages/docgen/tsconfig.json +9 -0
- package/core/packages/docgen/tsup.config.ts +9 -0
- package/core/packages/fluxer-core/README.md +26 -0
- package/core/packages/fluxer-core/package.json +60 -0
- package/core/packages/fluxer-core/src/client/ChannelManager.ts +143 -0
- package/core/packages/fluxer-core/src/client/Client.gateway.test.ts +84 -0
- package/core/packages/fluxer-core/src/client/Client.resolveEmoji.test.ts +45 -0
- package/core/packages/fluxer-core/src/client/Client.ts +558 -0
- package/core/packages/fluxer-core/src/client/ClientUser.ts +40 -0
- package/core/packages/fluxer-core/src/client/EventHandlerRegistry.ts +469 -0
- package/core/packages/fluxer-core/src/client/GuildManager.ts +79 -0
- package/core/packages/fluxer-core/src/client/GuildMemberManager.ts +91 -0
- package/core/packages/fluxer-core/src/client/MessageManager.ts +58 -0
- package/core/packages/fluxer-core/src/client/UsersManager.ts +122 -0
- package/core/packages/fluxer-core/src/errors/ErrorCodes.test.ts +19 -0
- package/core/packages/fluxer-core/src/errors/ErrorCodes.ts +12 -0
- package/core/packages/fluxer-core/src/errors/FluxerError.test.ts +32 -0
- package/core/packages/fluxer-core/src/errors/FluxerError.ts +15 -0
- package/core/packages/fluxer-core/src/index.ts +85 -0
- package/core/packages/fluxer-core/src/structures/Base.ts +7 -0
- package/core/packages/fluxer-core/src/structures/Channel.ts +508 -0
- package/core/packages/fluxer-core/src/structures/Guild.test.ts +189 -0
- package/core/packages/fluxer-core/src/structures/Guild.ts +734 -0
- package/core/packages/fluxer-core/src/structures/GuildBan.ts +35 -0
- package/core/packages/fluxer-core/src/structures/GuildEmoji.ts +57 -0
- package/core/packages/fluxer-core/src/structures/GuildMember.test.ts +203 -0
- package/core/packages/fluxer-core/src/structures/GuildMember.ts +213 -0
- package/core/packages/fluxer-core/src/structures/GuildMemberRoleManager.ts +121 -0
- package/core/packages/fluxer-core/src/structures/GuildSticker.ts +56 -0
- package/core/packages/fluxer-core/src/structures/Invite.test.ts +103 -0
- package/core/packages/fluxer-core/src/structures/Invite.ts +121 -0
- package/core/packages/fluxer-core/src/structures/Message.test.ts +109 -0
- package/core/packages/fluxer-core/src/structures/Message.ts +397 -0
- package/core/packages/fluxer-core/src/structures/MessageReaction.ts +72 -0
- package/core/packages/fluxer-core/src/structures/PartialMessage.ts +12 -0
- package/core/packages/fluxer-core/src/structures/Role.test.ts +77 -0
- package/core/packages/fluxer-core/src/structures/Role.ts +112 -0
- package/core/packages/fluxer-core/src/structures/User.test.ts +110 -0
- package/core/packages/fluxer-core/src/structures/User.ts +109 -0
- package/core/packages/fluxer-core/src/structures/Webhook.test.ts +109 -0
- package/core/packages/fluxer-core/src/structures/Webhook.ts +258 -0
- package/core/packages/fluxer-core/src/util/Constants.test.ts +16 -0
- package/core/packages/fluxer-core/src/util/Constants.ts +7 -0
- package/core/packages/fluxer-core/src/util/Events.ts +46 -0
- package/core/packages/fluxer-core/src/util/MessageCollector.ts +87 -0
- package/core/packages/fluxer-core/src/util/Options.ts +33 -0
- package/core/packages/fluxer-core/src/util/ReactionCollector.ts +116 -0
- package/core/packages/fluxer-core/src/util/cdn.test.ts +108 -0
- package/core/packages/fluxer-core/src/util/cdn.ts +130 -0
- package/core/packages/fluxer-core/src/util/guildUtils.ts +33 -0
- package/core/packages/fluxer-core/src/util/messageUtils.test.ts +74 -0
- package/core/packages/fluxer-core/src/util/messageUtils.ts +119 -0
- package/core/packages/fluxer-core/src/util/permissions.test.ts +95 -0
- package/core/packages/fluxer-core/src/util/permissions.ts +43 -0
- package/core/packages/fluxer-core/tsconfig.json +9 -0
- package/core/packages/fluxer-core/tsup.config.ts +9 -0
- package/core/packages/fluxer-core/vitest.config.ts +9 -0
- package/core/packages/rest/package.json +52 -0
- package/core/packages/rest/src/REST.test.ts +64 -0
- package/core/packages/rest/src/REST.ts +90 -0
- package/core/packages/rest/src/RateLimitManager.test.ts +71 -0
- package/core/packages/rest/src/RateLimitManager.ts +60 -0
- package/core/packages/rest/src/RequestManager.test.ts +87 -0
- package/core/packages/rest/src/RequestManager.ts +172 -0
- package/core/packages/rest/src/errors/FluxerAPIError.test.ts +57 -0
- package/core/packages/rest/src/errors/FluxerAPIError.ts +21 -0
- package/core/packages/rest/src/errors/HTTPError.test.ts +55 -0
- package/core/packages/rest/src/errors/HTTPError.ts +25 -0
- package/core/packages/rest/src/errors/RateLimitError.test.ts +41 -0
- package/core/packages/rest/src/errors/RateLimitError.ts +15 -0
- package/core/packages/rest/src/errors/index.ts +3 -0
- package/core/packages/rest/src/index.ts +6 -0
- package/core/packages/rest/src/utils/constants.test.ts +31 -0
- package/core/packages/rest/src/utils/constants.ts +5 -0
- package/core/packages/rest/src/utils/files.test.ts +37 -0
- package/core/packages/rest/src/utils/files.ts +75 -0
- package/core/packages/rest/tsconfig.json +9 -0
- package/core/packages/rest/tsup.config.ts +9 -0
- package/core/packages/rest/vitest.config.ts +9 -0
- package/core/packages/types/package.json +46 -0
- package/core/packages/types/src/api/ban.ts +8 -0
- package/core/packages/types/src/api/channel.ts +65 -0
- package/core/packages/types/src/api/embed.ts +82 -0
- package/core/packages/types/src/api/emoji.ts +12 -0
- package/core/packages/types/src/api/errors.ts +68 -0
- package/core/packages/types/src/api/gateway.ts +14 -0
- package/core/packages/types/src/api/guild.ts +123 -0
- package/core/packages/types/src/api/index.ts +15 -0
- package/core/packages/types/src/api/instance.ts +32 -0
- package/core/packages/types/src/api/interaction.ts +26 -0
- package/core/packages/types/src/api/invite.ts +28 -0
- package/core/packages/types/src/api/message.ts +140 -0
- package/core/packages/types/src/api/role.ts +41 -0
- package/core/packages/types/src/api/sticker.ts +14 -0
- package/core/packages/types/src/api/user.ts +79 -0
- package/core/packages/types/src/api/webhook.ts +41 -0
- package/core/packages/types/src/common/index.ts +1 -0
- package/core/packages/types/src/common/snowflake.test.ts +9 -0
- package/core/packages/types/src/common/snowflake.ts +8 -0
- package/core/packages/types/src/gateway/events.ts +189 -0
- package/core/packages/types/src/gateway/index.ts +3 -0
- package/core/packages/types/src/gateway/opcodes.ts +17 -0
- package/core/packages/types/src/gateway/payloads.ts +481 -0
- package/core/packages/types/src/index.ts +4 -0
- package/core/packages/types/src/rest/index.ts +1 -0
- package/core/packages/types/src/rest/routes.test.ts +169 -0
- package/core/packages/types/src/rest/routes.ts +109 -0
- package/core/packages/types/tsconfig.json +9 -0
- package/core/packages/types/tsup.config.ts +9 -0
- package/core/packages/types/vitest.config.ts +9 -0
- package/core/packages/util/package.json +51 -0
- package/core/packages/util/src/BitField.test.ts +96 -0
- package/core/packages/util/src/BitField.ts +105 -0
- package/core/packages/util/src/MessageFlagsBitField.test.ts +42 -0
- package/core/packages/util/src/MessageFlagsBitField.ts +20 -0
- package/core/packages/util/src/PermissionsBitField.test.ts +79 -0
- package/core/packages/util/src/PermissionsBitField.ts +97 -0
- package/core/packages/util/src/SnowflakeUtil.test.ts +69 -0
- package/core/packages/util/src/SnowflakeUtil.ts +65 -0
- package/core/packages/util/src/UserFlagsBitField.test.ts +39 -0
- package/core/packages/util/src/UserFlagsBitField.ts +48 -0
- package/core/packages/util/src/deprecation.test.ts +44 -0
- package/core/packages/util/src/deprecation.ts +28 -0
- package/core/packages/util/src/emojiShortcodes.generated.ts +5 -0
- package/core/packages/util/src/emojiShortcodes.test.ts +41 -0
- package/core/packages/util/src/emojiShortcodes.ts +22 -0
- package/core/packages/util/src/formatters.test.ts +65 -0
- package/core/packages/util/src/formatters.ts +35 -0
- package/core/packages/util/src/index.ts +34 -0
- package/core/packages/util/src/resolvers.test.ts +198 -0
- package/core/packages/util/src/resolvers.ts +127 -0
- package/core/packages/util/src/tenorUtils.test.ts +75 -0
- package/core/packages/util/src/tenorUtils.ts +86 -0
- package/core/packages/util/tsconfig.json +9 -0
- package/core/packages/util/tsup.config.ts +9 -0
- package/core/packages/util/vitest.config.ts +9 -0
- package/core/packages/voice/README.md +42 -0
- package/core/packages/voice/package.json +67 -0
- package/core/packages/voice/src/LiveKitRtcConnection.receive.test.ts +24 -0
- package/core/packages/voice/src/LiveKitRtcConnection.ts +1767 -0
- package/core/packages/voice/src/VoiceConnection.ts +413 -0
- package/core/packages/voice/src/VoiceManager.receive.test.ts +61 -0
- package/core/packages/voice/src/VoiceManager.test.ts +44 -0
- package/core/packages/voice/src/VoiceManager.ts +503 -0
- package/core/packages/voice/src/exports.test.ts +38 -0
- package/core/packages/voice/src/index.ts +51 -0
- package/core/packages/voice/src/livekit.test.ts +48 -0
- package/core/packages/voice/src/livekit.ts +33 -0
- package/core/packages/voice/src/mp4box.d.ts +32 -0
- package/core/packages/voice/src/opusUtils.test.ts +29 -0
- package/core/packages/voice/src/opusUtils.ts +86 -0
- package/core/packages/voice/src/streamPreviewPlaceholder.test.ts +16 -0
- package/core/packages/voice/src/streamPreviewPlaceholder.ts +8 -0
- package/core/packages/voice/src/ws.d.ts +1 -0
- package/core/packages/voice/tsconfig.json +5 -0
- package/core/packages/voice/tsup.config.ts +10 -0
- package/core/packages/voice/vitest.config.ts +9 -0
- package/core/packages/ws/package.json +52 -0
- package/core/packages/ws/src/WebSocketManager.ts +130 -0
- package/core/packages/ws/src/WebSocketShard.ts +296 -0
- package/core/packages/ws/src/index.ts +12 -0
- package/core/packages/ws/src/utils/constants.test.ts +46 -0
- package/core/packages/ws/src/utils/constants.ts +22 -0
- package/core/packages/ws/src/utils/getWebSocket.ts +55 -0
- package/core/packages/ws/src/ws.d.ts +10 -0
- package/core/packages/ws/tsconfig.json +9 -0
- package/core/packages/ws/tsup.config.ts +9 -0
- package/core/pnpm-lock.yaml +7033 -0
- package/core/pnpm-workspace.yaml +4 -0
- package/core/scripts/generate-ai-rag.ts +240 -0
- package/core/scripts/generate-docs.ts +143 -0
- package/core/scripts/generate-emoji-shortcodes.ts +58 -0
- package/core/scripts/generate-types.ts +6 -0
- package/core/scripts/publish-ordered.js +63 -0
- package/core/scripts/test-cjs-require.mjs +43 -0
- package/core/scripts/test-esm-imports.mjs +42 -0
- package/core/scripts/test-package-exports.mjs +98 -0
- package/core/scripts/test-smoke.mjs +103 -0
- package/core/tsconfig.json +18 -0
- package/core/turbo.json +30 -0
- package/core/vitest.config.ts +17 -0
- package/core/wrangler.jsonc +9 -0
- package/package.json +26 -0
|
@@ -0,0 +1,734 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseRoleMention,
|
|
3
|
+
resolvePermissionsToBitfield,
|
|
4
|
+
type PermissionResolvable,
|
|
5
|
+
} from '@erinjs/util';
|
|
6
|
+
import { FluxerAPIError } from '@erinjs/rest';
|
|
7
|
+
import { Client } from '../client/Client.js';
|
|
8
|
+
import { Collection } from '@erinjs/collection';
|
|
9
|
+
import { Base } from './Base.js';
|
|
10
|
+
import { FluxerError } from '../errors/FluxerError.js';
|
|
11
|
+
import { ErrorCodes } from '../errors/ErrorCodes.js';
|
|
12
|
+
import {
|
|
13
|
+
APIGuild,
|
|
14
|
+
APIGuildAuditLog,
|
|
15
|
+
APIGuildMember,
|
|
16
|
+
APIInvite,
|
|
17
|
+
APIRole,
|
|
18
|
+
APIVanityURL,
|
|
19
|
+
RESTCreateRoleBody,
|
|
20
|
+
GuildFeature,
|
|
21
|
+
GuildVerificationLevel,
|
|
22
|
+
GuildMFALevel,
|
|
23
|
+
GuildExplicitContentFilter,
|
|
24
|
+
DefaultMessageNotifications,
|
|
25
|
+
APIBan,
|
|
26
|
+
APIChannel,
|
|
27
|
+
APIEmoji,
|
|
28
|
+
APISticker,
|
|
29
|
+
} from '@erinjs/types';
|
|
30
|
+
import { GuildMemberManager } from '../client/GuildMemberManager.js';
|
|
31
|
+
import { GuildMember } from './GuildMember.js';
|
|
32
|
+
import { Role } from './Role.js';
|
|
33
|
+
import { Channel, GuildChannel } from './Channel.js';
|
|
34
|
+
import { CDN_URL } from '../util/Constants.js';
|
|
35
|
+
import { Routes } from '@erinjs/types';
|
|
36
|
+
import { Webhook } from './Webhook.js';
|
|
37
|
+
import { GuildBan } from './GuildBan.js';
|
|
38
|
+
import { GuildEmoji } from './GuildEmoji';
|
|
39
|
+
import { GuildSticker } from './GuildSticker';
|
|
40
|
+
import { Invite } from './Invite.js';
|
|
41
|
+
|
|
42
|
+
/** Represents a Fluxer guild (server). */
|
|
43
|
+
export class Guild extends Base {
|
|
44
|
+
readonly client: Client;
|
|
45
|
+
readonly id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
icon: string | null;
|
|
48
|
+
banner: string | null;
|
|
49
|
+
readonly ownerId: string;
|
|
50
|
+
/** Invite splash image hash. Null if none. */
|
|
51
|
+
splash: string | null;
|
|
52
|
+
/** Custom vanity URL code (e.g. fluxer.gg/code). Null if none. */
|
|
53
|
+
vanityURLCode: string | null;
|
|
54
|
+
/** Enabled guild features. */
|
|
55
|
+
features: GuildFeature[];
|
|
56
|
+
verificationLevel: GuildVerificationLevel;
|
|
57
|
+
defaultMessageNotifications: DefaultMessageNotifications;
|
|
58
|
+
explicitContentFilter: GuildExplicitContentFilter;
|
|
59
|
+
/** AFK voice channel ID. Null if none. */
|
|
60
|
+
afkChannelId: string | null;
|
|
61
|
+
/** AFK timeout in seconds. */
|
|
62
|
+
afkTimeout: number;
|
|
63
|
+
/** System messages channel ID. Null if none. */
|
|
64
|
+
systemChannelId: string | null;
|
|
65
|
+
/** Rules/guidelines channel ID. Null if none. */
|
|
66
|
+
rulesChannelId: string | null;
|
|
67
|
+
nsfwLevel: number;
|
|
68
|
+
mfaLevel: GuildMFALevel;
|
|
69
|
+
/** Banner image width. Optional. */
|
|
70
|
+
bannerWidth?: number | null;
|
|
71
|
+
/** Banner image height. Optional. */
|
|
72
|
+
bannerHeight?: number | null;
|
|
73
|
+
/** Splash image width. Optional. */
|
|
74
|
+
splashWidth?: number | null;
|
|
75
|
+
/** Splash image height. Optional. */
|
|
76
|
+
splashHeight?: number | null;
|
|
77
|
+
members: GuildMemberManager;
|
|
78
|
+
channels = new Collection<string, GuildChannel>();
|
|
79
|
+
roles = new Collection<string, Role>();
|
|
80
|
+
emojis = new Collection<string, GuildEmoji>();
|
|
81
|
+
stickers = new Collection<string, GuildSticker>();
|
|
82
|
+
|
|
83
|
+
/** @param data - API guild from GET /guilds/{id} or gateway GUILD_CREATE */
|
|
84
|
+
constructor(client: Client, data: APIGuild & { roles?: APIRole[]; ownerId?: string }) {
|
|
85
|
+
super();
|
|
86
|
+
this.client = client;
|
|
87
|
+
this.id = data.id;
|
|
88
|
+
this.members = new GuildMemberManager(this);
|
|
89
|
+
this.name = data.name;
|
|
90
|
+
this.icon = data.icon ?? null;
|
|
91
|
+
this.banner = data.banner ?? null;
|
|
92
|
+
this.ownerId = data.owner_id ?? data.ownerId ?? '';
|
|
93
|
+
this.splash = data.splash ?? null;
|
|
94
|
+
this.vanityURLCode = data.vanity_url_code ?? null;
|
|
95
|
+
this.features = data.features ?? [];
|
|
96
|
+
this.verificationLevel = data.verification_level ?? 0;
|
|
97
|
+
this.defaultMessageNotifications = data.default_message_notifications ?? 0;
|
|
98
|
+
this.explicitContentFilter = data.explicit_content_filter ?? 0;
|
|
99
|
+
this.afkChannelId = data.afk_channel_id ?? null;
|
|
100
|
+
this.afkTimeout = data.afk_timeout ?? 0;
|
|
101
|
+
this.systemChannelId = data.system_channel_id ?? null;
|
|
102
|
+
this.rulesChannelId = data.rules_channel_id ?? null;
|
|
103
|
+
this.nsfwLevel = data.nsfw_level ?? 0;
|
|
104
|
+
this.mfaLevel = data.mfa_level ?? 0;
|
|
105
|
+
this.bannerWidth = data.banner_width ?? null;
|
|
106
|
+
this.bannerHeight = data.banner_height ?? null;
|
|
107
|
+
this.splashWidth = data.splash_width ?? null;
|
|
108
|
+
this.splashHeight = data.splash_height ?? null;
|
|
109
|
+
for (const r of data.roles ?? []) {
|
|
110
|
+
this.roles.set(r.id, new Role(client, r, this.id));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Get the guild icon URL, or null if no icon. */
|
|
115
|
+
iconURL(options?: { size?: number }): string | null {
|
|
116
|
+
if (!this.icon) return null;
|
|
117
|
+
const size = options?.size ? `?size=${options.size}` : '';
|
|
118
|
+
return `${CDN_URL}/icons/${this.id}/${this.icon}.png${size}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Get the guild banner URL, or null if no banner. */
|
|
122
|
+
bannerURL(options?: { size?: number }): string | null {
|
|
123
|
+
if (!this.banner) return null;
|
|
124
|
+
const size = options?.size ? `?size=${options.size}` : '';
|
|
125
|
+
return `${CDN_URL}/banners/${this.id}/${this.banner}.png${size}`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Get the guild splash (invite background) URL, or null if no splash. */
|
|
129
|
+
splashURL(options?: { size?: number }): string | null {
|
|
130
|
+
if (!this.splash) return null;
|
|
131
|
+
const size = options?.size ? `?size=${options.size}` : '';
|
|
132
|
+
return `${CDN_URL}/splashes/${this.id}/${this.splash}.png${size}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Add a role to a member by user ID. Does not require fetching the member first.
|
|
137
|
+
* @param userId - The user ID of the member
|
|
138
|
+
* @param roleId - The role ID to add (or use guild.resolveRoleId for mention/name resolution)
|
|
139
|
+
* Requires Manage Roles permission.
|
|
140
|
+
*/
|
|
141
|
+
async addRoleToMember(userId: string, roleId: string): Promise<void> {
|
|
142
|
+
await this.client.rest.put(Routes.guildMemberRole(this.id, userId, roleId));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Remove a role from a member by user ID. Does not require fetching the member first.
|
|
147
|
+
* @param userId - The user ID of the member
|
|
148
|
+
* @param roleId - The role ID to remove
|
|
149
|
+
* Requires Manage Roles permission.
|
|
150
|
+
*/
|
|
151
|
+
async removeRoleFromMember(userId: string, roleId: string): Promise<void> {
|
|
152
|
+
await this.client.rest.delete(Routes.guildMemberRole(this.id, userId, roleId));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Create a role in this guild.
|
|
157
|
+
* Requires Manage Roles permission.
|
|
158
|
+
* @param options - Role data (permissions accepts PermissionResolvable for convenience)
|
|
159
|
+
* @returns The created role
|
|
160
|
+
* @example
|
|
161
|
+
* const role = await guild.createRole({ name: 'Mod', permissions: ['KickMembers', 'BanMembers'] });
|
|
162
|
+
*/
|
|
163
|
+
async createRole(
|
|
164
|
+
options: RESTCreateRoleBody & { permissions?: string | PermissionResolvable },
|
|
165
|
+
): Promise<Role> {
|
|
166
|
+
const body: Record<string, unknown> = {};
|
|
167
|
+
if (options.name !== undefined) body.name = options.name;
|
|
168
|
+
if (options.permissions !== undefined) {
|
|
169
|
+
body.permissions =
|
|
170
|
+
typeof options.permissions === 'string'
|
|
171
|
+
? options.permissions
|
|
172
|
+
: resolvePermissionsToBitfield(options.permissions);
|
|
173
|
+
}
|
|
174
|
+
if (options.color !== undefined) body.color = options.color;
|
|
175
|
+
if (options.hoist !== undefined) body.hoist = options.hoist;
|
|
176
|
+
if (options.mentionable !== undefined) body.mentionable = options.mentionable;
|
|
177
|
+
if (options.unicode_emoji !== undefined) body.unicode_emoji = options.unicode_emoji;
|
|
178
|
+
if (options.position !== undefined) body.position = options.position;
|
|
179
|
+
if (options.hoist_position !== undefined) body.hoist_position = options.hoist_position;
|
|
180
|
+
const data = await this.client.rest.post<APIRole>(Routes.guildRoles(this.id), {
|
|
181
|
+
body: Object.keys(body).length ? body : undefined,
|
|
182
|
+
auth: true,
|
|
183
|
+
});
|
|
184
|
+
const role = new Role(this.client, data, this.id);
|
|
185
|
+
this.roles.set(role.id, role);
|
|
186
|
+
return role;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Fetch all roles in this guild.
|
|
191
|
+
* @returns Array of Role objects (cached in guild.roles)
|
|
192
|
+
*/
|
|
193
|
+
async fetchRoles(): Promise<Role[]> {
|
|
194
|
+
const data = await this.client.rest.get<APIRole[] | Record<string, APIRole>>(
|
|
195
|
+
Routes.guildRoles(this.id),
|
|
196
|
+
);
|
|
197
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
198
|
+
const roles: Role[] = [];
|
|
199
|
+
for (const r of list) {
|
|
200
|
+
const role = new Role(this.client, r, this.id);
|
|
201
|
+
this.roles.set(role.id, role);
|
|
202
|
+
roles.push(role);
|
|
203
|
+
}
|
|
204
|
+
return roles;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Fetch a role by ID.
|
|
209
|
+
* @param roleId - The role ID to fetch
|
|
210
|
+
* @returns The role
|
|
211
|
+
* @throws FluxerError with ROLE_NOT_FOUND if role does not exist (404)
|
|
212
|
+
*/
|
|
213
|
+
async fetchRole(roleId: string): Promise<Role> {
|
|
214
|
+
try {
|
|
215
|
+
const data = await this.client.rest.get<APIRole>(Routes.guildRole(this.id, roleId));
|
|
216
|
+
const role = new Role(this.client, data, this.id);
|
|
217
|
+
this.roles.set(role.id, role);
|
|
218
|
+
return role;
|
|
219
|
+
} catch (err) {
|
|
220
|
+
const statusCode =
|
|
221
|
+
err instanceof FluxerAPIError
|
|
222
|
+
? err.statusCode
|
|
223
|
+
: (err as { statusCode?: number })?.statusCode;
|
|
224
|
+
if (statusCode === 404) {
|
|
225
|
+
throw new FluxerError(`Role ${roleId} not found in guild`, {
|
|
226
|
+
code: ErrorCodes.RoleNotFound,
|
|
227
|
+
cause: err as Error,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
throw err instanceof FluxerError
|
|
231
|
+
? err
|
|
232
|
+
: new FluxerError('Failed to fetch guild role', { cause: err as Error });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Resolve a role ID from an argument (role mention, raw ID, or name).
|
|
238
|
+
* Fetches guild roles if name is provided.
|
|
239
|
+
* @param arg - Role mention (@role), role ID, or role name
|
|
240
|
+
* @returns The role ID, or null if not found
|
|
241
|
+
*/
|
|
242
|
+
async resolveRoleId(arg: string): Promise<string | null> {
|
|
243
|
+
const parsed = parseRoleMention(arg);
|
|
244
|
+
if (parsed) return parsed;
|
|
245
|
+
if (/^\d{17,19}$/.test(arg.trim())) return arg.trim();
|
|
246
|
+
const cached = this.roles.find(
|
|
247
|
+
(r) => !!(r.name && r.name.toLowerCase() === arg.trim().toLowerCase()),
|
|
248
|
+
);
|
|
249
|
+
if (cached) return cached.id;
|
|
250
|
+
const roles = await this.client.rest.get(Routes.guildRoles(this.id));
|
|
251
|
+
const list = (Array.isArray(roles) ? roles : Object.values(roles ?? {})) as Array<APIRole>;
|
|
252
|
+
const role = list.find((r) => !!(r.name && r.name.toLowerCase() === arg.trim().toLowerCase()));
|
|
253
|
+
if (role) {
|
|
254
|
+
this.roles.set(role.id, new Role(this.client, role, this.id));
|
|
255
|
+
return role.id;
|
|
256
|
+
}
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Ban a user from this guild.
|
|
262
|
+
* @param userId - The user ID to ban
|
|
263
|
+
* @param options - Optional reason, delete_message_days (0–7), and ban_duration_seconds (temporary ban).
|
|
264
|
+
* ban_duration_seconds: 0 = permanent, or use 3600, 43200, 86400, 259200, 432000, 604800, 1209600, 2592000.
|
|
265
|
+
* Requires Ban Members permission.
|
|
266
|
+
*/
|
|
267
|
+
async ban(
|
|
268
|
+
userId: string,
|
|
269
|
+
options?: { reason?: string; delete_message_days?: number; ban_duration_seconds?: number },
|
|
270
|
+
): Promise<void> {
|
|
271
|
+
const body: Record<string, unknown> = {};
|
|
272
|
+
if (options?.reason) body.reason = options.reason;
|
|
273
|
+
if (options?.delete_message_days != null)
|
|
274
|
+
body.delete_message_days = options.delete_message_days;
|
|
275
|
+
if (options?.ban_duration_seconds != null)
|
|
276
|
+
body.ban_duration_seconds = options.ban_duration_seconds;
|
|
277
|
+
await this.client.rest.put(Routes.guildBan(this.id, userId), {
|
|
278
|
+
body: Object.keys(body).length ? body : undefined,
|
|
279
|
+
auth: true,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Fetch guild bans. Requires Ban Members permission.
|
|
285
|
+
* @returns List of GuildBan objects
|
|
286
|
+
*/
|
|
287
|
+
async fetchBans(): Promise<GuildBan[]> {
|
|
288
|
+
const data = await this.client.rest.get<APIBan[] | { bans?: APIBan[] }>(
|
|
289
|
+
Routes.guildBans(this.id),
|
|
290
|
+
);
|
|
291
|
+
const list = Array.isArray(data) ? data : (data?.bans ?? []);
|
|
292
|
+
return list.map((b) => new GuildBan(this.client, { ...b, guild_id: this.id }, this.id));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Remove a ban (unban a user).
|
|
297
|
+
* @param userId - The user ID to unban
|
|
298
|
+
* Requires Ban Members permission.
|
|
299
|
+
*/
|
|
300
|
+
async unban(userId: string): Promise<void> {
|
|
301
|
+
await this.client.rest.delete(Routes.guildBan(this.id, userId), { auth: true });
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Kick a member from this guild.
|
|
306
|
+
* @param userId - The user ID to kick
|
|
307
|
+
* Requires Kick Members permission.
|
|
308
|
+
*/
|
|
309
|
+
async kick(userId: string): Promise<void> {
|
|
310
|
+
await this.client.rest.delete(Routes.guildMember(this.id, userId), { auth: true });
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Fetch a guild member by user ID.
|
|
315
|
+
* @param userId - The user ID of the member to fetch
|
|
316
|
+
* @returns The guild member
|
|
317
|
+
* @throws FluxerError with MEMBER_NOT_FOUND if user is not in the guild (404)
|
|
318
|
+
* @throws FluxerError with cause for permission denied (403) or other REST errors
|
|
319
|
+
*/
|
|
320
|
+
async fetchMember(userId: string): Promise<GuildMember> {
|
|
321
|
+
try {
|
|
322
|
+
const data = await this.client.rest.get<APIGuildMember & { user: { id: string } }>(
|
|
323
|
+
Routes.guildMember(this.id, userId),
|
|
324
|
+
);
|
|
325
|
+
const member = new GuildMember(this.client, { ...data, guild_id: this.id }, this);
|
|
326
|
+
this.members.set(member.id, member);
|
|
327
|
+
return member;
|
|
328
|
+
} catch (err) {
|
|
329
|
+
const statusCode =
|
|
330
|
+
err instanceof FluxerAPIError
|
|
331
|
+
? err.statusCode
|
|
332
|
+
: (err as { statusCode?: number })?.statusCode;
|
|
333
|
+
if (statusCode === 404) {
|
|
334
|
+
throw new FluxerError(`Member ${userId} not found in guild`, {
|
|
335
|
+
code: ErrorCodes.MemberNotFound,
|
|
336
|
+
cause: err as Error,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
throw err instanceof FluxerError
|
|
340
|
+
? err
|
|
341
|
+
: new FluxerError('Failed to fetch guild member', { cause: err as Error });
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Fetch guild audit logs. Requires View Audit Log permission.
|
|
347
|
+
* @param options - Optional limit, before, after, user_id, action_type for filtering
|
|
348
|
+
*/
|
|
349
|
+
async fetchAuditLogs(options?: {
|
|
350
|
+
limit?: number;
|
|
351
|
+
before?: string;
|
|
352
|
+
after?: string;
|
|
353
|
+
userId?: string;
|
|
354
|
+
actionType?: number;
|
|
355
|
+
}): Promise<APIGuildAuditLog> {
|
|
356
|
+
const params = new URLSearchParams();
|
|
357
|
+
if (options?.limit != null) params.set('limit', String(options.limit));
|
|
358
|
+
if (options?.before) params.set('before', options.before);
|
|
359
|
+
if (options?.after) params.set('after', options.after);
|
|
360
|
+
if (options?.userId) params.set('user_id', options.userId);
|
|
361
|
+
if (options?.actionType != null) params.set('action_type', String(options.actionType));
|
|
362
|
+
const qs = params.toString();
|
|
363
|
+
const url = Routes.guildAuditLogs(this.id) + (qs ? `?${qs}` : '');
|
|
364
|
+
return this.client.rest.get(url) as Promise<APIGuildAuditLog>;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Fetch all webhooks in this guild. Returned webhooks do not include the token (cannot send). */
|
|
368
|
+
async fetchWebhooks(): Promise<Webhook[]> {
|
|
369
|
+
const data = await this.client.rest.get(Routes.guildWebhooks(this.id));
|
|
370
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
371
|
+
return list.map((w) => new Webhook(this.client, w));
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Fetch all invites in this guild.
|
|
376
|
+
* Requires Manage Guild permission.
|
|
377
|
+
*/
|
|
378
|
+
async fetchInvites(): Promise<Invite[]> {
|
|
379
|
+
const data = await this.client.rest.get<APIInvite[] | Record<string, APIInvite>>(
|
|
380
|
+
Routes.guildInvites(this.id),
|
|
381
|
+
);
|
|
382
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
383
|
+
return list.map((invite) => new Invite(this.client, invite));
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Fetch a guild invite by code or URL.
|
|
388
|
+
* Convenience wrapper for Invite.fetch(client, codeOrUrl).
|
|
389
|
+
*/
|
|
390
|
+
async fetchInvite(codeOrUrl: string): Promise<Invite> {
|
|
391
|
+
return Invite.fetch(this.client, codeOrUrl);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Create a channel in this guild.
|
|
396
|
+
* @param data - Channel data: type (0=text, 2=voice, 4=category, 5=link), name, and optional parent_id, topic, bitrate, user_limit, nsfw, permission_overwrites
|
|
397
|
+
* Requires Manage Channels permission.
|
|
398
|
+
*/
|
|
399
|
+
async createChannel(data: {
|
|
400
|
+
type: 0 | 2 | 4 | 5;
|
|
401
|
+
name: string;
|
|
402
|
+
parent_id?: string | null;
|
|
403
|
+
topic?: string | null;
|
|
404
|
+
bitrate?: number | null;
|
|
405
|
+
user_limit?: number | null;
|
|
406
|
+
nsfw?: boolean;
|
|
407
|
+
permission_overwrites?: Array<{ id: string; type: number; allow: string; deny: string }>;
|
|
408
|
+
}): Promise<GuildChannel> {
|
|
409
|
+
const created = await this.client.rest.post(Routes.guildChannels(this.id), {
|
|
410
|
+
body: data,
|
|
411
|
+
auth: true,
|
|
412
|
+
});
|
|
413
|
+
const channel = Channel.from(this.client, created as APIChannel);
|
|
414
|
+
if (channel) {
|
|
415
|
+
this.client.channels.set(channel.id, channel);
|
|
416
|
+
this.channels.set(channel.id, channel as GuildChannel);
|
|
417
|
+
}
|
|
418
|
+
return channel as GuildChannel;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Fetch all channels in this guild.
|
|
423
|
+
* @returns Array of GuildChannel objects (cached in guild.channels and client.channels)
|
|
424
|
+
*/
|
|
425
|
+
async fetchChannels(): Promise<GuildChannel[]> {
|
|
426
|
+
const data = await this.client.rest.get(Routes.guildChannels(this.id));
|
|
427
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
428
|
+
const channels: GuildChannel[] = [];
|
|
429
|
+
for (const ch of list) {
|
|
430
|
+
const channel = Channel.from(this.client, ch as APIChannel);
|
|
431
|
+
if (channel) {
|
|
432
|
+
this.client.channels.set(channel.id, channel);
|
|
433
|
+
this.channels.set(channel.id, channel as GuildChannel);
|
|
434
|
+
channels.push(channel as GuildChannel);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return channels;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Edit this guild. PATCH /guilds/{id}.
|
|
442
|
+
* Requires guild owner or Administrator.
|
|
443
|
+
*/
|
|
444
|
+
async edit(options: {
|
|
445
|
+
name?: string;
|
|
446
|
+
icon?: string | null;
|
|
447
|
+
system_channel_id?: string | null;
|
|
448
|
+
system_channel_flags?: number;
|
|
449
|
+
afk_channel_id?: string | null;
|
|
450
|
+
afk_timeout?: number;
|
|
451
|
+
default_message_notifications?: DefaultMessageNotifications;
|
|
452
|
+
verification_level?: GuildVerificationLevel;
|
|
453
|
+
mfa_level?: GuildMFALevel;
|
|
454
|
+
explicit_content_filter?: GuildExplicitContentFilter;
|
|
455
|
+
banner?: string | null;
|
|
456
|
+
splash?: string | null;
|
|
457
|
+
embed_splash?: string | null;
|
|
458
|
+
splash_card_alignment?: string;
|
|
459
|
+
features?: GuildFeature[];
|
|
460
|
+
}): Promise<this> {
|
|
461
|
+
const data = await this.client.rest.patch<APIGuild>(Routes.guild(this.id), {
|
|
462
|
+
body: options,
|
|
463
|
+
auth: true,
|
|
464
|
+
});
|
|
465
|
+
this.name = data.name;
|
|
466
|
+
this.icon = data.icon ?? this.icon;
|
|
467
|
+
this.banner = data.banner ?? this.banner;
|
|
468
|
+
this.splash = data.splash ?? this.splash;
|
|
469
|
+
this.systemChannelId = data.system_channel_id ?? this.systemChannelId;
|
|
470
|
+
this.afkChannelId = data.afk_channel_id ?? this.afkChannelId;
|
|
471
|
+
this.afkTimeout = data.afk_timeout ?? this.afkTimeout;
|
|
472
|
+
this.verificationLevel = data.verification_level ?? this.verificationLevel;
|
|
473
|
+
this.mfaLevel = data.mfa_level ?? this.mfaLevel;
|
|
474
|
+
this.explicitContentFilter = data.explicit_content_filter ?? this.explicitContentFilter;
|
|
475
|
+
this.defaultMessageNotifications =
|
|
476
|
+
data.default_message_notifications ?? this.defaultMessageNotifications;
|
|
477
|
+
this.features = data.features ?? this.features;
|
|
478
|
+
return this;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Delete this guild. POST /guilds/{id}/delete.
|
|
483
|
+
* Must be the guild owner.
|
|
484
|
+
*/
|
|
485
|
+
async delete(): Promise<void> {
|
|
486
|
+
await this.client.rest.post(Routes.guildDelete(this.id), { auth: true });
|
|
487
|
+
this.client.guilds.delete(this.id);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Fetch vanity URL for this guild. GET /guilds/{id}/vanity-url.
|
|
492
|
+
* Requires Manage Guild permission.
|
|
493
|
+
*/
|
|
494
|
+
async fetchVanityURL(): Promise<APIVanityURL> {
|
|
495
|
+
return this.client.rest.get<APIVanityURL>(Routes.guildVanityUrl(this.id), { auth: true });
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Transfer guild ownership to another user. POST /guilds/{id}/transfer-ownership.
|
|
500
|
+
* Must be the guild owner.
|
|
501
|
+
*/
|
|
502
|
+
async transferOwnership(newOwnerId: string, password?: string): Promise<void> {
|
|
503
|
+
await this.client.rest.post(Routes.guildTransferOwnership(this.id), {
|
|
504
|
+
body: { new_owner_id: newOwnerId, ...(password != null && { password }) },
|
|
505
|
+
auth: true,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Set text channel flexible names feature. PATCH /guilds/{id}/text-channel-flexible-names.
|
|
511
|
+
*/
|
|
512
|
+
setTextChannelFlexibleNames(enabled: boolean): Promise<this> {
|
|
513
|
+
return this.client.rest
|
|
514
|
+
.patch<APIGuild>(Routes.guildTextChannelFlexibleNames(this.id), {
|
|
515
|
+
body: { enabled },
|
|
516
|
+
auth: true,
|
|
517
|
+
})
|
|
518
|
+
.then(() => this);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Set detached banner feature. PATCH /guilds/{id}/detached-banner.
|
|
523
|
+
*/
|
|
524
|
+
setDetachedBanner(enabled: boolean): Promise<this> {
|
|
525
|
+
return this.client.rest
|
|
526
|
+
.patch<APIGuild>(Routes.guildDetachedBanner(this.id), {
|
|
527
|
+
body: { enabled },
|
|
528
|
+
auth: true,
|
|
529
|
+
})
|
|
530
|
+
.then(() => this);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Set disallow unclaimed accounts. PATCH /guilds/{id}/disallow-unclaimed-accounts.
|
|
535
|
+
*/
|
|
536
|
+
setDisallowUnclaimedAccounts(enabled: boolean): Promise<this> {
|
|
537
|
+
return this.client.rest
|
|
538
|
+
.patch<APIGuild>(Routes.guildDisallowUnclaimedAccounts(this.id), {
|
|
539
|
+
body: { enabled },
|
|
540
|
+
auth: true,
|
|
541
|
+
})
|
|
542
|
+
.then(() => this);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Update role positions. PATCH /guilds/{id}/roles.
|
|
547
|
+
* @param updates - Array of { id, position? }
|
|
548
|
+
*/
|
|
549
|
+
async setRolePositions(updates: Array<{ id: string; position?: number }>): Promise<APIRole[]> {
|
|
550
|
+
const data = await this.client.rest.patch<APIRole[] | Record<string, APIRole>>(
|
|
551
|
+
Routes.guildRoles(this.id),
|
|
552
|
+
{ body: updates, auth: true },
|
|
553
|
+
);
|
|
554
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
555
|
+
for (const r of list) {
|
|
556
|
+
this.roles.set(r.id, new Role(this.client, r, this.id));
|
|
557
|
+
}
|
|
558
|
+
return list as APIRole[];
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Update role hoist positions. PATCH /guilds/{id}/roles/hoist-positions.
|
|
563
|
+
*/
|
|
564
|
+
async setRoleHoistPositions(
|
|
565
|
+
updates: Array<{ id: string; hoist_position?: number }>,
|
|
566
|
+
): Promise<APIRole[]> {
|
|
567
|
+
const data = await this.client.rest.patch<APIRole[] | Record<string, APIRole>>(
|
|
568
|
+
Routes.guildRolesHoistPositions(this.id),
|
|
569
|
+
{ body: updates, auth: true },
|
|
570
|
+
);
|
|
571
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
572
|
+
for (const r of list) {
|
|
573
|
+
this.roles.set(r.id, new Role(this.client, r, this.id));
|
|
574
|
+
}
|
|
575
|
+
return list as APIRole[];
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Reset role hoist positions. DELETE /guilds/{id}/roles/hoist-positions.
|
|
580
|
+
*/
|
|
581
|
+
async resetRoleHoistPositions(): Promise<APIRole[]> {
|
|
582
|
+
const data = await this.client.rest.delete<APIRole[] | Record<string, APIRole>>(
|
|
583
|
+
Routes.guildRolesHoistPositions(this.id),
|
|
584
|
+
{ auth: true },
|
|
585
|
+
);
|
|
586
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
587
|
+
for (const r of list) {
|
|
588
|
+
this.roles.set(r.id, new Role(this.client, r, this.id));
|
|
589
|
+
}
|
|
590
|
+
return list as APIRole[];
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Update channel positions.
|
|
595
|
+
* @param updates - Array of { id, position?, parent_id?, lock_permissions? }
|
|
596
|
+
* Requires Manage Channels permission.
|
|
597
|
+
*/
|
|
598
|
+
async setChannelPositions(
|
|
599
|
+
updates: Array<{
|
|
600
|
+
id: string;
|
|
601
|
+
position?: number;
|
|
602
|
+
parent_id?: string | null;
|
|
603
|
+
lock_permissions?: boolean;
|
|
604
|
+
}>,
|
|
605
|
+
): Promise<void> {
|
|
606
|
+
await this.client.rest.patch(Routes.guildChannels(this.id), {
|
|
607
|
+
body: updates,
|
|
608
|
+
auth: true,
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Fetch all emojis in this guild.
|
|
614
|
+
* @returns Array of GuildEmoji objects (cached in guild.emojis)
|
|
615
|
+
*/
|
|
616
|
+
async fetchEmojis(): Promise<GuildEmoji[]> {
|
|
617
|
+
const data = await this.client.rest.get<APIEmoji[] | Record<string, APIEmoji>>(
|
|
618
|
+
Routes.guildEmojis(this.id),
|
|
619
|
+
);
|
|
620
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
621
|
+
const emojis: GuildEmoji[] = [];
|
|
622
|
+
for (const e of list) {
|
|
623
|
+
const emoji = new GuildEmoji(this.client, { ...e, guild_id: this.id }, this.id);
|
|
624
|
+
this.emojis.set(emoji.id, emoji);
|
|
625
|
+
emojis.push(emoji);
|
|
626
|
+
}
|
|
627
|
+
return emojis;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Fetch a single emoji by ID.
|
|
632
|
+
* @param emojiId - The emoji ID to fetch
|
|
633
|
+
* @returns The guild emoji
|
|
634
|
+
* @throws FluxerError if emoji not found (404)
|
|
635
|
+
*/
|
|
636
|
+
async fetchEmoji(emojiId: string): Promise<GuildEmoji> {
|
|
637
|
+
try {
|
|
638
|
+
const data = await this.client.rest.get<APIEmoji>(Routes.guildEmoji(this.id, emojiId));
|
|
639
|
+
const emoji = new GuildEmoji(this.client, { ...data, guild_id: this.id }, this.id);
|
|
640
|
+
this.emojis.set(emoji.id, emoji);
|
|
641
|
+
return emoji;
|
|
642
|
+
} catch (err) {
|
|
643
|
+
const statusCode =
|
|
644
|
+
err instanceof FluxerAPIError
|
|
645
|
+
? err.statusCode
|
|
646
|
+
: (err as { statusCode?: number })?.statusCode;
|
|
647
|
+
if (statusCode === 404) {
|
|
648
|
+
throw new FluxerError(`Emoji ${emojiId} not found in guild`, {
|
|
649
|
+
code: ErrorCodes.EmojiNotFound,
|
|
650
|
+
cause: err as Error,
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
throw err instanceof FluxerError
|
|
654
|
+
? err
|
|
655
|
+
: new FluxerError('Failed to fetch guild emoji', { cause: err as Error });
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Fetch all stickers in this guild.
|
|
661
|
+
* @returns Array of GuildSticker objects (cached in guild.stickers)
|
|
662
|
+
*/
|
|
663
|
+
async fetchStickers(): Promise<GuildSticker[]> {
|
|
664
|
+
const data = await this.client.rest.get<APISticker[] | Record<string, APISticker>>(
|
|
665
|
+
Routes.guildStickers(this.id),
|
|
666
|
+
);
|
|
667
|
+
const list = Array.isArray(data) ? data : Object.values(data ?? {});
|
|
668
|
+
const stickers: GuildSticker[] = [];
|
|
669
|
+
for (const s of list) {
|
|
670
|
+
const sticker = new GuildSticker(this.client, { ...s, guild_id: this.id }, this.id);
|
|
671
|
+
this.stickers.set(sticker.id, sticker);
|
|
672
|
+
stickers.push(sticker);
|
|
673
|
+
}
|
|
674
|
+
return stickers;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Fetch a single sticker by ID.
|
|
679
|
+
* @param stickerId - The sticker ID to fetch
|
|
680
|
+
*/
|
|
681
|
+
async fetchSticker(stickerId: string): Promise<GuildSticker> {
|
|
682
|
+
const data = await this.client.rest.get<APISticker>(Routes.guildSticker(this.id, stickerId));
|
|
683
|
+
const sticker = new GuildSticker(this.client, { ...data, guild_id: this.id }, this.id);
|
|
684
|
+
this.stickers.set(sticker.id, sticker);
|
|
685
|
+
return sticker;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Bulk create emojis. POST /guilds/{id}/emojis/bulk.
|
|
690
|
+
* @param emojis - Array of { name, image } (base64), 1-50 emojis
|
|
691
|
+
* @returns Array of created GuildEmoji objects
|
|
692
|
+
*/
|
|
693
|
+
async createEmojisBulk(emojis: Array<{ name: string; image: string }>): Promise<GuildEmoji[]> {
|
|
694
|
+
const data = await this.client.rest.post<APIEmoji[] | { emojis?: APIEmoji[] }>(
|
|
695
|
+
Routes.guildEmojisBulk(this.id),
|
|
696
|
+
{
|
|
697
|
+
body: { emojis },
|
|
698
|
+
auth: true,
|
|
699
|
+
},
|
|
700
|
+
);
|
|
701
|
+
const list = Array.isArray(data) ? data : (data?.emojis ?? []);
|
|
702
|
+
return list.map((e) => new GuildEmoji(this.client, { ...e, guild_id: this.id }, this.id));
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Bulk create stickers. POST /guilds/{id}/stickers/bulk.
|
|
707
|
+
* @param stickers - Array of { name, image, description?, tags? }, 1-50 stickers
|
|
708
|
+
* @returns Array of created GuildSticker objects
|
|
709
|
+
*/
|
|
710
|
+
async createStickersBulk(
|
|
711
|
+
stickers: Array<{
|
|
712
|
+
name: string;
|
|
713
|
+
image: string;
|
|
714
|
+
description?: string;
|
|
715
|
+
tags?: string[];
|
|
716
|
+
}>,
|
|
717
|
+
): Promise<GuildSticker[]> {
|
|
718
|
+
const data = await this.client.rest.post<APISticker[] | { stickers?: APISticker[] }>(
|
|
719
|
+
Routes.guildStickersBulk(this.id),
|
|
720
|
+
{
|
|
721
|
+
body: { stickers },
|
|
722
|
+
auth: true,
|
|
723
|
+
},
|
|
724
|
+
);
|
|
725
|
+
const list = Array.isArray(data) ? data : (data?.stickers ?? []);
|
|
726
|
+
const created = list.map(
|
|
727
|
+
(s) => new GuildSticker(this.client, { ...s, guild_id: this.id }, this.id),
|
|
728
|
+
);
|
|
729
|
+
for (const sticker of created) {
|
|
730
|
+
this.stickers.set(sticker.id, sticker);
|
|
731
|
+
}
|
|
732
|
+
return created;
|
|
733
|
+
}
|
|
734
|
+
}
|