├── assets ├── easter-egg └── jellycommands-banner.png ├── .gitattributes ├── packages ├── create-jellycommands │ ├── src │ │ ├── js │ │ │ ├── _env.example │ │ │ ├── _gitignore │ │ │ ├── src │ │ │ │ ├── app.d.ts │ │ │ │ ├── components │ │ │ │ │ ├── ready.js │ │ │ │ │ ├── hello.js │ │ │ │ │ └── test.js │ │ │ │ └── index.js │ │ │ ├── package.json │ │ │ ├── jsconfig.json │ │ │ └── README.md │ │ ├── ts │ │ │ ├── _env.example │ │ │ ├── _gitignore │ │ │ ├── src │ │ │ │ ├── app.d.ts │ │ │ │ ├── components │ │ │ │ │ ├── ready.ts │ │ │ │ │ ├── hello.ts │ │ │ │ │ └── test.ts │ │ │ │ └── index.ts │ │ │ ├── package.json │ │ │ ├── tsconfig.json │ │ │ └── README.md │ │ ├── version.js │ │ ├── copy.js │ │ ├── bin.js │ │ └── index.js │ ├── README.md │ ├── tsconfig.json │ ├── LICENSE │ └── package.json ├── playground │ ├── .env.example │ ├── src │ │ ├── app.d.ts │ │ ├── events │ │ │ ├── ready.js │ │ │ └── file-loaded │ │ │ │ └── messageCreate.js │ │ ├── buttons │ │ │ └── test.js │ │ ├── modals │ │ │ └── test.js │ │ ├── commands │ │ │ ├── file-loaded │ │ │ │ ├── messageCommand.js │ │ │ │ ├── userCommand.js │ │ │ │ ├── globalTest.js │ │ │ │ ├── _hiddenCommand.js │ │ │ │ ├── dmBlockedGlobal.js │ │ │ │ ├── guildTest.js │ │ │ │ ├── testButton.js │ │ │ │ ├── localise.js │ │ │ │ ├── autocomplete.js │ │ │ │ ├── testModal.js │ │ │ │ └── _colors.js │ │ │ └── pog.js │ │ └── index.js │ ├── jsconfig.json │ └── package.json ├── jellycommands │ ├── ambient.d.ts │ ├── src │ │ ├── utils │ │ │ ├── types.ts │ │ │ ├── zod.ts │ │ │ ├── snowflake.ts │ │ │ ├── logger.ts │ │ │ └── token.ts │ │ ├── components │ │ │ ├── commands │ │ │ │ ├── types │ │ │ │ │ ├── userCommands │ │ │ │ │ │ ├── options.ts │ │ │ │ │ │ └── UserCommand.ts │ │ │ │ │ ├── messageCommands │ │ │ │ │ │ ├── options.ts │ │ │ │ │ │ └── MessageCommand.ts │ │ │ │ │ ├── types.d.ts │ │ │ │ │ ├── commands │ │ │ │ │ │ └── options.ts │ │ │ │ │ ├── options.ts │ │ │ │ │ └── BaseCommand.ts │ │ │ │ ├── types.d.ts │ │ │ │ ├── register.ts │ │ │ │ ├── respond.ts │ │ │ │ ├── plugin.ts │ │ │ │ └── cache.ts │ │ │ ├── events │ │ │ │ ├── options.ts │ │ │ │ ├── plugin.ts │ │ │ │ └── Event.ts │ │ │ ├── modals │ │ │ │ ├── options.ts │ │ │ │ ├── modals.ts │ │ │ │ └── plugin.ts │ │ │ ├── buttons │ │ │ │ ├── options.ts │ │ │ │ ├── buttons.ts │ │ │ │ └── plugin.ts │ │ │ ├── components.ts │ │ │ └── loader.ts │ │ ├── plugins │ │ │ ├── core.ts │ │ │ └── plugins.ts │ │ ├── structures │ │ │ ├── Cache.ts │ │ │ └── SetMap.ts │ │ └── index.ts │ ├── tests │ │ ├── utils │ │ │ ├── files │ │ │ │ ├── test-files │ │ │ │ │ ├── index.mjs │ │ │ │ │ ├── test.mjs │ │ │ │ │ └── nested │ │ │ │ │ │ ├── hello.mjs │ │ │ │ │ │ └── _ignored.mjs │ │ │ │ └── read.test.ts │ │ │ ├── zod.test.ts │ │ │ ├── token │ │ │ │ ├── clientIdFromToken.test.ts │ │ │ │ ├── resolveClientId.test.ts │ │ │ │ ├── cleanToken.test.ts │ │ │ │ ├── resolveToken.test.ts │ │ │ │ └── getAuthData.test.ts │ │ │ ├── snowflake.test.ts │ │ │ └── logger.test.ts │ │ ├── tsconfig.json │ │ ├── mock.ts │ │ └── commands │ │ │ └── slash │ │ │ └── options.test.ts │ ├── tsup.config.ts │ ├── vitest.config.ts │ ├── tsconfig.json │ ├── README.md │ ├── LICENSE │ └── package.json └── docs │ ├── src │ ├── env.d.ts │ ├── assets │ │ ├── docs │ │ │ ├── button-failed.png │ │ │ ├── color-command.png │ │ │ ├── modal-failed.png │ │ │ ├── user-command.png │ │ │ ├── working-modal.png │ │ │ ├── message-command.png │ │ │ ├── working-button.png │ │ │ ├── channel-id-command.png │ │ │ ├── channel-update-event.png │ │ │ ├── create-a-button-command.png │ │ │ └── event-arg-intellisense.png │ │ └── logo.svg │ ├── content.config.ts │ ├── content │ │ └── docs │ │ │ ├── guides │ │ │ ├── messages.mdx │ │ │ └── fs.mdx │ │ │ ├── components │ │ │ ├── commands │ │ │ │ ├── caching.mdx │ │ │ │ ├── guards.mdx │ │ │ │ ├── dev.mdx │ │ │ │ ├── context-menu.mdx │ │ │ │ ├── slash.mdx │ │ │ │ └── index.mdx │ │ │ ├── deferring.mdx │ │ │ ├── custom-ids.mdx │ │ │ ├── props.mdx │ │ │ ├── events │ │ │ │ └── index.mdx │ │ │ ├── index.mdx │ │ │ ├── buttons │ │ │ │ └── index.mdx │ │ │ └── modals │ │ │ │ └── index.mdx │ │ │ ├── index.mdx │ │ │ ├── migrate │ │ │ ├── djs14.md │ │ │ ├── components.md │ │ │ └── props.md │ │ │ └── getting-started.mdx │ └── theme.css │ ├── public │ ├── events-run.png │ └── logo.svg │ ├── tsconfig.json │ ├── package.json │ └── astro.config.mjs ├── .git-blame-ignore-revs ├── .changeset ├── four-panthers-tap.md ├── hip-lions-vanish.md ├── nice-pears-attack.md ├── olive-trainers-relate.md ├── perfect-needles-rush.md ├── pink-drinks-learn.md ├── chilly-pets-speak.md ├── cyan-beers-heal.md ├── cyan-trainers-whisper.md ├── four-buses-knock.md ├── funny-falcons-mix.md ├── happy-sloths-kick.md ├── loud-lemons-shave.md ├── lovely-carrots-smoke.md ├── orange-ads-wave.md ├── popular-dolls-think.md ├── rare-owls-listen.md ├── cool-boats-kick.md ├── hungry-olives-allow.md ├── mean-pandas-develop.md ├── mighty-schools-happen.md ├── old-hotels-tease.md ├── orange-spiders-rescue.md ├── silly-beers-nail.md ├── silly-bugs-roll.md ├── small-knives-exercise.md ├── ten-walls-repair.md ├── unlucky-snails-suffer.md ├── wet-sheep-act.md ├── brown-feet-dress.md ├── cool-trees-guess.md ├── forty-apes-scream.md ├── khaki-roses-sin.md ├── lucky-wasps-study.md ├── metal-glasses-repeat.md ├── ninety-pants-hug.md ├── old-fireants-cover.md ├── perfect-oranges-beg.md ├── rude-results-tie.md ├── silver-pots-tickle.md ├── stale-candles-tap.md ├── tall-cups-shake.md ├── unlucky-peas-watch.md ├── all-forks-accept.md ├── angry-ladybugs-study.md ├── curvy-chefs-listen.md ├── great-horses-heal.md ├── mean-fans-explode.md ├── mean-turkeys-thank.md ├── nice-plants-drive.md ├── olive-kiwis-exist.md ├── red-otters-teach.md ├── rotten-zebras-perform.md ├── silent-llamas-hope.md ├── silly-goats-kiss.md ├── tough-kangaroos-yawn.md ├── yellow-snakes-thank.md ├── eighty-poets-laugh.md ├── five-trees-flow.md ├── forty-jeans-speak.md ├── healthy-dingos-push.md ├── large-feet-applaud.md ├── nasty-weeks-invent.md ├── proud-schools-pretend.md ├── sixty-candles-decide.md ├── sweet-lines-vanish.md ├── thick-clouds-battle.md ├── wise-needles-look.md ├── clean-jobs-play.md ├── evil-donuts-film.md ├── nervous-dots-jump.md ├── popular-laws-walk.md ├── rude-melons-whisper.md ├── soft-crabs-swim.md ├── stupid-candles-share.md ├── thick-llamas-check.md ├── wild-horses-lie.md ├── angry-radios-teach.md ├── early-cherries-poke.md ├── little-actors-march.md ├── long-squids-run.md ├── lucky-bobcats-smell.md ├── nasty-rice-laugh.md ├── rich-bugs-tickle.md ├── sweet-dolls-beg.md ├── thick-ducks-press.md ├── chatty-insects-whisper.md ├── dirty-wombats-sip.md ├── famous-books-switch.md ├── gentle-flowers-tease.md ├── lemon-walls-sin.md ├── light-boats-guess.md ├── many-items-pull.md ├── perfect-guests-eat.md ├── spicy-waves-compare.md ├── angry-mice-explode.md ├── lemon-eggs-grow.md ├── plenty-rats-look.md ├── violet-ways-reply.md ├── sharp-shirts-think.md ├── witty-geese-deliver.md ├── angry-panthers-report.md ├── chilled-avocados-speak.md ├── cool-mugs-knock.md ├── large-spoons-move.md ├── tiny-elephants-sing.md ├── silent-hounds-teach.md ├── config.json └── pre.json ├── .gitignore ├── .vscode ├── settings.json └── extensions.json ├── pnpm-workspace.yaml ├── .prettierignore ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature_request.yml │ └── bug.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── tests.yml │ └── release.yml ├── .prettierrc ├── biome.json ├── LICENSE ├── patches └── @astrojs__starlight.patch ├── package.json └── README.md /assets/easter-egg: -------------------------------------------------------------------------------- 1 | by jake -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/_env.example: -------------------------------------------------------------------------------- 1 | DISCORD_TOKEN="" 2 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/_env.example: -------------------------------------------------------------------------------- 1 | DISCORD_TOKEN="" 2 | -------------------------------------------------------------------------------- /packages/playground/.env.example: -------------------------------------------------------------------------------- 1 | DISCORD_TOKEN="" 2 | TEST_GUILD="" 3 | -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # formatting 2 | 7d3bb1fbee4ece77ba842f2acbe8e152640b6362 3 | -------------------------------------------------------------------------------- /packages/jellycommands/ambient.d.ts: -------------------------------------------------------------------------------- 1 | interface Props { 2 | [key: string]: any; 3 | } 4 | -------------------------------------------------------------------------------- /.changeset/four-panthers-tap.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix build 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | dist 4 | .jellycommands 5 | coverage 6 | .astro/ 7 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/_gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules 3 | .jellycommands 4 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/_gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules 3 | .jellycommands 4 | -------------------------------------------------------------------------------- /packages/jellycommands/src/utils/types.ts: -------------------------------------------------------------------------------- 1 | export type MaybePromise = Promise | T; 2 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/files/test-files/index.mjs: -------------------------------------------------------------------------------- 1 | export default 'correct'; 2 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/files/test-files/test.mjs: -------------------------------------------------------------------------------- 1 | export default 'correct'; 2 | -------------------------------------------------------------------------------- /.changeset/hip-lions-vanish.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | update deps 6 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/files/test-files/nested/hello.mjs: -------------------------------------------------------------------------------- 1 | export default 'correct'; 2 | -------------------------------------------------------------------------------- /.changeset/nice-pears-attack.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | support buttons 6 | -------------------------------------------------------------------------------- /.changeset/olive-trainers-relate.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | new dm option 6 | -------------------------------------------------------------------------------- /.changeset/perfect-needles-rush.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | global dev mode 6 | -------------------------------------------------------------------------------- /.changeset/pink-drinks-learn.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | switch to api v10 6 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/files/test-files/nested/_ignored.mjs: -------------------------------------------------------------------------------- 1 | export default 'WRONG'; 2 | -------------------------------------------------------------------------------- /.changeset/chilly-pets-speak.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | new permissions system 6 | -------------------------------------------------------------------------------- /.changeset/cyan-beers-heal.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": minor 3 | --- 4 | 5 | breaking: better logging 6 | -------------------------------------------------------------------------------- /.changeset/cyan-trainers-whisper.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix event.run types 6 | -------------------------------------------------------------------------------- /.changeset/four-buses-knock.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": minor 3 | --- 4 | 5 | feat: add modal component 6 | -------------------------------------------------------------------------------- /.changeset/funny-falcons-mix.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: improve exports 6 | -------------------------------------------------------------------------------- /.changeset/happy-sloths-kick.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | cache is disableable 6 | -------------------------------------------------------------------------------- /.changeset/loud-lemons-shave.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | fix dev script 6 | -------------------------------------------------------------------------------- /.changeset/lovely-carrots-smoke.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix event class type 6 | -------------------------------------------------------------------------------- /.changeset/orange-ads-wave.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix broken disabled option 6 | -------------------------------------------------------------------------------- /.changeset/popular-dolls-think.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | deps: remove totalist 6 | -------------------------------------------------------------------------------- /.changeset/rare-owls-listen.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | add a gitignore 6 | -------------------------------------------------------------------------------- /.changeset/cool-boats-kick.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | move utility type (internal) 6 | -------------------------------------------------------------------------------- /.changeset/hungry-olives-allow.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | update template deps 6 | -------------------------------------------------------------------------------- /.changeset/mean-pandas-develop.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fixes token handling logic 6 | -------------------------------------------------------------------------------- /.changeset/mighty-schools-happen.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | improved API error format 6 | -------------------------------------------------------------------------------- /.changeset/old-hotels-tease.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | update template deps 6 | -------------------------------------------------------------------------------- /.changeset/orange-spiders-rescue.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | add src/app.d.ts 6 | -------------------------------------------------------------------------------- /.changeset/silly-beers-nail.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | update dependancies 6 | -------------------------------------------------------------------------------- /.changeset/silly-bugs-roll.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | limit descriptions to 100 chars 6 | -------------------------------------------------------------------------------- /.changeset/small-knives-exercise.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix broken type - #86 6 | -------------------------------------------------------------------------------- /.changeset/ten-walls-repair.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': minor 3 | --- 4 | 5 | feat: update templates 6 | -------------------------------------------------------------------------------- /.changeset/unlucky-snails-suffer.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | add more error logging 6 | -------------------------------------------------------------------------------- /.changeset/wet-sheep-act.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix command id resolution process 6 | -------------------------------------------------------------------------------- /.changeset/brown-feet-dress.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | perf: remove cpy dependency 6 | -------------------------------------------------------------------------------- /.changeset/cool-trees-guess.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | internally rename util to utils 6 | -------------------------------------------------------------------------------- /.changeset/forty-apes-scream.md: -------------------------------------------------------------------------------- 1 | --- 2 | "create-jellycommands": patch 3 | --- 4 | 5 | chore: update templates 6 | -------------------------------------------------------------------------------- /.changeset/khaki-roses-sin.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | update template dependancies 6 | -------------------------------------------------------------------------------- /.changeset/lucky-wasps-study.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | deps: switch to ofetch from axios 6 | -------------------------------------------------------------------------------- /.changeset/metal-glasses-repeat.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | temporary disable permissions 6 | -------------------------------------------------------------------------------- /.changeset/ninety-pants-hug.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | improve internal requester types 6 | -------------------------------------------------------------------------------- /.changeset/old-fireants-cover.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | refactor internals to improve 6 | -------------------------------------------------------------------------------- /.changeset/perfect-oranges-beg.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | New create jellycommands 6 | -------------------------------------------------------------------------------- /.changeset/rude-results-tie.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | perf: remove desm dependency 6 | -------------------------------------------------------------------------------- /.changeset/silver-pots-tickle.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | autocomplete for slash commands 6 | -------------------------------------------------------------------------------- /.changeset/stale-candles-tap.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": minor 3 | --- 4 | 5 | feat: make event name not strict 6 | -------------------------------------------------------------------------------- /.changeset/tall-cups-shake.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix being able to use type strings 6 | -------------------------------------------------------------------------------- /.changeset/unlucky-peas-watch.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': minor 3 | --- 4 | 5 | update to discord.js v14 6 | -------------------------------------------------------------------------------- /.changeset/all-forks-accept.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | fix: add license to package.json 6 | -------------------------------------------------------------------------------- /.changeset/angry-ladybugs-study.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | snowflake max length has changed 6 | -------------------------------------------------------------------------------- /.changeset/curvy-chefs-listen.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | throw error if can't find option type 6 | -------------------------------------------------------------------------------- /.changeset/great-horses-heal.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | provide `Command` and `Event` directly 6 | -------------------------------------------------------------------------------- /.changeset/mean-fans-explode.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': minor 3 | --- 4 | 5 | update templates to have buttons 6 | -------------------------------------------------------------------------------- /.changeset/mean-turkeys-thank.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | remove GUILD_MEMBERS intent 6 | -------------------------------------------------------------------------------- /.changeset/nice-plants-drive.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix automatic file loading on windows 6 | -------------------------------------------------------------------------------- /.changeset/olive-kiwis-exist.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix JellyApplicationCommandOption type 6 | -------------------------------------------------------------------------------- /.changeset/red-otters-teach.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | breaking: add new "components" system 6 | -------------------------------------------------------------------------------- /.changeset/rotten-zebras-perform.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | command registration improvements 6 | -------------------------------------------------------------------------------- /.changeset/silent-llamas-hope.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | perf: replace minimist with mri 6 | -------------------------------------------------------------------------------- /.changeset/silly-goats-kiss.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | error catching in events and commands 6 | -------------------------------------------------------------------------------- /.changeset/tough-kangaroos-yawn.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | deps: switch to parsing with zod 6 | -------------------------------------------------------------------------------- /.changeset/yellow-snakes-thank.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | add .jellycommands to ignore 6 | -------------------------------------------------------------------------------- /assets/jellycommands-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/assets/jellycommands-banner.png -------------------------------------------------------------------------------- /packages/docs/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /.changeset/eighty-poets-laugh.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | update JellyApplicationCommandOption types 6 | -------------------------------------------------------------------------------- /.changeset/five-trees-flow.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | nested files with \_ are now ignored correctly 6 | -------------------------------------------------------------------------------- /.changeset/forty-jeans-speak.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | update styles of create-jellycommands 6 | -------------------------------------------------------------------------------- /.changeset/healthy-dingos-push.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | commands are only registered in dev guilds 6 | -------------------------------------------------------------------------------- /.changeset/large-feet-applaud.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | feat: add more jsdoc comments to exports 6 | -------------------------------------------------------------------------------- /.changeset/nasty-weeks-invent.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix config.messages.unknownCommand types 6 | -------------------------------------------------------------------------------- /.changeset/proud-schools-pretend.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: able to read files directly again 6 | -------------------------------------------------------------------------------- /.changeset/sixty-candles-decide.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | improved command cache/presistance system 6 | -------------------------------------------------------------------------------- /.changeset/sweet-lines-vanish.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | perf: replace kleur with picocolors 6 | -------------------------------------------------------------------------------- /.changeset/thick-clouds-battle.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: reject lowercase slash command name 6 | -------------------------------------------------------------------------------- /.changeset/wise-needles-look.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | change command/event file resolution logic 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true 4 | } 5 | -------------------------------------------------------------------------------- /.changeset/clean-jobs-play.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: type error when manually adding command/event 6 | -------------------------------------------------------------------------------- /.changeset/evil-donuts-film.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | perf: remove update-notifier dependency 6 | -------------------------------------------------------------------------------- /.changeset/nervous-dots-jump.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: debug logs firing when debug is disabled 6 | -------------------------------------------------------------------------------- /.changeset/popular-laws-walk.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | update the jsconfig.json and tsconfig.json 6 | -------------------------------------------------------------------------------- /.changeset/rude-melons-whisper.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | fix gitignore not being copied accross 6 | -------------------------------------------------------------------------------- /.changeset/soft-crabs-swim.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | fix command run callback having incorrect signature 6 | -------------------------------------------------------------------------------- /.changeset/stupid-candles-share.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | command name and description localisations 6 | -------------------------------------------------------------------------------- /.changeset/thick-llamas-check.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: validate client id when parsing from token 6 | -------------------------------------------------------------------------------- /.changeset/wild-horses-lie.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | 'jellycommands': patch 4 | --- 5 | 6 | update docs links 7 | -------------------------------------------------------------------------------- /packages/docs/public/events-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/public/events-run.png -------------------------------------------------------------------------------- /packages/playground/src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | interface Props { 4 | a: string; 5 | } 6 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | 4 | catalog: 5 | publint: ^0.3.14 6 | '@types/node': ^20.13.0 7 | -------------------------------------------------------------------------------- /.changeset/angry-radios-teach.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | add comments and switch to global dev mode 6 | -------------------------------------------------------------------------------- /.changeset/early-cherries-poke.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | 'jellycommands': patch 4 | --- 5 | 6 | update readme's 7 | -------------------------------------------------------------------------------- /.changeset/little-actors-march.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": minor 3 | --- 4 | 5 | feat: support exporting a component under any name 6 | -------------------------------------------------------------------------------- /.changeset/long-squids-run.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | migrated to discord-api-types instead of custom ones 6 | -------------------------------------------------------------------------------- /.changeset/lucky-bobcats-smell.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | stop transformOptionType from mutating the object 6 | -------------------------------------------------------------------------------- /.changeset/nasty-rice-laugh.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | 'jellycommands': patch 4 | --- 5 | 6 | update dependancies 7 | -------------------------------------------------------------------------------- /.changeset/rich-bugs-tickle.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | add a guard to catch no guild id when dev mode enabled 6 | -------------------------------------------------------------------------------- /.changeset/sweet-dolls-beg.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | moved token functions out of client and into util file 6 | -------------------------------------------------------------------------------- /.changeset/thick-ducks-press.md: -------------------------------------------------------------------------------- 1 | --- 2 | "create-jellycommands": minor 3 | --- 4 | 5 | breaking: require discord.js v14.15.3 or above 6 | -------------------------------------------------------------------------------- /.changeset/chatty-insects-whisper.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | 'jellycommands': patch 4 | --- 5 | 6 | update dependancies 7 | -------------------------------------------------------------------------------- /.changeset/dirty-wombats-sip.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | 'jellycommands': patch 4 | --- 5 | 6 | update to discord.js v14 7 | -------------------------------------------------------------------------------- /.changeset/famous-books-switch.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | 'jellycommands': patch 4 | --- 5 | 6 | update dependancies 7 | -------------------------------------------------------------------------------- /.changeset/gentle-flowers-tease.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | improve cahce by checking ids in cache not structure 6 | -------------------------------------------------------------------------------- /.changeset/lemon-walls-sin.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | (breaking) update props api to be typesafe and easier to use 6 | -------------------------------------------------------------------------------- /.changeset/light-boats-guess.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | this is a rerelease of last version, check changelog there 6 | -------------------------------------------------------------------------------- /.changeset/many-items-pull.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: use correct regex for validating slash command names 6 | -------------------------------------------------------------------------------- /.changeset/perfect-guests-eat.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | use applicationCommandData for hashId instead of options 6 | -------------------------------------------------------------------------------- /.changeset/spicy-waves-compare.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | make login method responsible for creating CommandManager 6 | -------------------------------------------------------------------------------- /.changeset/angry-mice-explode.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | breaking: require node v20.13.1 or above (drops node 16 & 18) 6 | -------------------------------------------------------------------------------- /.changeset/lemon-eggs-grow.md: -------------------------------------------------------------------------------- 1 | --- 2 | "create-jellycommands": patch 3 | "jellycommands": patch 4 | --- 5 | 6 | chore: update jsdoc comments 7 | -------------------------------------------------------------------------------- /.changeset/plenty-rats-look.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": minor 3 | --- 4 | 5 | feat: add option to control the file extensions that are allowed 6 | -------------------------------------------------------------------------------- /.changeset/violet-ways-reply.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | --- 4 | 5 | windows doesn't like the \* character so replace with \_ 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | dist 4 | .jellycommands 5 | .changeset/*.md 6 | .changeset/pre.json 7 | pnpm-lock.yaml 8 | .astro/ 9 | -------------------------------------------------------------------------------- /.changeset/sharp-shirts-think.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | updates discord-api-types (and other deps) - fixes incorrect typings 6 | -------------------------------------------------------------------------------- /.changeset/witty-geese-deliver.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'create-jellycommands': patch 3 | 'jellycommands': patch 4 | --- 5 | 6 | update non-minor dependancies 7 | -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/button-failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/button-failed.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/color-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/color-command.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/modal-failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/modal-failed.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/user-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/user-command.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/working-modal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/working-modal.png -------------------------------------------------------------------------------- /.changeset/angry-panthers-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": patch 3 | --- 4 | 5 | fix: skip any exports which aren't components, rather than erroring 6 | -------------------------------------------------------------------------------- /.changeset/chilled-avocados-speak.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | add errors to props.get, props.set, props.has to aid in migration 6 | -------------------------------------------------------------------------------- /.changeset/cool-mugs-knock.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | change `nameLocalizations` & `descriptionLocalizations` to a partial type 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "esbenp.prettier-vscode", 4 | "biomejs.biome", 5 | "astro-build.astro-vscode" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/message-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/message-command.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/working-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/working-button.png -------------------------------------------------------------------------------- /.changeset/large-spoons-move.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': patch 3 | --- 4 | 5 | switch slash commands from CommandInteraction to ChatInputCommandInteraction 6 | -------------------------------------------------------------------------------- /.changeset/tiny-elephants-sing.md: -------------------------------------------------------------------------------- 1 | --- 2 | "jellycommands": minor 3 | --- 4 | 5 | feat: support a non-empty DEBUG environment variable to enable debug logs 6 | -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/channel-id-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/channel-id-command.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/channel-update-event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/channel-update-event.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/create-a-button-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/create-a-button-command.png -------------------------------------------------------------------------------- /packages/docs/src/assets/docs/event-arg-intellisense.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostdevv/jellycommands/HEAD/packages/docs/src/assets/docs/event-arg-intellisense.png -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // See https://jellycommands.dev/components/props 4 | interface Props {} 5 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/src/app.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // See https://jellycommands.dev/components/props 4 | interface Props {} 5 | -------------------------------------------------------------------------------- /.changeset/silent-hounds-teach.md: -------------------------------------------------------------------------------- 1 | --- 2 | 'jellycommands': minor 3 | --- 4 | 5 | breaking: remove options.commands, options.events, and options.buttons in favour of single options.components 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Discord Server 3 | url: https://discord.gg/2Vd4wAjJnm 4 | about: Come join the discord to talk and get help with your code! 5 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/src/components/ready.js: -------------------------------------------------------------------------------- 1 | import { event } from 'jellycommands'; 2 | 3 | export default event({ 4 | name: 'clientReady', 5 | run: (_, client) => console.log(client.user.tag, 'is online!'), 6 | }); 7 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/src/components/ready.ts: -------------------------------------------------------------------------------- 1 | import { event } from 'jellycommands'; 2 | 3 | export default event({ 4 | name: 'clientReady', 5 | run: (_, client) => console.log(client.user.tag, 'is online!'), 6 | }); 7 | -------------------------------------------------------------------------------- /packages/playground/src/events/ready.js: -------------------------------------------------------------------------------- 1 | import { event } from 'jellycommands'; 2 | 3 | export default event({ 4 | name: 'ready', 5 | 6 | once: true, 7 | 8 | run: () => { 9 | console.log('Online'); 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "quoteProps": "as-needed", 4 | "trailingComma": "all", 5 | "bracketSpacing": true, 6 | "arrowParens": "always", 7 | "semi": true, 8 | "useTabs": true, 9 | "tabWidth": 4 10 | } 11 | -------------------------------------------------------------------------------- /packages/docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strictest", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "$assets/*": ["./src/assets/*"], 7 | "$lib/*": ["./src/lib/*"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/playground/src/events/file-loaded/messageCreate.js: -------------------------------------------------------------------------------- 1 | import { event } from 'jellycommands'; 2 | 3 | export default event({ 4 | name: 'messageCreate', 5 | 6 | once: false, 7 | 8 | run: () => { 9 | console.log('10-4'); 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/playground/src/buttons/test.js: -------------------------------------------------------------------------------- 1 | import { button } from 'jellycommands'; 2 | 3 | export default button({ 4 | id: 'test', 5 | 6 | async run({ interaction }) { 7 | interaction.reply({ 8 | content: 'Hello World', 9 | }); 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "$mock": ["./mock.ts"], 7 | "$src/*": ["../src/*"], 8 | "$src": ["../src"] 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/src/components/hello.js: -------------------------------------------------------------------------------- 1 | import { button } from 'jellycommands'; 2 | 3 | export default button({ 4 | id: 'hello', 5 | 6 | async run({ interaction }) { 7 | interaction.reply({ 8 | content: 'Hello from a button!', 9 | }); 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/src/components/hello.ts: -------------------------------------------------------------------------------- 1 | import { button } from 'jellycommands'; 2 | 3 | export default button({ 4 | id: 'hello', 5 | 6 | async run({ interaction }) { 7 | interaction.reply({ 8 | content: 'Hello from a button!', 9 | }); 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/playground/src/modals/test.js: -------------------------------------------------------------------------------- 1 | import { modal } from 'jellycommands'; 2 | 3 | export default modal({ 4 | id: 'test', 5 | 6 | async run({ interaction }) { 7 | interaction.reply({ 8 | content: `Hello, ${interaction.fields.getTextInputValue('nameInput')}`, 9 | }); 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/messageCommand.js: -------------------------------------------------------------------------------- 1 | import { messageCommand } from 'jellycommands'; 2 | 3 | export default messageCommand({ 4 | name: 'test', 5 | 6 | global: true, 7 | 8 | dev: true, 9 | 10 | run: ({ interaction }) => { 11 | interaction.reply({ content: 'Hello World :o' }); 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/userCommand.js: -------------------------------------------------------------------------------- 1 | import { userCommand } from 'jellycommands'; 2 | 3 | export default userCommand({ 4 | name: 'Hello World', 5 | 6 | global: true, 7 | 8 | dev: true, 9 | 10 | run: ({ interaction }) => { 11 | interaction.reply({ content: `Hello ${interaction.user.tag}` }); 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/docs/src/content.config.ts: -------------------------------------------------------------------------------- 1 | import { docsLoader } from '@astrojs/starlight/loaders'; 2 | import { docsSchema } from '@astrojs/starlight/schema'; 3 | import { defineCollection } from 'astro:content'; 4 | 5 | export const collections = { 6 | docs: defineCollection({ 7 | loader: docsLoader(), 8 | schema: docsSchema(), 9 | }), 10 | }; 11 | -------------------------------------------------------------------------------- /packages/jellycommands/src/components/commands/types/userCommands/options.ts: -------------------------------------------------------------------------------- 1 | import { baseCommandSchema } from '../../../commands/types/options'; 2 | import type { BaseOptions } from '../../../commands/types/options'; 3 | 4 | export interface UserCommandOptions extends BaseOptions {} 5 | 6 | export const userCommandSchema = baseCommandSchema.extend({}); 7 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/globalTest.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | 3 | export default command({ 4 | name: 'globaltest', 5 | description: 'A testing command bound to global', 6 | 7 | global: true, 8 | 9 | run: ({ interaction }) => 10 | interaction.reply({ embeds: [{ description: 'global test' }] }), 11 | }); 12 | -------------------------------------------------------------------------------- /packages/create-jellycommands/README.md: -------------------------------------------------------------------------------- 1 | # Create JellyCommands 2 | 3 | This is the package for the official [jellycommands](https://github.com/ghostdevv/jellycommands) project creation cli, you can checkout the [main repo here](https://github.com/ghostdevv/jellycommands) 4 | 5 | # Use CLI 6 | 7 | ```bash 8 | npm create jellycommands my-project 9 | ``` 10 | -------------------------------------------------------------------------------- /packages/jellycommands/src/components/commands/types/messageCommands/options.ts: -------------------------------------------------------------------------------- 1 | import { baseCommandSchema } from '../../../commands/types/options'; 2 | import type { BaseOptions } from '../../../commands/types/options'; 3 | 4 | export interface MessageCommandOptions extends BaseOptions {} 5 | 6 | export const messageCommandSchema = baseCommandSchema.extend({}); 7 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "dev": "node --watch src/index.js", 5 | "start": "node src/index.js" 6 | }, 7 | "dependencies": { 8 | "discord.js": "^14.23.2", 9 | "dotenv": "^17.2.3", 10 | "jellycommands": "1.0.0-next.45" 11 | }, 12 | "engines": { 13 | "node": ">=20.13.1" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/jellycommands/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from 'tsup'; 2 | 3 | export const tsup: Options = { 4 | splitting: false, 5 | sourcemap: false, 6 | clean: true, 7 | dts: true, 8 | keepNames: true, 9 | target: 'esnext', 10 | format: ['esm', 'cjs'], 11 | entryPoints: ['src/index.ts'], 12 | shims: true, 13 | noExternal: [/^[a-zA-Z]:/], 14 | }; 15 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.6.3/schema.json", 3 | "changelog": [ 4 | "@svitejs/changesets-changelog-github-compact", 5 | { 6 | "repo": "ghostdevv/jellycommands" 7 | } 8 | ], 9 | "commit": false, 10 | "linked": [], 11 | "access": "public", 12 | "baseBranch": "main", 13 | "updateInternalDependencies": "patch" 14 | } 15 | -------------------------------------------------------------------------------- /packages/jellycommands/src/components/commands/types/types.d.ts: -------------------------------------------------------------------------------- 1 | import type { MessageCommand } from './messageCommands/MessageCommand'; 2 | import type { UserCommand } from './userCommands/UserCommand'; 3 | import type { Command } from './commands/Command'; 4 | import type { BaseCommand } from './BaseCommand'; 5 | 6 | export type AnyCommand = BaseCommand | Command | UserCommand | MessageCommand; 7 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/_hiddenCommand.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | 3 | export default command({ 4 | name: 'hidden', 5 | description: "you shouldn't be seeing this", 6 | 7 | global: true, 8 | 9 | dev: true, 10 | 11 | run: ({ interaction }) => 12 | interaction.reply({ 13 | embeds: [{ description: 'Peek-a-boo!' }], 14 | }), 15 | }); 16 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/dmBlockedGlobal.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | 3 | export default command({ 4 | name: 'dmblockglobal', 5 | description: "I am a global command that shouldn't work in dm", 6 | 7 | global: true, 8 | dm: false, 9 | 10 | run: ({ interaction }) => 11 | interaction.reply({ embeds: [{ description: 'global test' }] }), 12 | }); 13 | -------------------------------------------------------------------------------- /packages/jellycommands/src/components/commands/types.d.ts: -------------------------------------------------------------------------------- 1 | import type { AnyCommand } from './types/types'; 2 | 3 | export type GlobalCommands = Set; 4 | export type GuildCommands = Map>; 5 | 6 | export type CommandIDMap = Map; 7 | 8 | export interface ResolvedCommands { 9 | guildCommands: GuildCommands; 10 | globalCommands: GlobalCommands; 11 | commands: Set; 12 | } 13 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/guildTest.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | 3 | export default command({ 4 | name: 'guildtest', 5 | description: 'A testing command bound to guild not global', 6 | 7 | guilds: [process.env.TEST_GUILD], 8 | 9 | dev: true, 10 | 11 | guards: { 12 | permissions: ['Administrator'], 13 | }, 14 | 15 | run: ({ interaction }) => 16 | interaction.reply({ embeds: [{ description: 'as' }] }), 17 | }); 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Checklist 4 | 5 | - [ ] Related issue: 6 | - [ ] Changesets done 7 | - [ ] Docs Updated 8 | - [ ] Tests Added 9 | 10 | ### Body 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/create-jellycommands/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "ESNext", 5 | "target": "ESNext", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "moduleResolution": "node", 9 | "resolveJsonModule": true, 10 | "strict": true, 11 | "checkJs": true, 12 | "allowJs": true 13 | }, 14 | "include": ["./src/**/*.js"], 15 | "exclude": ["./src/js/**", "./src/ts/**", "node_modules/**"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/jellycommands/src/plugins/core.ts: -------------------------------------------------------------------------------- 1 | import { commandsPlugin } from '../components/commands/plugin'; 2 | import { buttonsPlugin } from '../components/buttons/plugin'; 3 | import { eventsPlugin } from '../components/events/plugin'; 4 | import { modalsPlugin } from '../components/modals/plugin'; 5 | import type { AnyPlugin } from './plugins'; 6 | 7 | export const CORE_PLUGINS: AnyPlugin[] = [ 8 | buttonsPlugin, 9 | commandsPlugin, 10 | eventsPlugin, 11 | modalsPlugin, 12 | ]; 13 | -------------------------------------------------------------------------------- /packages/playground/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "ESNext", 5 | "target": "ESNext", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "moduleResolution": "node", 9 | "resolveJsonModule": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "checkJs": true, 13 | "allowJs": true 14 | }, 15 | "include": ["./src/**/*.js", "./src/**/*.ts"], 16 | "exclude": ["node_modules/**"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "scripts": { 4 | "dev": "tsx --watch src/index.ts", 5 | "start": "tsx src/index.ts" 6 | }, 7 | "dependencies": { 8 | "discord.js": "^14.23.2", 9 | "dotenv": "^17.2.3", 10 | "jellycommands": "1.0.0-next.45", 11 | "typescript": "^5.9.3" 12 | }, 13 | "devDependencies": { 14 | "@types/node": "^20.12.11", 15 | "tsx": "^4.20.6" 16 | }, 17 | "engines": { 18 | "node": ">=20.13.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "ESNext", 5 | "target": "ESNext", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "moduleResolution": "node", 9 | "resolveJsonModule": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "checkJs": true, 13 | "allowJs": true 14 | }, 15 | "include": ["./src/**/*.js", "./src/**/*.ts"], 16 | "exclude": ["node_modules/**"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ESNext"], 4 | "module": "ESNext", 5 | "target": "ESNext", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "moduleResolution": "node", 9 | "resolveJsonModule": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "checkJs": true, 13 | "allowJs": true 14 | }, 15 | "include": ["./src/**/*.js", "./src/**/*.ts"], 16 | "exclude": ["node_modules/**"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/zod.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'vitest'; 2 | import { parseSchema } from '$src/utils/zod'; 3 | import { z } from 'zod'; 4 | 5 | describe('zod utils', () => { 6 | it('parses schema', () => { 7 | const now = Date.now(); 8 | const result = parseSchema('test', z.number(), now); 9 | 10 | expect(result).toBe(now); 11 | }); 12 | 13 | it('throws on invalid data', () => { 14 | expect(() => parseSchema('test', z.string(), 10)).toThrowError(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/jellycommands/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | import { dirname, join } from 'node:path'; 3 | import { fileURLToPath } from 'node:url'; 4 | 5 | const __dirname = dirname(fileURLToPath(import.meta.url)); 6 | 7 | export default defineConfig({ 8 | test: { 9 | alias: { 10 | $src: join(__dirname, './src'), 11 | $mock: join(__dirname, './tests/mock.ts'), 12 | }, 13 | include: ['tests/**/*.test.ts'], 14 | unstubEnvs: true, 15 | mockReset: true, 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/token/clientIdFromToken.test.ts: -------------------------------------------------------------------------------- 1 | import { clientIdFromToken } from '$src/utils/token'; 2 | import { mockToken, rawClientId } from '$mock'; 3 | import { describe, it, expect } from 'vitest'; 4 | 5 | describe('parse client id from token', () => { 6 | it('works', () => { 7 | const result = clientIdFromToken(mockToken); 8 | expect(result).toBe(rawClientId); 9 | }); 10 | 11 | it('returns null on invalid id', () => { 12 | expect(clientIdFromToken('empty')).toBeNull(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/playground/src/commands/pog.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | 3 | export default command({ 4 | name: 'pog', 5 | description: 'champ', 6 | 7 | global: true, 8 | 9 | options: [ 10 | { 11 | type: 'Channel', 12 | name: 'channel', 13 | description: 'Channel to pog', 14 | required: true, 15 | }, 16 | ], 17 | 18 | dev: true, 19 | dm: false, 20 | 21 | run: ({ interaction }) => 22 | interaction.reply({ 23 | embeds: [{ description: '🔥🔥🔥🔥 CCChaaaaammmmpppppp 🔥🔥🔥🔥' }], 24 | }), 25 | }); 26 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", 3 | "vcs": { 4 | "enabled": true, 5 | "clientKind": "git", 6 | "useIgnoreFile": true 7 | }, 8 | "files": { 9 | "ignore": ["packages/create-jellycommands/**/app.d.ts"] 10 | }, 11 | "formatter": { 12 | "enabled": false 13 | }, 14 | "organizeImports": { 15 | "enabled": false 16 | }, 17 | "linter": { 18 | "enabled": true, 19 | "rules": { 20 | "recommended": true, 21 | "suspicious": { 22 | "noExplicitAny": "off" 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/jellycommands/src/utils/zod.ts: -------------------------------------------------------------------------------- 1 | import type { z } from 'zod'; 2 | 3 | export function parseSchema( 4 | name: string, 5 | schema: T, 6 | data: unknown, 7 | ): z.infer { 8 | const result = schema.safeParse(data); 9 | if (result.success) return result.data; 10 | 11 | const formattedError = result.error.errors 12 | .map((e) => ` => [${e.path.join(' -> ')}] (${e.code}) ${e.message}`) 13 | .join('\n'); 14 | 15 | throw new TypeError( 16 | `Error parsing schema for ${name}:\n${formattedError}\n`, 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /packages/jellycommands/src/utils/snowflake.ts: -------------------------------------------------------------------------------- 1 | import { SnowflakeUtil } from 'discord.js'; 2 | import { z } from 'zod'; 3 | 4 | export function isSnowflake(id: any): id is string { 5 | try { 6 | SnowflakeUtil.deconstruct(id); 7 | return true; 8 | } catch { 9 | return false; 10 | } 11 | } 12 | 13 | export const snowflakeSchema = z 14 | .string({ 15 | invalid_type_error: 'Snowflake ids should be given as a string', 16 | required_error: 'Must give a valid Snowflake id', 17 | }) 18 | .min(18, { message: 'Discord Snowflake ids are at least 18 chars' }); 19 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/version.js: -------------------------------------------------------------------------------- 1 | import { compare, parse } from './semver.js'; 2 | 3 | /** 4 | * Check whether an update is available 5 | * @param {string} currentVersion 6 | */ 7 | export async function checkForUpdate(currentVersion) { 8 | try { 9 | const res = await fetch('https://npm.antfu.dev/create-jellycommands'); 10 | const data = /** @type {{ version: string }} */ (await res.json()); 11 | 12 | return { 13 | available: 14 | compare(parse(data.version), parse(currentVersion)) === 1, 15 | version: data.version, 16 | }; 17 | } catch { 18 | return null; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@jellycommands/playground", 3 | "private": true, 4 | "version": "0.1.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "node --watch src/index.js" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "catalog:", 11 | "discord.js": "^14.23.2", 12 | "dotenv": "^17.2.3", 13 | "jellycommands": "workspace:*" 14 | }, 15 | "packageManager": "pnpm@10.18.3", 16 | "engines": { 17 | "pnpm": "^10.18.3", 18 | "npm": "forbidden, use pnpm", 19 | "node": ">=20.13.1" 20 | }, 21 | "volta": { 22 | "node": "20.13.1", 23 | "pnpm": "10.18.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/jellycommands/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "esnext", 5 | "lib": ["es2023"], 6 | "moduleResolution": "Bundler", 7 | 8 | "strict": true, 9 | "strictNullChecks": true, 10 | "noImplicitReturns": true, 11 | "noImplicitThis": true, 12 | "noImplicitAny": true, 13 | "esModuleInterop": true, 14 | "exactOptionalPropertyTypes": false, 15 | "forceConsistentCasingInFileNames": true, 16 | "skipLibCheck": true, 17 | "noEmit": true, 18 | "declaration": false, 19 | "verbatimModuleSyntax": true 20 | }, 21 | "include": ["src/**/*.ts", "ambient.d.ts", "tests/**/*.ts"], 22 | "exclude": ["node_modules/**", "dist/**"] 23 | } 24 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/src/components/test.ts: -------------------------------------------------------------------------------- 1 | import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; 2 | import { command } from 'jellycommands'; 3 | 4 | export default command({ 5 | name: 'test', 6 | description: 'Testing that the bot works fine', 7 | 8 | global: true, 9 | 10 | run: ({ interaction }) => { 11 | const row = new ActionRowBuilder(); 12 | 13 | const button = new ButtonBuilder() 14 | .setCustomId('hello') 15 | .setLabel('Click me!') 16 | .setStyle(ButtonStyle.Primary); 17 | 18 | row.addComponents(button); 19 | 20 | interaction.reply({ 21 | content: 'Hello, world!', 22 | components: [row], 23 | }); 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/testButton.js: -------------------------------------------------------------------------------- 1 | import { ButtonBuilder, ActionRowBuilder, ButtonStyle } from 'discord.js'; 2 | import { command } from 'jellycommands'; 3 | 4 | export default command({ 5 | name: 'testbutton', 6 | description: 'Test the buttons', 7 | 8 | global: true, 9 | defer: true, 10 | 11 | async run({ interaction }) { 12 | const row = new ActionRowBuilder().addComponents( 13 | new ButtonBuilder() 14 | .setCustomId('test') 15 | .setLabel('test') 16 | .setStyle(ButtonStyle.Primary), 17 | ); 18 | 19 | interaction.followUp({ 20 | content: 'Test Buttons', 21 | components: [ 22 | // @ts-ignore 23 | row, 24 | ], 25 | }); 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /packages/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@jellycommands/docs", 3 | "private": true, 4 | "type": "module", 5 | "version": "0.1.0", 6 | "scripts": { 7 | "dev": "astro dev", 8 | "build": "astro build", 9 | "lint": "astro check" 10 | }, 11 | "devDependencies": { 12 | "@astrojs/check": "^0.9.4", 13 | "@astrojs/starlight": "^0.36.1", 14 | "astro": "^5.14.6", 15 | "sharp": "^0.34.4", 16 | "starlight-links-validator": "^0.19.0", 17 | "typescript": "^5.9.3" 18 | }, 19 | "packageManager": "pnpm@10.18.3", 20 | "engines": { 21 | "pnpm": "^10.18.3", 22 | "npm": "forbidden, use pnpm", 23 | "node": ">=20.13.1" 24 | }, 25 | "volta": { 26 | "node": "20.13.1", 27 | "pnpm": "10.18.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/README.md: -------------------------------------------------------------------------------- 1 | # Create JellyCommands 2 | 3 | This project was created with `npm create jellycommands`! 4 | 5 | # Get Started 6 | 7 | You need to make sure you have your `.env` file, this is where you will put your discord bot token. You can see how that should look from the `.env.example` file. 8 | 9 | ```bash 10 | cp .env.example .env 11 | ``` 12 | 13 | # Commands 14 | 15 | `npm run ` 16 | 17 | | Command | Description | 18 | | ------- | ------------------------------------------------------ | 19 | | dev | You can use this command when developing your bot | 20 | | start | When you host/run your bot you should use this command | 21 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/README.md: -------------------------------------------------------------------------------- 1 | # Create JellyCommands 2 | 3 | This project was created with `npm create jellycommands`! 4 | 5 | # Get Started 6 | 7 | You need to make sure you have your `.env` file, this is where you will put your discord bot token. You can see how that should look from the `.env.example` file. 8 | 9 | ```bash 10 | cp .env.example .env 11 | ``` 12 | 13 | # Commands 14 | 15 | `npm run ` 16 | 17 | | Command | Description | 18 | | ------- | ------------------------------------------------------ | 19 | | dev | You can use this command when developing your bot | 20 | | start | When you host/run your bot you should use this command | 21 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/src/components/test.js: -------------------------------------------------------------------------------- 1 | import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; 2 | import { command } from 'jellycommands'; 3 | 4 | export default command({ 5 | name: 'test', 6 | description: 'Testing that the bot works fine', 7 | 8 | global: true, 9 | 10 | run: ({ interaction }) => { 11 | /** @type {ActionRowBuilder} */ 12 | const row = new ActionRowBuilder(); 13 | 14 | const button = new ButtonBuilder() 15 | .setCustomId('hello') 16 | .setLabel('Click me!') 17 | .setStyle(ButtonStyle.Primary); 18 | 19 | row.addComponents(button); 20 | 21 | interaction.reply({ 22 | content: 'Hello, world!', 23 | components: [row], 24 | }); 25 | }, 26 | }); 27 | -------------------------------------------------------------------------------- /packages/jellycommands/src/components/events/options.ts: -------------------------------------------------------------------------------- 1 | import type { BaseComponentOptions } from '../components'; 2 | import type { EventName } from './Event'; 3 | 4 | export interface EventOptions 5 | extends BaseComponentOptions { 6 | /** 7 | * The Discord event name 8 | * @see https://discord.js.org/docs/packages/discord.js/14.16.3/ClientEvents:Interface 9 | */ 10 | name: Event; 11 | 12 | /** 13 | * Should the event be ran once or every time it's received 14 | * @default false 15 | */ 16 | once?: boolean; 17 | } 18 | 19 | import { z } from 'zod'; 20 | 21 | export const eventSchema = z.object({ 22 | name: z.string() as z.ZodType, 23 | disabled: z.boolean().default(false), 24 | once: z.boolean().default(false), 25 | }); 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: 'Feature Request' 2 | description: Request a new feature in JellyCommands 3 | labels: [enhancement] 4 | body: 5 | - type: textarea 6 | id: description 7 | attributes: 8 | label: Describe the feature 9 | description: A detailed description of the feature would be awesome, but not required. 10 | placeholder: I want x because... 11 | validations: 12 | required: false 13 | 14 | - type: textarea 15 | id: example 16 | attributes: 17 | label: Examples 18 | description: Some examples of where this feature can be seen in the wild. 19 | placeholder: Command handler x has this because y... 20 | validations: 21 | required: false 22 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/token/resolveClientId.test.ts: -------------------------------------------------------------------------------- 1 | import { resolveClientId } from '$src/utils/token'; 2 | import { mockClient, rawClientId } from '$mock'; 3 | import { describe, expect, it } from 'vitest'; 4 | 5 | describe('resolves client id', () => { 6 | it('gets the client id', () => { 7 | expect(resolveClientId(mockClient())).toBe(rawClientId); 8 | }); 9 | 10 | it('gets the client id from the token', () => { 11 | const client = mockClient(); 12 | client.user = null; 13 | 14 | expect(resolveClientId(client)).toBe(rawClientId); 15 | }); 16 | 17 | it('returns null if unable to find', () => { 18 | const client = mockClient(); 19 | client.user = null; 20 | client.token = null; 21 | 22 | expect(resolveClientId(client)).toBeNull(); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/jellycommands/src/components/events/plugin.ts: -------------------------------------------------------------------------------- 1 | import { defineComponentPlugin } from '../../plugins/plugins'; 2 | import type { Event } from './Event'; 3 | 4 | export const EVENTS_COMPONENT_ID = 'jellycommands.event'; 5 | 6 | export const eventsPlugin = defineComponentPlugin(EVENTS_COMPONENT_ID, { 7 | register(client, events) { 8 | for (const event of events) { 9 | async function cb(...ctx: any[]) { 10 | try { 11 | await event.run({ client, props: client.props }, ...ctx); 12 | } catch (error) { 13 | console.error( 14 | `There was an error running event ${event.name}`, 15 | error, 16 | ); 17 | } 18 | } 19 | 20 | event.options.once 21 | ? client.once(event.name, cb) 22 | : client.on(event.name, cb); 23 | } 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/token/cleanToken.test.ts: -------------------------------------------------------------------------------- 1 | import { cleanToken } from '$src/utils/token'; 2 | import { describe, it, expect } from 'vitest'; 3 | import { mockToken } from '$mock'; 4 | 5 | describe('cleans a discord token', () => { 6 | it('strips bot prefixes', () => { 7 | const result = cleanToken(`Bot ${mockToken}`); 8 | expect(result).toBe(mockToken); 9 | }); 10 | 11 | it('strips bearer prefixes', () => { 12 | const result = cleanToken(`Bearer ${mockToken}`); 13 | expect(result).toBe(mockToken); 14 | }); 15 | 16 | it('applies has no prefix', () => { 17 | const result = cleanToken(mockToken); 18 | expect(result).toBe(mockToken); 19 | }); 20 | 21 | it('accepts no token', () => { 22 | const result = cleanToken(); 23 | expect(result).toBeNull(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/token/resolveToken.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it, vi } from 'vitest'; 2 | import { resolveToken } from '$src/utils/token'; 3 | import { mockClient, mockToken } from '$mock'; 4 | 5 | describe('resolve token from client', () => { 6 | it('gets the token', () => { 7 | expect(resolveToken(mockClient())).toBe(mockToken); 8 | }); 9 | 10 | it('gets the token from environment vars', () => { 11 | const client = mockClient(); 12 | client.token = null; 13 | 14 | vi.stubEnv('DISCORD_TOKEN', mockToken); 15 | 16 | expect(resolveToken(client)).toBe(mockToken); 17 | }); 18 | 19 | it('returns null if unable to get token', () => { 20 | const client = mockClient(); 21 | client.token = null; 22 | 23 | expect(resolveToken(client)).toBeNull(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/copy.js: -------------------------------------------------------------------------------- 1 | import { cp, rename, readdir } from 'node:fs/promises'; 2 | import { join } from 'node:path'; 3 | 4 | /** 5 | * Copy a directory to a new location. 6 | * Files that bein with _ will have it replaced with a period. 7 | * 8 | * @param {string} from - The source directory path. 9 | * @param {string} to - The destination directory path. 10 | */ 11 | export async function copy(from, to) { 12 | await cp(from, to, { recursive: true }); 13 | 14 | const files = await readdir(to, { 15 | withFileTypes: true, 16 | recursive: true, 17 | }); 18 | 19 | for (const file of files) { 20 | if (file.name.startsWith('_')) { 21 | await rename( 22 | join(file.parentPath, file.name), 23 | join(file.parentPath, `.${file.name.slice(1)}`), 24 | ); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/js/src/index.js: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import { JellyCommands } from 'jellycommands'; 3 | import { IntentsBitField } from 'discord.js'; 4 | 5 | const client = new JellyCommands({ 6 | // https://jellycommands.dev/components 7 | components: 'src/components', 8 | 9 | clientOptions: { 10 | intents: [IntentsBitField.Flags.Guilds], 11 | }, 12 | 13 | dev: { 14 | // In testing we should enable this, it will make all our commands register in our testing guild 15 | // https://jellycommands.dev/components/commands/dev 16 | global: true, 17 | 18 | // Put your testing guild id here 19 | // https://jellycommands.dev/components/commands/dev 20 | guilds: [''], 21 | }, 22 | }); 23 | 24 | // Automatically reads the DISCORD_TOKEN environment variable 25 | client.login(); 26 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/ts/src/index.ts: -------------------------------------------------------------------------------- 1 | import 'dotenv/config'; 2 | import { JellyCommands } from 'jellycommands'; 3 | import { IntentsBitField } from 'discord.js'; 4 | 5 | const client = new JellyCommands({ 6 | // https://jellycommands.dev/components 7 | components: 'src/components', 8 | 9 | clientOptions: { 10 | intents: [IntentsBitField.Flags.Guilds], 11 | }, 12 | 13 | dev: { 14 | // In testing we should enable this, it will make all our commands register in our testing guild 15 | // https://jellycommands.dev/components/commands/dev 16 | global: true, 17 | 18 | // Put your testing guild id here 19 | // https://jellycommands.dev/components/commands/dev 20 | guilds: [''], 21 | }, 22 | }); 23 | 24 | // Automatically reads the DISCORD_TOKEN environment variable 25 | client.login(); 26 | -------------------------------------------------------------------------------- /packages/docs/src/content/docs/guides/messages.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Messages 3 | description: Covers how you can customise the default JellyCommands responses. 4 | --- 5 | 6 | :::caution 7 | This feature [**may** be removed](https://github.com/ghostdevv/jellycommands/issues/218) in a feature pre-release. 8 | ::: 9 | 10 | `messages` are used to customise `JellyCommands` responses. 11 | 12 | ## Unknown Command 13 | 14 | If JellyCommands recieves an unknown command, it will respond to it with a configurable message. This can be set with the `unknownCommand` option. For example: 15 | 16 | ```js 17 | const client = new JellyCommands({ 18 | messages: { 19 | unknownCommand: { 20 | embeds: [ 21 | { 22 | color: 'RANDOM', 23 | title: 'Unknown Command', 24 | }, 25 | ], 26 | }, 27 | }, 28 | }); 29 | ``` 30 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/localise.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | 3 | export default command({ 4 | name: 'localised', 5 | description: 'testing localisations', 6 | 7 | nameLocalizations: { 8 | de: 'spiel', 9 | }, 10 | 11 | descriptionLocalizations: { 12 | de: 'wir spielen', 13 | }, 14 | 15 | options: [ 16 | { 17 | name: 'play', 18 | type: 'String', 19 | nameLocalizations: { 20 | de: 'speil', 21 | }, 22 | description: 'play', 23 | descriptionLocalizations: { 24 | de: 'wir spielen', 25 | }, 26 | }, 27 | ], 28 | 29 | global: true, 30 | 31 | run: ({ interaction }) => { 32 | console.log({ 33 | locale: interaction.locale, 34 | glocale: interaction.guildLocale, 35 | }); 36 | interaction.reply({ embeds: [{ description: 'global test' }] }); 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /packages/create-jellycommands/src/bin.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { checkForUpdate } from './version.js'; 3 | import { readFile } from 'node:fs/promises'; 4 | import { dirname, join } from 'node:path'; 5 | import { fileURLToPath } from 'node:url'; 6 | import { intro } from '@clack/prompts'; 7 | import { run } from './index.js'; 8 | import pc from 'picocolors'; 9 | 10 | const dir = dirname(fileURLToPath(import.meta.url)); 11 | const pkg = await readFile(join(dir, '../package.json'), 'utf-8'); 12 | const currentVersion = JSON.parse(pkg).version; 13 | const update = await checkForUpdate(currentVersion); 14 | 15 | // prettier-ignore 16 | intro(`${pc.bold(pc.magenta('create-jellycommands'))} ${pc.dim(`v${currentVersion}`)} ${update?.available ? `=> ${pc.reset(pc.green(`v${update.version}`))} ${pc.dim('(Update Available)')}`: ''}`); 17 | 18 | await run(); 19 | -------------------------------------------------------------------------------- /packages/jellycommands/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ![](https://raw.githubusercontent.com/ghostdevv/jellycommands/main/assets/jellycommands-banner.png) 4 | 5 | `npm install jellycommands` 6 | 7 | [![](https://img.shields.io/npm/v/jellycommands?label=Latest%20Version&style=for-the-badge&logo=npm&color=informational)](https://www.npmjs.com/package/jellycommands) 8 | 9 |
10 | 11 | --- 12 | 13 |
14 | 15 | # What is JellyCommands 16 | 17 | Jellycommands is a developer experience focused command framework for discord.js. It has support for all types of application commands, including slash commands and context menus. It also includes quality of life features such as caching and developer mode. 18 | 19 | # Get Started 20 | 21 | The best way to get started is using our cli: 22 | 23 | ```bash 24 | npm create jellycommands my-project 25 | ``` 26 | 27 | # Documentation 28 | 29 | [You can view the documentation here](https://jellycommands.dev) 30 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/autocomplete.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | import { colors } from './_colors.js'; 3 | 4 | export default command({ 5 | name: 'rainbow', 6 | description: 'send a rainbow', 7 | 8 | global: true, 9 | 10 | options: [ 11 | { 12 | type: 'String', 13 | name: 'color', 14 | description: 'The color of the thing idk', 15 | required: true, 16 | autocomplete: true, 17 | }, 18 | ], 19 | 20 | dev: true, 21 | 22 | run: ({ interaction }) => 23 | interaction.reply(interaction.options.getString('color', true)), 24 | 25 | autocomplete: async ({ interaction }) => { 26 | const focused = interaction.options.getFocused(true); 27 | 28 | if (focused.name === 'color') { 29 | interaction.respond( 30 | colors 31 | .filter((color) => color.startsWith(focused.value)) 32 | .map((color) => ({ name: color, value: color })) 33 | .slice(0, 10), 34 | ); 35 | } 36 | }, 37 | }); 38 | -------------------------------------------------------------------------------- /packages/docs/src/content/docs/components/commands/caching.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Caching 3 | description: Learn about how command caching helps save you from Discord rate limits when developing 4 | --- 5 | 6 | When developing, you'll be restarting your bot repeatedly. This is a pain since you have to re-register your commands each time, which takes time and is rate limted by Discord. JellyCommands can help with this by caching your commands. It computes a hash of all your commands, and stores it locally to the `.jellycommands` folder (which you should add to your `.gitignore`). When your bot starts, it'll check if you've made any changes, and if so, will automatically re-register your commands! 7 | 8 | We **don't** recommend disabling cache, but if you want to, you can with the `cache` option: 9 | 10 | ```js {4} 11 | import { JellyCommands } from 'jellycommands'; 12 | 13 | const client = new JellyCommands({ 14 | cache: true, 15 | }); 16 | 17 | client.login(); 18 | ``` 19 | -------------------------------------------------------------------------------- /packages/docs/src/content/docs/components/commands/guards.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Guards 3 | description: Learn about protecting your commands with JellyCommands guards. 4 | --- 5 | 6 | Guards provide a good developer experience for protecting your commands. 7 | 8 | :::note 9 | At the moment, we use Discord's permissions system. We'd like to support local guards in the future! 10 | ::: 11 | 12 | ## Permissions 13 | 14 | You can specify which users are permitted to use a command by referencing their guild permissions. 15 | 16 | ```js {7-11} 17 | import { command } from 'jellycommands'; 18 | 19 | export default command({ 20 | name: 'commandname', 21 | description: 'A short description of what the command does', 22 | 23 | guards: { 24 | // This means only people with the Administrator 25 | // permission can use the command 26 | permissions: ['Administrator'], 27 | }, 28 | 29 | run: ({ interaction }) => { 30 | // Do something with interaction 31 | }, 32 | }); 33 | ``` 34 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/utils/snowflake.test.ts: -------------------------------------------------------------------------------- 1 | import { isSnowflake, snowflakeSchema } from '$src/utils/snowflake'; 2 | import { describe, expect, it } from 'vitest'; 3 | 4 | describe('snowflake schema', () => { 5 | it('parses valid snowflake', () => { 6 | const result = snowflakeSchema.safeParse('282839711834177537'); 7 | 8 | expect(result.success).toBe(true); 9 | expect(result.success && result.data).toBe('282839711834177537'); 10 | }); 11 | 12 | it('parses 19 digit snowflake', () => { 13 | const result = snowflakeSchema.safeParse('1162817990652346458'); 14 | 15 | expect(result.success).toBe(true); 16 | expect(result.success && result.data).toBe('1162817990652346458'); 17 | }); 18 | }); 19 | 20 | describe('snowflake utils', () => { 21 | it('works on valid snowflake', () => { 22 | expect(isSnowflake('282839711834177537')).toBe(true); 23 | }); 24 | 25 | it('fails on invalid snowflake', () => { 26 | expect(isSnowflake('empty')).toBe(false); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/jellycommands/tests/mock.ts: -------------------------------------------------------------------------------- 1 | import { JellyCommands } from '$src/JellyCommands'; 2 | import { Client } from 'discord.js'; 3 | import { vi } from 'vitest'; 4 | 5 | export const rawToken = 'ImAToken'; 6 | export const rawClientId = '843642576971759667'; 7 | 8 | export const encodedToken = Buffer.from(rawToken).toString('base64'); 9 | export const encodedClientId = Buffer.from(rawClientId).toString('base64'); 10 | 11 | export const mockToken = `${encodedClientId}.${encodedToken}`; 12 | 13 | export function mockClient() { 14 | const client = new Client({ intents: [] }); 15 | 16 | client.token = mockToken; 17 | // @ts-expect-error missing properties 18 | client.user = { id: rawClientId }; 19 | 20 | return client; 21 | } 22 | 23 | export function mockJellyClient() { 24 | const client = new JellyCommands({ 25 | clientOptions: { intents: [] }, 26 | }); 27 | 28 | client.token = encodedToken; 29 | // @ts-expect-error missing properties 30 | client.user = { id: rawClientId }; 31 | 32 | return client; 33 | } 34 | -------------------------------------------------------------------------------- /packages/playground/src/commands/file-loaded/testModal.js: -------------------------------------------------------------------------------- 1 | import { command } from 'jellycommands'; 2 | import { 3 | TextInputBuilder, 4 | TextInputStyle, 5 | ModalBuilder, 6 | ActionRowBuilder, 7 | } from 'discord.js'; 8 | 9 | export default command({ 10 | name: 'test-modal', 11 | description: 'Shows a modal with a text input', 12 | 13 | global: true, 14 | 15 | async run({ interaction }) { 16 | // Create a text input component with the builder 17 | const nameInput = new TextInputBuilder() 18 | .setCustomId('nameInput') 19 | .setLabel('Whats your name?') 20 | .setStyle(TextInputStyle.Short); 21 | 22 | // All components need to be in a "row" 23 | const row = /** @type {ActionRowBuilder} */ ( 24 | new ActionRowBuilder() 25 | ).addComponents(nameInput); 26 | 27 | // Create the actual modal 28 | const modal = new ModalBuilder() 29 | .setCustomId('test') 30 | .setTitle('Whats Your Name?') 31 | .addComponents(row); 32 | 33 | // Send the modal 34 | interaction.showModal(modal); 35 | }, 36 | }); 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2021 Willow Smith 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /patches/@astrojs__starlight.patch: -------------------------------------------------------------------------------- 1 | diff --git a/user-components/LinkCard.astro b/user-components/LinkCard.astro 2 | index 8cf6fbd90fd6eb128bdcdcd35731a252ef74c44a..a044e67d1023c618382b09a5299cf5abe1e54689 100644 3 | --- a/user-components/LinkCard.astro 4 | +++ b/user-components/LinkCard.astro 5 | @@ -1,13 +1,20 @@ 6 | --- 7 | import Icon from './Icon.astro'; 8 | import type { HTMLAttributes } from 'astro/types'; 9 | +import { getRouteBySlugParam } from '../utils/routing' 10 | 11 | interface Props extends Omit, 'title'> { 12 | - title: string; 13 | + title?: string; 14 | description?: string; 15 | } 16 | 17 | -const { title, description, ...attributes } = Astro.props; 18 | +const route = getRouteBySlugParam(Astro.props.href.replace(/^\//, '')) 19 | + 20 | +const { title = route?.entry.data.title, description = route?.entry.data.description, ...attributes } = Astro.props; 21 | + 22 | +if (!title) { 23 | + throw new Error('Starlight LinkCard requires a `title`, and one couldn\'t be determind from your `href`') 24 | +} 25 | --- 26 | 27 |