Skip to content

Commit 1309d03

Browse files
Finish Dev Mode and Deploy Scripts (#227)
Co-authored-by: Vlad Frangu <[email protected]>
1 parent 0107277 commit 1309d03

File tree

13 files changed

+176
-101
lines changed

13 files changed

+176
-101
lines changed

.devcontainer/.gitkeep

Whitespace-only changes.

.devcontainer/devcontainer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"label": "interactionkit.dev"
4040
}
4141
},
42-
"postCreateCommand": "npm install",
42+
"postCreateCommand": "npm install && npm run build",
4343
"features": {
4444
"git": "latest",
4545
"github-cli": "latest",

apps/flint/package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
"type": "module",
55
"scripts": {
66
"deploy": "ikit deploy",
7-
"bot": "DEBUG=* ikit dev"
7+
"bot": "DEBUG=* ikit dev",
8+
"typecheck": "tsc --noEmit",
9+
"prettier": "prettier src/**/*.ts --check",
10+
"lint": "eslint ./src/**/*.ts"
811
},
912
"engines": {
1013
"node": ">=18"

apps/flint/src/commands/ping.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default new SlashCommand({
55
description: "Get a pong back",
66
handler: async (interaction) => {
77
try {
8-
await interaction.reply({ message: "pong reload", ephemeral: true });
8+
await interaction.reply({ message: "pong", ephemeral: true });
99
} catch (err: unknown) {
1010
console.error("Error!");
1111
}

package-lock.json

+28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+9-8
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
"packageManager": "[email protected]",
1010
"type": "module",
1111
"scripts": {
12-
"cli": "turbo run cli --filter=create-ikit-app",
13-
"dev": "turbo run dev --no-cache --parallel --continue",
14-
"bot": "turbo run bot --no-cache",
15-
"clean": "turbo run clean",
16-
"build": "turbo run build",
17-
"typecheck": "turbo run typecheck",
18-
"prettier": "turbo run prettier",
19-
"lint": "turbo run lint",
12+
"cli": "cross-env FORCE_COLOR=1 turbo run cli --filter=create-ikit-app",
13+
"dev": "cross-env FORCE_COLOR=1 turbo run dev --no-cache --parallel --continue",
14+
"bot": "cross-env FORCE_COLOR=1 turbo run bot --no-cache",
15+
"clean": "cross-env FORCE_COLOR=1 turbo run clean",
16+
"build": "cross-env FORCE_COLOR=1 turbo run build",
17+
"typecheck": "cross-env FORCE_COLOR=1 turbo run typecheck",
18+
"prettier": "cross-env FORCE_COLOR=1 turbo run prettier",
19+
"lint": "cross-env FORCE_COLOR=1 turbo run lint",
2020
"pretest": "npm run clean && npm run build",
2121
"test": "vitest run",
2222
"version": "npx changeset version",
@@ -36,6 +36,7 @@
3636
"@types/node": "^18.7.7",
3737
"@typescript-eslint/eslint-plugin": "^5.33.1",
3838
"@typescript-eslint/parser": "^5.33.1",
39+
"cross-env": "^7.0.3",
3940
"eslint": "^8.22.0",
4041
"eslint-config-prettier": "^8.5.0",
4142
"eslint-config-xo": "^0.41.0",

packages/interaction-kit/src/application.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ import type SlashCommand from "./commands/slash-command.js";
99
import type { ExecutableComponent } from "./components/index.js";
1010
import { isExecutableComponent } from "./components/index.js";
1111
import Config from "./config.js";
12-
import type ApplicationCommandInteraction from "./interactions/application-commands/application-command-interaction.js";
1312
import * as Interaction from "./interactions/index.js";
14-
import type {
15-
InteractionKitCommand,
16-
MapValue,
17-
SerializableComponent,
18-
} from "./interfaces.js";
19-
import { response, ResponseStatus } from "./requests/response.js";
13+
import type { MapValue, SerializableComponent } from "./interfaces.js";
14+
import { ResponseStatus, response } from "./requests/response.js";
2015

2116
const log = debug("ikit:application");
2217

@@ -40,12 +35,17 @@ type CommandMap = {
4035

4136
type CommandMapValue<K extends keyof CommandMap> = MapValue<CommandMap[K]>;
4237

38+
export type AllCommands =
39+
| SlashCommand
40+
| ContextMenu<ApplicationCommandType.User>
41+
| ContextMenu<ApplicationCommandType.Message>;
42+
4343
export default class Application {
4444
#applicationId: Snowflake;
4545
#publicKey: string;
4646
#token: string;
4747
#commands: CommandMap;
48-
#components: Map<string, ExecutableComponent> = new Map();
48+
#components = new Map<string, ExecutableComponent>();
4949
#shutdown: AbortController;
5050

5151
constructor({ applicationId, publicKey, token }: ApplicationArgs) {
@@ -93,14 +93,14 @@ export default class Application {
9393
.flat();
9494
}
9595

96-
addCommand(command: InteractionKitCommand<ApplicationCommandInteraction>) {
96+
addCommand(command: AllCommands) {
9797
if (this.#commands[command.type]?.has(command.name.toLowerCase())) {
9898
throw new Error(
9999
`Error registering ${command.name.toLowerCase()}: Duplicate names are not allowed`
100100
);
101101
}
102102

103-
log(`Registering the ${command.name.toLowerCase()} command`);
103+
log(`Adding the ${command.name.toLowerCase()} command`);
104104

105105
this.#commands[command.type].set(
106106
command.name.toLowerCase(),
@@ -112,9 +112,7 @@ export default class Application {
112112
return this;
113113
}
114114

115-
addCommands(
116-
...commands: Array<InteractionKitCommand<ApplicationCommandInteraction>>
117-
) {
115+
addCommands(...commands: AllCommands[]) {
118116
commands.forEach((command) => this.addCommand(command));
119117
return this;
120118
}
@@ -185,7 +183,8 @@ export default class Application {
185183
json,
186184
(status: ResponseStatus, json: Record<string, any>) => {
187185
resolve(response(status, json));
188-
}
186+
},
187+
request
189188
);
190189
});
191190
} catch (error: unknown) {

packages/interaction-kit/src/cli/dev.ts

+51-21
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import arg from "arg";
22
import boxen from "boxen";
33
import chalk from "chalk";
44
import debug from "debug";
5-
import { bulkOverwriteGuildApplicationCommands } from "discord-api";
5+
import {
6+
bulkOverwriteGuildApplicationCommands,
7+
client,
8+
getGuildApplicationCommands,
9+
} from "discord-api";
10+
import type { RESTGetAPIApplicationGuildCommandsResult } from "discord-api-types/v10";
611
import server from "discord-edge-runner";
712
import type { Snowflake } from "discord-snowflake";
813
import ngrok from "ngrok";
@@ -14,35 +19,53 @@ import {
1419

1520
const log = debug("cli:dev");
1621

17-
async function updateCommands(guildId: Snowflake) {
18-
// Start application
19-
const application = await getApplicationEntrypoint();
20-
21-
log("Checking for command updates in Development Server");
22-
const devCommandChangeSet = await getGuildApplicationCommandChanges(
23-
application,
24-
guildId
25-
);
26-
27-
log(
28-
`${devCommandChangeSet.newCommands.size} new commands, ${devCommandChangeSet.updatedCommands.size} changed commands, ${devCommandChangeSet.deletedCommands.size} removed commands, and ${devCommandChangeSet.unchangedCommands.size} unchanged commands.`
29-
);
30-
31-
const serializedCommands = application.commands.map((command) =>
32-
command.serialize()
33-
);
22+
const listFormatter = new Intl.ListFormat("en", {
23+
style: "long",
24+
type: "conjunction",
25+
});
3426

27+
async function updateCommands(
28+
guildId: Snowflake,
29+
commands: RESTGetAPIApplicationGuildCommandsResult
30+
) {
3531
try {
36-
if (devCommandChangeSet.hasChanges) {
37-
await bulkOverwriteGuildApplicationCommands(
32+
// Start application
33+
const application = await getApplicationEntrypoint();
34+
35+
log("Checking for command updates in Development Server");
36+
const comparison = await getGuildApplicationCommandChanges(
37+
application,
38+
guildId,
39+
commands
40+
);
41+
42+
log(
43+
listFormatter.format([
44+
chalk.green(`${comparison.new.size} new commands`),
45+
chalk.yellow(`${comparison.updated.size} updated commands`),
46+
chalk.red(`${comparison.deleted.size} deleted commands`),
47+
chalk.gray(`${comparison.unchanged.size} unchanged commands`),
48+
])
49+
);
50+
51+
if (comparison.changed) {
52+
const serializedCommands = application.commands.map((command) =>
53+
command.serialize()
54+
);
55+
56+
const response = await bulkOverwriteGuildApplicationCommands(
3857
application.id,
3958
guildId,
4059
serializedCommands
4160
);
61+
62+
return response;
4263
}
4364
} catch (error: unknown) {
4465
log((error as Error).message);
4566
}
67+
68+
return commands;
4669
}
4770

4871
export default async function dev(argv?: string[]) {
@@ -79,6 +102,7 @@ export default async function dev(argv?: string[]) {
79102
}
80103

81104
const guildId = process.env.DEVELOPMENT_SERVER_ID as Snowflake;
105+
client.setToken(process.env.TOKEN);
82106

83107
// Parse input args
84108
const args = arg(
@@ -96,8 +120,14 @@ export default async function dev(argv?: string[]) {
96120
const port = args["--port"] ?? 3000;
97121
let entrypoint = args["--entrypoint"] ?? "";
98122

123+
let commands: RESTGetAPIApplicationGuildCommandsResult;
124+
99125
try {
100126
entrypoint = await getEdgeEntrypoint(entrypoint);
127+
commands = await getGuildApplicationCommands(
128+
process.env.APPLICATION_ID as Snowflake,
129+
guildId
130+
);
101131
} catch (error: unknown) {
102132
log(chalk.red((error as Error).message));
103133
process.exit(1);
@@ -117,7 +147,7 @@ export default async function dev(argv?: string[]) {
117147
FORCE_COLOR: "1",
118148
},
119149
onReload: async () => {
120-
await updateCommands(guildId);
150+
commands = await updateCommands(guildId, commands);
121151
},
122152
onError: (error: unknown) => {
123153
log(chalk.red({ error }));

packages/interaction-kit/src/interactions/autocomplete/types.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
NumberOption,
66
StringOption,
77
} from "../../commands/options/index.js";
8+
import type { Awaitable } from "../../interfaces.js";
89
import type SlashCommandAutocompleteInteraction from "./application-command-autocomplete.js";
910

1011
// 🥺 selects when, discord?
@@ -20,5 +21,9 @@ export type SlashCommandAutocompleteType =
2021
| NumberOption;
2122

2223
export interface Autocomplete<T extends AutocompleteInteractionTypes> {
23-
autocomplete?: (interaction: T, application: Application) => Promise<void>;
24+
autocomplete?: (
25+
interaction: T,
26+
application: Application,
27+
request: Request
28+
) => Awaitable;
2429
}

0 commit comments

Comments
 (0)