{"id":14983468,"url":"https://github.com/eds-fw/framework","last_synced_at":"2025-10-29T22:30:40.175Z","repository":{"id":189804447,"uuid":"680273925","full_name":"eds-fw/framework","owner":"eds-fw","description":"Simply TypeScript framework for your discord.js bots","archived":false,"fork":false,"pushed_at":"2024-08-16T10:07:31.000Z","size":268,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-08-19T13:37:37.504Z","etag":null,"topics":["discord","discord-bot","discord-js","framework","javascript","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eds-fw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-18T19:16:03.000Z","updated_at":"2024-08-24T09:23:06.624Z","dependencies_parsed_at":"2024-06-01T11:19:04.518Z","dependency_job_id":"4c701613-d5a9-4c90-b534-fff8c0d06ca2","html_url":"https://github.com/eds-fw/framework","commit_stats":null,"previous_names":["easy-ds-bot/framework","eds-fw/framework"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eds-fw%2Fframework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eds-fw%2Fframework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eds-fw%2Fframework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eds-fw%2Fframework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eds-fw","download_url":"https://codeload.github.com/eds-fw/framework/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238900369,"owners_count":19549493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discord","discord-bot","discord-js","framework","javascript","nodejs","typescript"],"created_at":"2024-09-24T14:07:15.277Z","updated_at":"2025-10-29T22:30:39.841Z","avatar_url":"https://github.com/eds-fw.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://avatars.githubusercontent.com/u/142582396?s=400\u0026u=efba7a6a242149915b23e51923a6c3afb7fa8fcb\u0026v=4\" width=\"200\"/\u003e\n\u003c/p\u003e\n\n\u003cb align=\"center\"\u003e\n    \n    Simply TypeScript framework for your discord.js bots\n    \n[![CodeFactor](https://www.codefactor.io/repository/github/eds-fw/framework/badge/main)](https://www.codefactor.io/repository/github/eds-fw/framework/overview/main)\n\u003c/b\u003e\n\u003chr\u003e\n\n# Features\n- Intuitive and does not complicate the development process\n- Contains type declarations (.d.ts)\n- Fully configurable\n- Built-in `/help` command\n- Lazy constructors (`createSlashCommand()`, `createButton()` and more)\n- Smart Fetches: get from cache or fetch (`sfMember(context, userId)` and more)\n- Simply 'Map'-based storage: `get()`, `set()`, `save()` and more\n- Quick message panels for advanced for data input (`InteractivePanel`)\n- Utils: `getAvatar()`, `quickEmbed()`, `optionsWithDefaultValue()` and `expandDirs()`\n\n# Requirements\n- [NodeJS](https://nodejs.org/en) `v18` or newer\n\n# Setup\n1. Install EDS via npm:\n```bat\nnpm i @eds-fw/framework\n```\n\n2. Create `tsconfig.json` file:\n```json\n{\n    \"extends\": \"./node_modules/@eds-fw/framework/tsconfig.base.json\",\n    \"exclude\": [\n        \"node_modules/\",\n        \"logs/\",\n        \"vault.json\",\n        \"dist/\",\n        \"assets/\"\n    ],\n    \"compilerOptions\": {\n        \"rootDit\": \"src\",\n        \"outDir\": \"dist\"\n    }\n}\n```\n\n3. Create your first bot using EDS:\n```ts\n// src/index.ts\n//'runtime' is a 'global' object equivalent\nimport { eds } from \"@eds-fw/framework\";\nimport { ApplicationCommandType } from \"discord.js\";\nimport { token } from \"../vault.json\" with { \"type\": \"json\" };\nconst config: eds.ConfigExemplar = {\n    token,\n    intents: \"all\",\n    commandsPath: \"./commands/\",\n    slashOnly: true, //default value\n    includeBuiltinCommands: {\n        help: true, //default value\n    },\n    colors: {\n        default: 0xffffff, //'0x' + HEX color without '#'\n        info: 0x00FFEA,\n    },\n};\n\nconst bot = eds.createBot(config);\neds.createSlashCommand({\n    name: \"cake\",\n    description: \"Give me a cake!\",\n    nsfw: false,\n    type: ApplicationCommandType.ChatInput,\n    defaultMemberPermissions: null,\n    dmPermission: false,\n});\neds.startBot();\n\nexport default bot;\n```\n\n4. Create your first `/cake` command:\n```ts\n// src/commands/cake.ts\nimport { eds } from \"@eds-fw/framework\";\nimport { ComponentType, ButtonStyle } from \"discord.js\";\n\n//eds components are resistant to bot restarts\neds.createButton({\n    custom_id: \"get cake\"\n}, async context =\u003e { //\"get cake\" button code\n    await context.quickReply(\n        true, //epemeral?\n        undefined, //title\n        \"# :cake:\" //description\n    );\n})\n\nexport default {\n    async run(context)\n    {\n        await context.reply(\n            true, //ephemeral?\n            \"aloha hawaii\", //embed title (optional if has desc)\n            `\u003c@${context.user.id}\u003e, do you want a cake?`, //embed desc (optional if has title)\n            \"info\", //?embed color name (set in config)\n            [{ //?djs components\n                type: ComponentType.ActionRow,\n                components: [{\n                    type: ComponentType.Button,\n                    style: ButtonStyle.Secondary, //gray\n                    custom_id: \"get cake\",\n                    label: \"Get cake\"\n                }]\n            }]\n        );\n    },\n\n    //command options\n    info: {\n        name: \"cake\",\n        type: \"slash\",\n        \n        //for auto-help:\n        desc: \"Give me a cake!\",\n        category: \"General\",\n        usage: '',\n        hidden: true,\n    }\n} satisfies eds.CommandFile\u003c\"slash\"\u003e;\n```\n\n5. A) Create `start.bat` file (WINDOWS ONLY) for easily compile \u0026 launch your bot:\n```batch\nrem start.bat\n@npx tsc\n@node dist/index.js\n@pause\nrem \"@pause\" keeps window open after bot crash\n```\n5. B) Create `start.sh` file for easily compile \u0026 launch your bot:\n```sh\n# start.sh\nnpx tsc\nnode dist/index.js\nread -p \"\" #keeps window open after bot crash\n```\n\n6. Execute (open) `start.bat` or `start.sh` file. Voila! It's alive!\n\n# API\n- *module* `@eds-fw/utils`\n- *module* `@eds-fw/storage`\n- *module* `@eds-fw/fetch`\n- `createBot (config: ConfigExemplar): KnownRuntimeProperties` *(lazyConstructor)*\n- `createButton (options: ButtonOptions, code: ButtonCode): void` *(lazyConstructor)*\n    \u003e- runtime: `componentManager`\n- `createMenu (options: MenuOptions, code: MenuUserCode | MenuStringCode): void` *(lazyConstructor)*\n    \u003e- runtime: `componentManager`\n- `createModal (options: ModalOptions, code: ModalCode): void` *(lazyConstructor)*\n    \u003e- runtime: `componentManager`\n- `createSlashCommand (options: SpplicationCommandData): void` *(lazyConstructor)*\n    \u003e- runtime: `slashCommandsManager`\n- *async* `sfUser (mng_or_ctx: AnyContext | UserManager | undefined, id: Snowflake | undefined): Promise\u003cUser | undefined\u003e`\n- *async* `sfMember (mng_or_ctx: AnyContext | GuildMemberManager | undefined, id: Snowflake | undefined): Promise\u003cGuildMember | undefined\u003e`\n- *async* `sfChannel (mng_or_ctx: AnyContext | GuildChannelManager | undefined, id: Snowflake | undefined): Promise\u003cGuildBasedChannel | undefined\u003e`\n- *async* `sfGuild (mng_or_ctx: AnyContext | GuildManager | undefined, id: Snowflake | undefined): Promise\u003cGuild | undefined\u003e`\n- *async* `sfRole (mng_or_ctx: AnyContext | RoleManager | undefined, id: Snowflake | undefined): Promise\u003cRole | undefined\u003e`\n- *async* `sfMessage (mng_or_ctx: AnyContext | MessageManager | undefined, id: Snowflake | undefined): Promise\u003cMessage | undefined\u003e`\n- `getAvatar (user: \u003cany user\u003e | \u003cany member\u003e | undefined | null): string`\n- `quickEmbed (title?: string, description?: string, type: string = \"default\", components?: BaseMessageOptions[\"components\"], customEmbed?: JSONEncodable\u003cAPIEmbed\u003e | APIEmbed): BaseMessageOptions`\n- `optionsWithDefaultValue (options: SelectMenuComponentOptionData[], defaultVal: string | null): SelectMenuComponentOptionData[]`\n- *async* `startBot (): Promise\u003cvoid\u003e`\n    \u003e- runtime: `slashCommandsManager, client, config`\n- *anonimous class* `runtimeStorage` *(runtime)*\n    \u003e- `[key: string]: any`\n    \u003e- `getAll \u003cT\u003e(...keys: (keyof T)): T`\n    \u003e- `get \u003cV\u003e(key: string): V`\n    \u003e- `setAll \u003cT\u003e(values: T): T`\n    \u003e- `set \u003cK, V\u003e(key: K, value: V): { [X in K]: V }`\n- *class* `Client` *extends djs.Client*\n    \u003e- *constructor* `(options: Options)`\n    \u003e- *async* `init (): Promise\u003cvoid\u003e`\n- *class* `Handler`\n    \u003e- runtime: `config, loader, client, contextFactory`\n    \u003e- *constructor* `new ()`\n- *class* `InteractivePanel \u003cT\u003e`\n    \u003e- *static* `register \u003cT extends object\u003e(messageConstructor: InteractivePanel.ConstructMessageFn\u003cT\u003e, msgId: string): void`\n    \u003e- *static* `getMenu\u003cT extends object\u003e(msgId: string): InteractivePanel\u003cT\u003e | undefined`\n    \u003e- *static* `renderValues(keysAndValues: [string, string | undefined, string?][]): string`\n    \u003e- `data: Partial\u003cT\u003e`\n    \u003e- `render (): MessageCreateOptions \u0026 InteractionUpdateOptions \u0026 InteractionReplyOptions  `\n    \u003e- `deleteInstance (): void`\n    \u003e- *private* *constructor* `()`\n- *class* `Loader`\n    \u003e- *field* `commandHelp: AutoCommandHelp`\n    \u003e- *constructor* `new (path: string, noLog?: boolean, ignorePrefixes?: string[], builtinCommands?: ConfigExemplar.includeBuiltinCommands)`\n    \u003e- `clearMaps (): void`\n    \u003e- *async* `load (): Promise\u003cvoid\u003e`\n    \u003e- *iternal* *async* `loadBuiltin (): Promise\u003cvoid\u003e`\n    \u003e- *iternal* *get* `getCallMap: Map\u003cstring[], string\u003e`\n    \u003e- *iternal* *get* `getSlashCallMap: Map\u003cstring, string\u003e`\n    \u003e- *iternal* *get* `getAlwaysCallMap: string[]`\n    \u003e- *iternal* *get* `getHelpInfoMap: Map\u003cstring[], CommandHelpInfo\u003e`\n- *class* `SlashCommandsManager`\n    \u003e- runtime: `client`\n    \u003e- `create (options: djs.ApplicationCommandData): void`\n    \u003e- `save (): void`\n- *type* `SupportedInteractions`\n- *type* `CommandContext \u003cCmdType\u003e`\n- *type* `AnyContext`\n- *type* `InteractionContext \u003cSupportedInteractions\u003e`\n- *type* `SlashCommandContext`\n- *type* `TextCommandContext`\n- *type* `CommandFile`\n- *type* `CommandHelpInfo`\n- *type* `CommandInfo`\n- *type* `ConfigExemplar`\n- *type* `KnownRuntimeProperties`\n- *iternal* *async* `expandDirs (path: string): Promise\u003cstring[]\u003e`\n- *iternal* *class* `AutoCommandHelp`\n    \u003e- runtime: `config`\n    \u003e- *field* `pages: Map\u003cstring, string\u003e`\n    \u003e- *field* `commandTypes: Map\u003cstring, \"slash\" | \"text\" | \"nonPrefixed\"\u003e`\n    \u003e- *field* `descriptions: Map\u003cstring, string\u003e`\n    \u003e- *field* `templates: {...}`\n    \u003e- *field* `_fullCommandList: string`\n    \u003e- *constructor* `new ()`\n    \u003e- `getCommandList (roles: string[]): string`\n    \u003e- `getCommandNames (roles: string[]): string[]`\n    \u003e- `getBakedCommandNames (roles: string[]): string[]`\n    \u003e- `clear (): void`\n    \u003e- *iternal* `reg (file: CommandFile\u003cboolean\u003e as const): void`\n    \u003e- *iternal* *field* `_publicCommands: string`\n    \u003e- *iternal* *field* `_fullCommandList: string`\n- *iternal* *class* `ContextFactory`\n    \u003e- runtime: `config`\n    \u003e- *constructor* `new ()`\n    \u003e- `createTextContext (message: djs.Message): CommandContext\u003cfalse\u003e`\n    \u003e- `createSlashContext (interaction: djs.ChatInputCommandInteraction): CommandContext\u003ctrue\u003e`\n- *iternal* *class* `ComponentsManager`\n    \u003e- *constructor* `()` *empty*\n    \u003e- `clearMaps (): void`\n    \u003e- `createButton (options: ButtonOptions, code: ButtonCode): void`\n    \u003e- `createMenu (options: MenuOptions, code: MenuUserCode | MenuStringCode): void`\n    \u003e- `createModal (options: ModalOptions, code: ModalCode): void`\n    \u003e- *iternal* *get* `getButtonsMap: Map\u003cstring, MapVal\u003c...\u003e\u003e`\n    \u003e- *iternal* *get* `getMenusMap: Map\u003cstring, MapVal\u003c...\u003e\u003e`\n    \u003e- *iternal* *get* `getModalsMap: Map\u003cstring, MapVal\u003c...\u003e\u003e`\n\n# [Source (git)](https://github.com/eds-fw/framework)\n# [Issues (git)](https://github.com/eds-fw/framework/issues)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feds-fw%2Fframework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feds-fw%2Fframework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feds-fw%2Fframework/lists"}