Skip to content

Commit

Permalink
New Architecture (#146)
Browse files Browse the repository at this point in the history
* feat: `Plugin` class and `createHandle` method

* feat: initial node adapter, remove nodejs package

* feat: initial cloudflare adapter

* feat: initial bun adapter

* feat: initial nextjs adapter

* refactor: use handlebars templates in create carbon package

* chore: formatting and clean up

* chore: use consistent indentation style in template

* refactor: remove need to pass client to linked roles plugin

* Update packages/create-carbon/package.json

Co-authored-by: Shadow <william.shadow@outlook.com>

* Revert "refactor: remove need to pass client to linked roles plugin"

This reverts commit cf924be.

* chore: add jsdocs

* chore: add jsdocs to adapters

* feat: add ability to protect routes

* refactor: improve carbon template

* feat: add ability to disable routes

* chore: formatting

* feat: add deploy linked roles route

* refactor: move internal error handling to handle

* fix: add client secret as a default to env template

* fix: env not being loaded in node.js template

* fix: typescript import issues in template

* fix: some routes not correctly responding with content

* refactor: replace `autoRegister` client option with `disableAutoRegister`

* refactor: move relative path resolution to use base url

* fix: trim and clean template output content

* refactor: change linked roles routes connect segment to verify-user

* fix: incorrect linked roles put metadata endpoint

* refactor: use tsc-watch in node.js template for dev script

* refactor: minor changes

* fix: next.js template issues

* fix: req url host issue related to proxy tunnel

* fix: more incorrect endpoints in linked roles plugin

* fix: carbon template linked roles checker key

* fix: cloudflare template missing files and dev flow

* refactor: update template readme

* refactor: rename nextjs to next in template plus minor fixes

* refactor: use separate secret for deploy endpoints

* refactor: new docs

* refactor: instead link to docs in readme template

* chore: update demo apps to use new carbon

* fix: some old href paths

* chore: add changeset

* chore: update linked roles plugin example

---------

Co-authored-by: Shadow <shadow@buape.com>
  • Loading branch information
apteryxxyz and thewilloftheshadow authored Oct 19, 2024
1 parent 7797395 commit 8b489db
Show file tree
Hide file tree
Showing 195 changed files with 3,416 additions and 3,395 deletions.
6 changes: 6 additions & 0 deletions .changeset/slow-lies-tease.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"create-carbon": minor
"@buape/carbon": minor
---

New Architecture
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ build/
.next/
.DS_Store
packages/*/docs/
website/content/*/api
website/.source
!packages/create-carbon/templates/**/.env*
website/content/api
website/.source
6 changes: 6 additions & 0 deletions apps/cloudo/.dev.vars.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
BASE_URL=
DEPLOY_SECRET=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_PUBLIC_KEY=
DISCORD_BOT_TOKEN=
3 changes: 3 additions & 0 deletions apps/cloudo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
.wrangler/
.dev.vars
8 changes: 6 additions & 2 deletions apps/cloudo/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Cloudo
## cloudo

Cloudo is our test bot that runs on CF workers, to test that Carbon functions correctly.
This is a [Discord](https://discord.dev) app made with [Carbon](https://carbon.buape.com) and generated with the [`create-carbon`](https://npmjs.com/create-carbon) tool.

To learn how to get started in development, deploy to production, or add commands, head over to the [documentation](https://carbon.buape.com/adapters/cloudflare) for your runtime.

If you need any assistance, you can join our [Discord](https://go.buape.com/carbon) and ask in the [`#support`](https://discord.com/channels/1280628625904894072/1280630704308486174) channel.
14 changes: 7 additions & 7 deletions apps/cloudo/package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{
"name": "demo-cloudo",
"type": "module",
"main": "./dist/src/index.js",
"private": true,
"type": "module",
"main": "./src/index.ts",
"scripts": {
"build": "wrangler deploy --dry-run",
"dev": "wrangler dev --port 3000",
"deploy": "wrangler deploy",
"dev": "wrangler deploy && wrangler tail"
"wrangler": "wrangler"
},
"dependencies": {
"@buape/carbon": "workspace:*"
},
"license": "MIT",
"devDependencies": {
"@cloudflare/workers-types": "4.20241004.0",
"wrangler": "3.80.1"
"@cloudflare/workers-types": "4.20241011.0",
"typescript": "5.6.3",
"wrangler": "3.81.0"
}
}
7 changes: 2 additions & 5 deletions apps/cloudo/src/commands/ping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,9 @@ import { Command, type CommandInteraction } from "@buape/carbon"

export default class PingCommand extends Command {
name = "ping"
description = "A simple ping command"
defer = false
description = "Replies with Pong!"

async run(interaction: CommandInteraction) {
return interaction.reply({
content: "Pong!"
})
await interaction.reply("Pong! Hello from cloudo!")
}
}
22 changes: 11 additions & 11 deletions apps/cloudo/src/commands/testing/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,27 @@ export default class ButtonCommand extends Command {
description = "A simple command with a button!"
defer = true

components = [PingButton]
components = [ClickMeButton]

async run(interaction: CommandInteraction) {
await interaction.reply({
content: "Pong!",
components: [new Row([new PingButton(), new Link()])]
content: "Look at this button!",
components: [new Row([new ClickMeButton(), new DocsButton()])]
})
}
}

class PingButton extends Button {
customId = "ping"
label = "Ping"
style = ButtonStyle.Primary as typeof Button.prototype.style
class ClickMeButton extends Button {
customId = "click-me"
label = "Click me!"
style = ButtonStyle.Primary

async run(interaction: ButtonInteraction) {
await interaction.reply({ content: "OMG YOU CLICKED THE BUTTON" })
await interaction.reply("You clicked the button!")
}
}

class Link extends LinkButton {
label = "Link"
url = "https://buape.com"
class DocsButton extends LinkButton {
label = "Carbon Documentation"
url = "https://carbon.buape.com"
}
35 changes: 35 additions & 0 deletions apps/cloudo/src/commands/testing/ephemeral.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {
Command,
type CommandInteraction,
CommandWithSubcommands
} from "@buape/carbon"

class EphemeralNoDefer extends Command {
name = "no-defer"
description = "Ephemeral test"
ephemeral = true
defer = false

async run(interaction: CommandInteraction): Promise<void> {
await interaction.reply({ content: "Ephemeral no defer" })
}
}

class EphemeralDefer extends Command {
name = "defer"
description = "Ephemeral test"
ephemeral = true
defer = true

async run(interaction: CommandInteraction): Promise<void> {
await interaction.reply({ content: "Ephemeral defer" })
}
}

export default class EphemeralCommand extends CommandWithSubcommands {
name = "ephemeral"
description = "Ephemeral test"
ephemeral = true

subcommands = [new EphemeralNoDefer(), new EphemeralDefer()]
}
29 changes: 14 additions & 15 deletions apps/cloudo/src/commands/testing/every_select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import {
type UserSelectMenuInteraction
} from "@buape/carbon"

export default class SelectCommand extends Command {
name = "every_select"
export default class EverySelectCommand extends Command {
name = "every-select"
description = "Send every select menu"
defer = true

Expand All @@ -28,16 +28,15 @@ export default class SelectCommand extends Command {
]

async run(interaction: CommandInteraction) {
const row = new Row()
row.addComponent(new StringSelect())
row.addComponent(new RoleSelect())
row.addComponent(new MentionableSelect())
row.addComponent(new ChannelSelect())
row.addComponent(new UserSelect())
const stringRow = new Row([new StringSelect()])
const roleRow = new Row([new RoleSelect()])
const mentionableRow = new Row([new MentionableSelect()])
const channelRow = new Row([new ChannelSelect()])
const userRow = new Row([new UserSelect()])

interaction.reply({
await interaction.reply({
content: "Select menus!!",
components: [row]
components: [stringRow, roleRow, mentionableRow, channelRow, userRow]
})
}
}
Expand All @@ -47,35 +46,35 @@ class StringSelect extends StringSelectMenu {
placeholder = "String select menu"
options = [{ label: "Option 1", value: "option1" }]
async run(interaction: StringSelectMenuInteraction) {
interaction.reply({ content: interaction.values.join(", ") })
await interaction.reply({ content: interaction.values.join(", ") })
}
}

class RoleSelect extends RoleSelectMenu {
customId = "role-select"
placeholder = "Role select menu"
async run(interaction: RoleSelectMenuInteraction) {
interaction.reply({ content: interaction.values.join(", ") })
await interaction.reply({ content: interaction.values.join(", ") })
}
}
class MentionableSelect extends MentionableSelectMenu {
customId = "mentionable-select"
placeholder = "Mentionable select menu"
async run(interaction: MentionableSelectMenuInteraction) {
interaction.reply({ content: interaction.values.join(", ") })
await interaction.reply({ content: interaction.values.join(", ") })
}
}
class ChannelSelect extends ChannelSelectMenu {
customId = "channel-select"
placeholder = "Channel select menu"
async run(interaction: ChannelSelectMenuInteraction) {
interaction.reply({ content: interaction.values.join(", ") })
await interaction.reply({ content: interaction.values.join(", ") })
}
}
class UserSelect extends UserSelectMenu {
customId = "user-select"
placeholder = "User select menu"
async run(interaction: UserSelectMenuInteraction) {
interaction.reply({ content: interaction.values.join(", ") })
await interaction.reply({ content: interaction.values.join(", ") })
}
}
2 changes: 1 addition & 1 deletion apps/cloudo/src/commands/testing/message_command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ export default class MessageCommand extends Command {
type = ApplicationCommandType.Message

async run(interaction: CommandInteraction) {
interaction.reply({ content: "Message command" })
await interaction.reply({ content: "Message command" })
}
}
12 changes: 8 additions & 4 deletions apps/cloudo/src/commands/testing/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,14 @@ class TestModal extends Modal {
new Row([new TextInputHeight()])
]

run(interaction: ModalInteraction) {
return interaction.reply({
content: `Hi ${interaction.fields.getText("name")}, you are ${interaction.fields.getText("age")} years old, and your favorite color is ${interaction.fields.getText("color")}. You are ${interaction.fields.getText("height") || "not"} tall.`
})
async run(interaction: ModalInteraction) {
const name = interaction.fields.getText("name")
const age = interaction.fields.getText("age")
const color = interaction.fields.getText("color")
const height = interaction.fields.getText("height") || "not"
await interaction.reply(
`Hi ${name}, you are ${age} years old, and your favorite color is ${color}. You are ${height} tall.`
)
}
}

Expand Down
88 changes: 80 additions & 8 deletions apps/cloudo/src/commands/testing/options.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,99 @@
import {
type APIApplicationCommandBasicOption,
ApplicationCommandOptionType,
type AutocompleteInteraction,
Command,
type CommandInteraction
type CommandInteraction,
type CommandOptions
} from "@buape/carbon"

export default class Options extends Command {
export default class OptionsCommand extends Command {
name = "options"
description = "Options test"
defer = true

options: APIApplicationCommandBasicOption[] = [
options: CommandOptions = [
{
name: "str",
type: ApplicationCommandOptionType.String,
description: "DESCRIPTION",
required: true
required: false
},
{
name: "int",
type: ApplicationCommandOptionType.Integer,
description: "DESCRIPTION",
required: false
},
{
name: "num",
type: ApplicationCommandOptionType.Number,
description: "DESCRIPTION",
required: false
},
{
name: "bool",
type: ApplicationCommandOptionType.Boolean,
description: "DESCRIPTION",
required: false
},
{
name: "user",
type: ApplicationCommandOptionType.User,
description: "DESCRIPTION",
required: false
},
{
name: "channel",
type: ApplicationCommandOptionType.Channel,
description: "DESCRIPTION",
required: false
},
{
name: "role",
type: ApplicationCommandOptionType.Role,
description: "DESCRIPTION",
required: false
},
{
name: "mentionable",
type: ApplicationCommandOptionType.Mentionable,
description: "DESCRIPTION",
required: false
},
{
name: "autocomplete",
type: ApplicationCommandOptionType.String,
description: "DESCRIPTION",
required: false,
autocomplete: true
}
]

async autocomplete(interaction: AutocompleteInteraction) {
await interaction.respond([
{
name: "That thing you said",
value: String(interaction.options.getFocused()) || "No focused option"
},
{
name: "That thing you said but with a prefix",
value: `Prefix: ${String(interaction.options.getFocused())}`
}
])
}

async run(interaction: CommandInteraction) {
interaction.reply({
content: `${interaction.options.getString("str")}`
})
const str = interaction.options.getString("str")
const int = interaction.options.getInteger("int")
const num = interaction.options.getNumber("num")
const bool = interaction.options.getBoolean("bool")
const user = interaction.options.getUser("user")
const channel = await interaction.options.getChannel("channel")
const role = interaction.options.getRole("role")
const mentionable = await interaction.options.getMentionable("mentionable")

await interaction.reply(
`You provided the following options:\n str: ${str}\n int: ${int}\n num: ${num}\n bool: ${bool}\n user: ${user?.id}\n channel: ${channel?.id}\n role: ${role?.id}\n mentionable: ${mentionable?.id}`
)
}
}
Loading

0 comments on commit 8b489db

Please sign in to comment.