@wolfstar/cli 2.2.0 → 2.3.0-next-20261004142621
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +465 -304
- package/dist/{_shared-DJrpalNQ.js → _shared-BIQK0Bhm.js} +2 -2
- package/dist/_shared-BIQK0Bhm.js.map +1 -0
- package/dist/bridge-BvkmlAOZ.js +410 -0
- package/dist/bridge-BvkmlAOZ.js.map +1 -0
- package/dist/{build-CluOR8dJ.js → build-DJcc95Yq.js} +5 -5
- package/dist/build-DJcc95Yq.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/{codegen-D6V1i_fa.js → codegen-aJSyPz-J.js} +4 -4
- package/dist/codegen-aJSyPz-J.js.map +1 -0
- package/dist/command-diff-BK912Hjc.js +78 -0
- package/dist/command-diff-BK912Hjc.js.map +1 -0
- package/dist/commands-CIPWQtF0.js +3 -0
- package/dist/commands-Clpbqq3K.js +15 -0
- package/dist/commands-Clpbqq3K.js.map +1 -0
- package/dist/{commands-BJ589_AC.js → commands-DVC7ky6f.js} +259 -9
- package/dist/commands-DVC7ky6f.js.map +1 -0
- package/dist/completions-D2KYtrrv.js +161 -0
- package/dist/completions-D2KYtrrv.js.map +1 -0
- package/dist/{dev-DJJZN4NJ.js → dev-oPPVR7d_.js} +434 -28
- package/dist/dev-oPPVR7d_.js.map +1 -0
- package/dist/{diagnostics-3JRAy8Xj.js → diagnostics-BysbNnPD.js} +22 -1
- package/dist/diagnostics-BysbNnPD.js.map +1 -0
- package/dist/doctor-DkVUwgDd.js +334 -0
- package/dist/doctor-DkVUwgDd.js.map +1 -0
- package/dist/errors-COFWKKKw.js.map +1 -1
- package/dist/external-CxFKxwi3.js.map +1 -1
- package/dist/framework-auto-imports-Gu_PXSyr.js.map +1 -1
- package/dist/{hooks-BfDFM38k.js → hooks-Cy6F2bhH.js} +20 -4
- package/dist/hooks-Cy6F2bhH.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/{info-C1Kx_4Og.js → info-CKJVMWIT.js} +15 -4
- package/dist/info-CKJVMWIT.js.map +1 -0
- package/dist/{locales-BzOLRBVg.js → locales-BJAP4HYf.js} +5 -5
- package/dist/locales-BJAP4HYf.js.map +1 -0
- package/dist/log-view-B7uJEnMR.js +342 -0
- package/dist/log-view-B7uJEnMR.js.map +1 -0
- package/dist/{nitro-yjqZBh5L.js → nitro-B8u1iVgf.js} +2 -2
- package/dist/nitro-B8u1iVgf.js.map +1 -0
- package/dist/none-uC_wi_l4.js.map +1 -1
- package/dist/output-mode-Bp7Da8vJ.js.map +1 -1
- package/dist/{plain-B6z85uQP.js → plain-DG7cy0Kk.js} +7 -2
- package/dist/plain-DG7cy0Kk.js.map +1 -0
- package/dist/{prepare-Cb45Z4re.js → prepare-BM93i3Rm.js} +4 -4
- package/dist/prepare-BM93i3Rm.js.map +1 -0
- package/dist/{project-D-8VIcyF.js → project-zlQStwsf.js} +2 -2
- package/dist/project-zlQStwsf.js.map +1 -0
- package/dist/{run-BiLZqib3.js → run-DMM2YlP3.js} +2 -12
- package/dist/run-DMM2YlP3.js.map +1 -0
- package/dist/{theme-3Fc_LI-2.js → theme-yS2h5dd_.js} +25 -1
- package/dist/theme-yS2h5dd_.js.map +1 -0
- package/dist/tsc-C5l5TQGC.js +3 -0
- package/dist/{tsc-DEBcwIO0.js → tsc-puVAcwmo.js} +24 -5
- package/dist/tsc-puVAcwmo.js.map +1 -0
- package/dist/{tsdown-DrWXld54.js → tsdown-Dwt3JhPw.js} +2 -2
- package/dist/tsdown-Dwt3JhPw.js.map +1 -0
- package/dist/{tui-BRddrLQP.js → tui-nldGSD4c.js} +913 -141
- package/dist/tui-nldGSD4c.js.map +1 -0
- package/dist/version-BzclCE19.js.map +1 -1
- package/dist/{vite-Bf7nrJx7.js → vite-YZUtv2Hk.js} +2 -2
- package/dist/vite-YZUtv2Hk.js.map +1 -0
- package/package.json +5 -5
- package/dist/_shared-DJrpalNQ.js.map +0 -1
- package/dist/build-CluOR8dJ.js.map +0 -1
- package/dist/codegen-D6V1i_fa.js.map +0 -1
- package/dist/commands-BJ589_AC.js.map +0 -1
- package/dist/dev-DJJZN4NJ.js.map +0 -1
- package/dist/diagnostics-3JRAy8Xj.js.map +0 -1
- package/dist/hooks-BfDFM38k.js.map +0 -1
- package/dist/info-C1Kx_4Og.js.map +0 -1
- package/dist/locales-BzOLRBVg.js.map +0 -1
- package/dist/log-buffer-CY82aqnb.js +0 -72
- package/dist/log-buffer-CY82aqnb.js.map +0 -1
- package/dist/nitro-yjqZBh5L.js.map +0 -1
- package/dist/plain-B6z85uQP.js.map +0 -1
- package/dist/prepare-Cb45Z4re.js.map +0 -1
- package/dist/project-D-8VIcyF.js.map +0 -1
- package/dist/run-BiLZqib3.js.map +0 -1
- package/dist/theme-3Fc_LI-2.js.map +0 -1
- package/dist/tsc-B931Ezh7.js +0 -3
- package/dist/tsc-DEBcwIO0.js.map +0 -1
- package/dist/tsdown-DrWXld54.js.map +0 -1
- package/dist/tui-BRddrLQP.js.map +0 -1
- package/dist/tunnel-DHSxOZKr.js +0 -175
- package/dist/tunnel-DHSxOZKr.js.map +0 -1
- package/dist/vite-Bf7nrJx7.js.map +0 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region src/utils/command-diff.ts
|
|
2
|
+
const typeOf = (command) => command.type ?? 1;
|
|
3
|
+
const keyOf = (command) => `${typeOf(command)}:${command.name}`;
|
|
4
|
+
/** `JSON.stringify` with sorted keys, so two bodies built in a different order compare equal. */
|
|
5
|
+
function stableStringify(value) {
|
|
6
|
+
if (Array.isArray(value)) return `[${value.map(stableStringify).join(",")}]`;
|
|
7
|
+
if (value !== null && typeof value === "object") return `{${Object.entries(value).filter(([, item]) => item !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(",")}}`;
|
|
8
|
+
return JSON.stringify(value) ?? "null";
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Whether what Discord has deployed matches what the project defines. Discord answers with fields the project never
|
|
12
|
+
* sent (ids, `version`, defaults such as `nsfw: false` or `options: []`), so only the keys the definition sets are
|
|
13
|
+
* compared, and a missing value equals an empty one. This reads a command as changed when the project changed it, not
|
|
14
|
+
* when Discord filled something in.
|
|
15
|
+
*/
|
|
16
|
+
function matchesDeployed(local, deployed) {
|
|
17
|
+
if (isEmpty(local)) return isEmpty(deployed);
|
|
18
|
+
if (Array.isArray(local)) return Array.isArray(deployed) && local.length === deployed.length && local.every((item, index) => matchesDeployed(item, deployed[index]));
|
|
19
|
+
if (typeof local === "object" && local !== null) {
|
|
20
|
+
if (typeof deployed !== "object" || deployed === null || Array.isArray(deployed)) return false;
|
|
21
|
+
return Object.entries(local).every(([key, value]) => matchesDeployed(value, deployed[key]));
|
|
22
|
+
}
|
|
23
|
+
return local === deployed || String(local) === String(deployed);
|
|
24
|
+
}
|
|
25
|
+
function isEmpty(value) {
|
|
26
|
+
if (value === void 0 || value === null || value === false) return true;
|
|
27
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
28
|
+
return typeof value === "object" && Object.keys(value).length === 0;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The difference between two lists of commands of one scope. `same` decides whether a command present in both is
|
|
32
|
+
* unchanged: exact for two snapshots of the bot, {@link matchesDeployed} against what Discord answers.
|
|
33
|
+
*/
|
|
34
|
+
function diffCommands(previous, next, guild, same = (a, b) => stableStringify(a) === stableStringify(b)) {
|
|
35
|
+
const before = new Map(previous.map((command) => [keyOf(command), command]));
|
|
36
|
+
const after = new Map(next.map((command) => [keyOf(command), command]));
|
|
37
|
+
const changes = [];
|
|
38
|
+
for (const [key, command] of after) {
|
|
39
|
+
const old = before.get(key);
|
|
40
|
+
if (old === void 0) changes.push({
|
|
41
|
+
kind: "added",
|
|
42
|
+
name: command.name,
|
|
43
|
+
type: typeOf(command),
|
|
44
|
+
guild
|
|
45
|
+
});
|
|
46
|
+
else if (!same(old, command)) changes.push({
|
|
47
|
+
kind: "changed",
|
|
48
|
+
name: command.name,
|
|
49
|
+
type: typeOf(command),
|
|
50
|
+
guild
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
for (const [key, command] of before) if (!after.has(key)) changes.push({
|
|
54
|
+
kind: "removed",
|
|
55
|
+
name: command.name,
|
|
56
|
+
type: typeOf(command),
|
|
57
|
+
guild
|
|
58
|
+
});
|
|
59
|
+
return changes;
|
|
60
|
+
}
|
|
61
|
+
/** What changed between two snapshots of the commands the bot registers, across the global scope and every guild. */
|
|
62
|
+
function diffSnapshots(previous, next) {
|
|
63
|
+
const guilds = /* @__PURE__ */ new Set([...Object.keys(previous.guilds), ...Object.keys(next.guilds)]);
|
|
64
|
+
return [...diffCommands(previous.global, next.global, null), ...[...guilds].sort().flatMap((guild) => diffCommands(previous.guilds[guild] ?? [], next.guilds[guild] ?? [], guild))];
|
|
65
|
+
}
|
|
66
|
+
const KIND_NAMES = {
|
|
67
|
+
2: "user",
|
|
68
|
+
3: "message"
|
|
69
|
+
};
|
|
70
|
+
/** `ping`, `Report (message)`, `ping @ 1234` for a guild command. */
|
|
71
|
+
function describeCommand(change) {
|
|
72
|
+
const kind = KIND_NAMES[change.type];
|
|
73
|
+
return `${change.name}${kind ? ` (${kind})` : ""}${change.guild ? ` @ ${change.guild}` : ""}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//#endregion
|
|
77
|
+
export { matchesDeployed as i, diffCommands as n, diffSnapshots as r, describeCommand as t };
|
|
78
|
+
//# sourceMappingURL=command-diff-BK912Hjc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-diff-BK912Hjc.js","names":[],"sources":["../src/utils/command-diff.ts"],"sourcesContent":["import type { CommandData, CommandSnapshot } from '../dev/bridge.js';\n\nexport type CommandChangeKind = 'added' | 'removed' | 'changed';\n\nexport interface CommandChange {\n\tkind: CommandChangeKind;\n\tname: string;\n\t/** Discord's command type: `1` chat input, `2` user, `3` message. */\n\ttype: number;\n\t/** `null` for a global command, the guild id otherwise. */\n\tguild: string | null;\n}\n\nconst typeOf = (command: CommandData) => command.type ?? 1;\nconst keyOf = (command: CommandData) => `${typeOf(command)}:${command.name}`;\n\n/** `JSON.stringify` with sorted keys, so two bodies built in a different order compare equal. */\nexport function stableStringify(value: unknown): string {\n\tif (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`;\n\tif (value !== null && typeof value === 'object') {\n\t\tconst entries = Object.entries(value as Record<string, unknown>)\n\t\t\t.filter(([, item]) => item !== undefined)\n\t\t\t.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));\n\t\treturn `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`).join(',')}}`;\n\t}\n\n\treturn JSON.stringify(value) ?? 'null';\n}\n\n/**\n * Whether what Discord has deployed matches what the project defines. Discord answers with fields the project never\n * sent (ids, `version`, defaults such as `nsfw: false` or `options: []`), so only the keys the definition sets are\n * compared, and a missing value equals an empty one. This reads a command as changed when the project changed it, not\n * when Discord filled something in.\n */\nexport function matchesDeployed(local: unknown, deployed: unknown): boolean {\n\tif (isEmpty(local)) return isEmpty(deployed);\n\tif (Array.isArray(local)) {\n\t\treturn Array.isArray(deployed) && local.length === deployed.length && local.every((item, index) => matchesDeployed(item, deployed[index]));\n\t}\n\n\tif (typeof local === 'object' && local !== null) {\n\t\tif (typeof deployed !== 'object' || deployed === null || Array.isArray(deployed)) return false;\n\t\treturn Object.entries(local).every(([key, value]) => matchesDeployed(value, (deployed as Record<string, unknown>)[key]));\n\t}\n\n\t// `default_member_permissions` is sent as a string or a number and comes back as a string.\n\treturn local === deployed || String(local) === String(deployed);\n}\n\nfunction isEmpty(value: unknown): boolean {\n\tif (value === undefined || value === null || value === false) return true;\n\tif (Array.isArray(value)) return value.length === 0;\n\treturn typeof value === 'object' && Object.keys(value).length === 0;\n}\n\n/**\n * The difference between two lists of commands of one scope. `same` decides whether a command present in both is\n * unchanged: exact for two snapshots of the bot, {@link matchesDeployed} against what Discord answers.\n */\nexport function diffCommands(\n\tprevious: readonly CommandData[],\n\tnext: readonly CommandData[],\n\tguild: string | null,\n\tsame: (previous: CommandData, next: CommandData) => boolean = (a, b) => stableStringify(a) === stableStringify(b)\n): CommandChange[] {\n\tconst before = new Map(previous.map((command) => [keyOf(command), command]));\n\tconst after = new Map(next.map((command) => [keyOf(command), command]));\n\tconst changes: CommandChange[] = [];\n\n\tfor (const [key, command] of after) {\n\t\tconst old = before.get(key);\n\t\tif (old === undefined) changes.push({ kind: 'added', name: command.name, type: typeOf(command), guild });\n\t\telse if (!same(old, command)) changes.push({ kind: 'changed', name: command.name, type: typeOf(command), guild });\n\t}\n\n\tfor (const [key, command] of before) {\n\t\tif (!after.has(key)) changes.push({ kind: 'removed', name: command.name, type: typeOf(command), guild });\n\t}\n\n\treturn changes;\n}\n\n/** What changed between two snapshots of the commands the bot registers, across the global scope and every guild. */\nexport function diffSnapshots(previous: CommandSnapshot, next: CommandSnapshot): CommandChange[] {\n\tconst guilds = new Set([...Object.keys(previous.guilds), ...Object.keys(next.guilds)]);\n\treturn [\n\t\t...diffCommands(previous.global, next.global, null),\n\t\t...[...guilds].sort().flatMap((guild) => diffCommands(previous.guilds[guild] ?? [], next.guilds[guild] ?? [], guild))\n\t];\n}\n\nconst KIND_NAMES: Record<number, string> = { 2: 'user', 3: 'message' };\n\n/** `ping`, `Report (message)`, `ping @ 1234` for a guild command. */\nexport function describeCommand(change: Pick<CommandChange, 'name' | 'type' | 'guild'>): string {\n\tconst kind = KIND_NAMES[change.type];\n\treturn `${change.name}${kind ? ` (${kind})` : ''}${change.guild ? ` @ ${change.guild}` : ''}`;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/commands/index.ts
|
|
2
|
+
const commands = {
|
|
3
|
+
dev: () => import("./dev-oPPVR7d_.js").then((module) => module.default),
|
|
4
|
+
build: () => import("./build-DJcc95Yq.js").then((module) => module.default),
|
|
5
|
+
info: () => import("./info-CKJVMWIT.js").then((module) => module.default),
|
|
6
|
+
codegen: () => import("./codegen-aJSyPz-J.js").then((module) => module.default),
|
|
7
|
+
prepare: () => import("./prepare-BM93i3Rm.js").then((module) => module.default),
|
|
8
|
+
commands: () => import("./commands-DVC7ky6f.js").then((module) => module.default),
|
|
9
|
+
doctor: () => import("./doctor-DkVUwgDd.js").then((module) => module.default),
|
|
10
|
+
completions: () => import("./completions-D2KYtrrv.js").then((module) => module.default)
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { commands as t };
|
|
15
|
+
//# sourceMappingURL=commands-Clpbqq3K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands-Clpbqq3K.js","names":[],"sources":["../src/commands/index.ts"],"sourcesContent":["import type { CommandDef } from 'citty';\n\n// citty types each command by its own arguments; the registry needs the erased form.\n// oxlint-disable-next-line typescript/no-explicit-any\ntype AnyCommand = CommandDef<any>;\n\nexport const commands: Record<string, () => Promise<AnyCommand>> = {\n\tdev: () => import('./dev.js').then((module) => module.default),\n\tbuild: () => import('./build.js').then((module) => module.default),\n\tinfo: () => import('./info.js').then((module) => module.default),\n\tcodegen: () => import('./codegen.js').then((module) => module.default),\n\tprepare: () => import('./prepare.js').then((module) => module.default),\n\tcommands: () => import('./commands.js').then((module) => module.default),\n\tdoctor: () => import('./doctor.js').then((module) => module.default),\n\tcompletions: () => import('./completions.js').then((module) => module.default)\n};\n"],"mappings":";AAMA,MAAa,WAAsD;CAClE,WAAW,OAAO,oBAAW,CAAC,MAAM,WAAW,OAAO,OAAO;CAC7D,aAAa,OAAO,sBAAa,CAAC,MAAM,WAAW,OAAO,OAAO;CACjE,YAAY,OAAO,qBAAY,CAAC,MAAM,WAAW,OAAO,OAAO;CAC/D,eAAe,OAAO,wBAAe,CAAC,MAAM,WAAW,OAAO,OAAO;CACrE,eAAe,OAAO,wBAAe,CAAC,MAAM,WAAW,OAAO,OAAO;CACrE,gBAAgB,OAAO,yBAAgB,CAAC,MAAM,WAAW,OAAO,OAAO;CACvE,cAAc,OAAO,uBAAc,CAAC,MAAM,WAAW,OAAO,OAAO;CACnE,mBAAmB,OAAO,4BAAmB,CAAC,MAAM,WAAW,OAAO,OAAO;AAC9E"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { i as shouldUseColor } from "./output-mode-Bp7Da8vJ.js";
|
|
2
|
-
import { t as cliDiagnostics } from "./diagnostics-
|
|
3
|
-
import {
|
|
4
|
-
import { n as
|
|
2
|
+
import { t as cliDiagnostics } from "./diagnostics-BysbNnPD.js";
|
|
3
|
+
import { c as moduleImportArgs, d as resolveCwd, n as loadProject, r as withProjectEnv, s as envImportArgs, t as applyEnvOptions, u as projectArgs } from "./hooks-Cy6F2bhH.js";
|
|
4
|
+
import { i as matchesDeployed, n as diffCommands, t as describeCommand } from "./command-diff-BK912Hjc.js";
|
|
5
|
+
import { i as bridgeImportArgs, l as readDiscordCredentials, o as parseBridgeMessage, r as DUMP_ENV, t as BRIDGE_FRAMEWORK_VERSION } from "./bridge-BvkmlAOZ.js";
|
|
5
6
|
import { defineCommand } from "citty";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { displayPath } from "@wolfstar/schema";
|
|
6
9
|
import { createColors } from "colorette";
|
|
10
|
+
import { spawn } from "node:child_process";
|
|
7
11
|
|
|
8
12
|
//#region src/utils/discord.ts
|
|
9
13
|
const API = "https://discord.com/api/v10";
|
|
@@ -22,10 +26,14 @@ function createDiscordClient(config, env = process.env) {
|
|
|
22
26
|
if (!credentials.applicationId) throw cliDiagnostics.DISCORD_APPLICATION_ID_MISSING({});
|
|
23
27
|
const applicationId = credentials.applicationId;
|
|
24
28
|
const scope = (guildId) => guildId ? `/applications/${applicationId}/guilds/${guildId}/commands` : `/applications/${applicationId}/commands`;
|
|
25
|
-
const request = async (method, path) => {
|
|
29
|
+
const request = async (method, path, payload) => {
|
|
26
30
|
const response = await fetch(`${API}${path}`, {
|
|
27
31
|
method,
|
|
28
|
-
headers: {
|
|
32
|
+
headers: {
|
|
33
|
+
authorization: `Bot ${credentials.token}`,
|
|
34
|
+
...payload === void 0 ? {} : { "content-type": "application/json" }
|
|
35
|
+
},
|
|
36
|
+
...payload === void 0 ? {} : { body: JSON.stringify(payload) },
|
|
29
37
|
signal: AbortSignal.timeout(15e3)
|
|
30
38
|
});
|
|
31
39
|
if (response.status === 204) return null;
|
|
@@ -47,10 +55,100 @@ function createDiscordClient(config, env = process.env) {
|
|
|
47
55
|
},
|
|
48
56
|
async deleteCommand(guildId, commandId) {
|
|
49
57
|
await request("DELETE", `${scope(guildId)}/${commandId}`);
|
|
58
|
+
},
|
|
59
|
+
async putCommands(guildId, commands) {
|
|
60
|
+
const body = await request("PUT", scope(guildId), commands);
|
|
61
|
+
return Array.isArray(body) ? body : [];
|
|
50
62
|
}
|
|
51
63
|
};
|
|
52
64
|
}
|
|
53
65
|
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/utils/local-commands.ts
|
|
68
|
+
/**
|
|
69
|
+
* The application commands the project defines, as the bot itself would register them.
|
|
70
|
+
*
|
|
71
|
+
* Commands are declared with builders and decorators that only exist once the bot's modules ran, so nothing short of
|
|
72
|
+
* running them knows the answer. This starts the built bot with the dev bridge in its "dump" mode: it loads its
|
|
73
|
+
* pieces, reports its registry over IPC and exits before it listens or talks to Discord.
|
|
74
|
+
*
|
|
75
|
+
* It is a plain start of the bot, not a `stars dev` session: `STARS_DEV` is not set, so commands a project only
|
|
76
|
+
* registers while developing are not part of what `stars commands deploy` deploys.
|
|
77
|
+
*/
|
|
78
|
+
async function readLocalCommands(config, options = {}) {
|
|
79
|
+
if (!existsSync(config.build.output)) throw cliDiagnostics.LOCAL_COMMANDS_UNAVAILABLE({
|
|
80
|
+
reason: `${displayPath(config.root, config.build.output)} does not exist`,
|
|
81
|
+
fix: "Run `stars build` first: the commands are read from the built bot."
|
|
82
|
+
});
|
|
83
|
+
const bridge = bridgeImportArgs(config);
|
|
84
|
+
if (bridge.length === 0) throw cliDiagnostics.LOCAL_COMMANDS_UNAVAILABLE({
|
|
85
|
+
reason: `@wolfstar/http-framework ${BRIDGE_FRAMEWORK_VERSION} or later is not installed in ${config.root}`,
|
|
86
|
+
fix: `Install @wolfstar/http-framework@^${BRIDGE_FRAMEWORK_VERSION} in the project.`
|
|
87
|
+
});
|
|
88
|
+
const child = spawn(process.execPath, [
|
|
89
|
+
...envImportArgs(config),
|
|
90
|
+
...moduleImportArgs(config),
|
|
91
|
+
...bridge,
|
|
92
|
+
...config.dev.nodeArgs,
|
|
93
|
+
config.build.output,
|
|
94
|
+
...config.dev.args
|
|
95
|
+
], {
|
|
96
|
+
cwd: config.root,
|
|
97
|
+
env: {
|
|
98
|
+
...process.env,
|
|
99
|
+
...config.dev.env,
|
|
100
|
+
NODE_ENV: process.env.NODE_ENV ?? "development",
|
|
101
|
+
[DUMP_ENV]: "1"
|
|
102
|
+
},
|
|
103
|
+
stdio: [
|
|
104
|
+
"ignore",
|
|
105
|
+
"ignore",
|
|
106
|
+
"pipe",
|
|
107
|
+
"ipc"
|
|
108
|
+
],
|
|
109
|
+
windowsHide: true
|
|
110
|
+
});
|
|
111
|
+
return new Promise((resolve, reject) => {
|
|
112
|
+
let stderr = "";
|
|
113
|
+
let settled = false;
|
|
114
|
+
const finish = (action) => {
|
|
115
|
+
if (settled) return;
|
|
116
|
+
settled = true;
|
|
117
|
+
clearTimeout(timer);
|
|
118
|
+
action();
|
|
119
|
+
};
|
|
120
|
+
const unavailable = (reason) => cliDiagnostics.LOCAL_COMMANDS_UNAVAILABLE({
|
|
121
|
+
reason,
|
|
122
|
+
fix: "Check that the bot starts with `stars dev`: it has to construct its `Client` and call `client.load()`."
|
|
123
|
+
});
|
|
124
|
+
const timer = setTimeout(() => {
|
|
125
|
+
child.kill("SIGKILL");
|
|
126
|
+
finish(() => reject(unavailable("the bot did not load its commands in time")));
|
|
127
|
+
}, options.timeout ?? 3e4);
|
|
128
|
+
child.stderr?.on("data", (chunk) => stderr = `${stderr}${chunk.toString()}`.slice(-2e3));
|
|
129
|
+
let snapshot = null;
|
|
130
|
+
child.on("message", (message) => {
|
|
131
|
+
const parsed = parseBridgeMessage(message);
|
|
132
|
+
if (parsed?.type !== "commands" || snapshot !== null) return;
|
|
133
|
+
snapshot = {
|
|
134
|
+
global: parsed.global,
|
|
135
|
+
guilds: parsed.guilds
|
|
136
|
+
};
|
|
137
|
+
setTimeout(() => child.kill("SIGKILL"), 2e3).unref();
|
|
138
|
+
});
|
|
139
|
+
child.once("error", (error) => finish(() => reject(unavailable(error.message))));
|
|
140
|
+
child.once("exit", (code) => {
|
|
141
|
+
if (snapshot !== null) {
|
|
142
|
+
const commands = snapshot;
|
|
143
|
+
finish(() => resolve(commands));
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const detail = stderr.trim().split("\n").at(-1);
|
|
147
|
+
finish(() => reject(unavailable(`the bot exited with code ${code} before loading its commands${detail ? ` (${detail})` : ""}`)));
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
54
152
|
//#endregion
|
|
55
153
|
//#region src/utils/prompts.ts
|
|
56
154
|
/**
|
|
@@ -154,6 +252,100 @@ async function runCommandsClean(options) {
|
|
|
154
252
|
name: command.name
|
|
155
253
|
})) }, null, 2)}\n`);
|
|
156
254
|
}
|
|
255
|
+
const SYMBOLS = {
|
|
256
|
+
added: "+",
|
|
257
|
+
removed: "-",
|
|
258
|
+
changed: "~"
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* What a deploy of `guild` (or the global scope) would change: the commands the project defines for it against the
|
|
262
|
+
* ones Discord has. A command is `changed` when the project's definition no longer matches (see `matchesDeployed`).
|
|
263
|
+
*/
|
|
264
|
+
async function compare(options) {
|
|
265
|
+
const project = await loadProject({
|
|
266
|
+
cwd: resolveCwd(options),
|
|
267
|
+
configFile: options.config
|
|
268
|
+
});
|
|
269
|
+
const config = withProjectEnv(await applyEnvOptions(project.config, project.hooks));
|
|
270
|
+
const { client, guild } = connectTo(config, options);
|
|
271
|
+
const snapshot = options.local ?? await readLocalCommands(config);
|
|
272
|
+
const local = guild === null ? snapshot.global : snapshot.guilds[guild] ?? [];
|
|
273
|
+
const deployed = await client.listCommands(guild);
|
|
274
|
+
return {
|
|
275
|
+
client,
|
|
276
|
+
guild,
|
|
277
|
+
local,
|
|
278
|
+
changes: diffCommands(deployed, local, guild, (old, next) => matchesDeployed(next, old))
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function writeChanges(stdout, colors, changes) {
|
|
282
|
+
const paint = {
|
|
283
|
+
added: colors.green,
|
|
284
|
+
removed: colors.red,
|
|
285
|
+
changed: colors.yellow
|
|
286
|
+
};
|
|
287
|
+
for (const change of changes) stdout.write(` ${paint[change.kind](`${SYMBOLS[change.kind]} ${describeCommand({
|
|
288
|
+
...change,
|
|
289
|
+
guild: null
|
|
290
|
+
})}`)} ${colors.dim(change.kind)}\n`);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Compares the commands the project defines with the ones Discord has deployed, without changing anything: what
|
|
294
|
+
* `stars commands deploy` would do. `--check` makes a difference an error, for CI.
|
|
295
|
+
*/
|
|
296
|
+
async function runCommandsDiff(options) {
|
|
297
|
+
const stdout = options.stdout ?? process.stdout;
|
|
298
|
+
const colors = createColors({ useColor: shouldUseColor() && !options.json });
|
|
299
|
+
const { client, guild, changes } = await compare(options);
|
|
300
|
+
if (options.json) stdout.write(`${JSON.stringify({
|
|
301
|
+
applicationId: client.applicationId,
|
|
302
|
+
guildId: guild,
|
|
303
|
+
changes
|
|
304
|
+
}, null, 2)}\n`);
|
|
305
|
+
else if (changes.length === 0) stdout.write(`${colors.dim("stars")} ${guild ? `guild ${guild}` : "the global scope"} is up to date\n`);
|
|
306
|
+
else {
|
|
307
|
+
stdout.write(`${colors.dim("stars")} ${changes.length} difference(s) in ${guild ? `guild ${guild}` : "the global scope"}\n`);
|
|
308
|
+
writeChanges(stdout, colors, changes);
|
|
309
|
+
}
|
|
310
|
+
if (options.check && changes.length > 0) throw cliDiagnostics.COMMANDS_DIFFER({ count: changes.length });
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Deploys the commands the project defines to Discord with a bulk overwrite: a deployed command the project no
|
|
314
|
+
* longer defines is deleted. It shows what will change and asks first; scripts pass `--yes`.
|
|
315
|
+
*/
|
|
316
|
+
async function runCommandsDeploy(options) {
|
|
317
|
+
const stdout = options.stdout ?? process.stdout;
|
|
318
|
+
const colors = createColors({ useColor: shouldUseColor() && !options.json });
|
|
319
|
+
const { client, guild, local, changes } = await compare(options);
|
|
320
|
+
const scope = guild ? `guild ${guild}` : "the global scope";
|
|
321
|
+
if (changes.length === 0) {
|
|
322
|
+
if (options.json) stdout.write(`${JSON.stringify({
|
|
323
|
+
applicationId: client.applicationId,
|
|
324
|
+
guildId: guild,
|
|
325
|
+
deployed: 0,
|
|
326
|
+
changes
|
|
327
|
+
}, null, 2)}\n`);
|
|
328
|
+
else stdout.write(`${colors.dim("stars")} ${scope} is up to date, nothing to deploy\n`);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (!options.json) {
|
|
332
|
+
stdout.write(`${colors.dim("stars")} deploying to ${scope}\n`);
|
|
333
|
+
writeChanges(stdout, colors, changes);
|
|
334
|
+
}
|
|
335
|
+
if (!options.yes) {
|
|
336
|
+
const stdin = options.stdin ?? process.stdin;
|
|
337
|
+
if (!options.prompt && (!stdin.isTTY || options.json)) throw cliDiagnostics.DEPLOY_CONFIRMATION_REQUIRED({});
|
|
338
|
+
if (!await (options.prompt ?? createClackPrompt()).confirm(`Overwrite the commands of ${scope} with the ${local.length} the project defines?`)) throw cliDiagnostics.ABORTED({});
|
|
339
|
+
}
|
|
340
|
+
const deployed = await client.putCommands(guild, local);
|
|
341
|
+
if (options.json) stdout.write(`${JSON.stringify({
|
|
342
|
+
applicationId: client.applicationId,
|
|
343
|
+
guildId: guild,
|
|
344
|
+
deployed: deployed.length,
|
|
345
|
+
changes
|
|
346
|
+
}, null, 2)}\n`);
|
|
347
|
+
else stdout.write(`${colors.dim("stars")} ${colors.green("deployed")} ${deployed.length} command(s) to ${scope}\n`);
|
|
348
|
+
}
|
|
157
349
|
/**
|
|
158
350
|
* Works out what to delete: `--name` (and `--yes`) keep the command scriptable, while a bare `stars commands clean`
|
|
159
351
|
* on a terminal runs the wizard — a checklist of what Discord has deployed, then a confirmation.
|
|
@@ -181,6 +373,9 @@ async function connect(options) {
|
|
|
181
373
|
cwd: resolveCwd(options),
|
|
182
374
|
configFile: options.config
|
|
183
375
|
});
|
|
376
|
+
return connectTo(config, options);
|
|
377
|
+
}
|
|
378
|
+
function connectTo(config, options) {
|
|
184
379
|
return {
|
|
185
380
|
client: options.client ?? createDiscordClient(config),
|
|
186
381
|
guild: options.guild ?? null
|
|
@@ -272,18 +467,73 @@ const clean = defineCommand({
|
|
|
272
467
|
});
|
|
273
468
|
}
|
|
274
469
|
});
|
|
470
|
+
const diff = defineCommand({
|
|
471
|
+
meta: {
|
|
472
|
+
name: "diff",
|
|
473
|
+
description: "Compare the commands the built bot defines with the ones Discord has deployed"
|
|
474
|
+
},
|
|
475
|
+
args: {
|
|
476
|
+
...scopeArgs,
|
|
477
|
+
check: {
|
|
478
|
+
type: "boolean",
|
|
479
|
+
description: "Fail when the deployed commands differ, for CI",
|
|
480
|
+
default: false
|
|
481
|
+
}
|
|
482
|
+
},
|
|
483
|
+
async run({ args }) {
|
|
484
|
+
await runCommandsDiff({
|
|
485
|
+
config: args.config,
|
|
486
|
+
cwd: args.cwd,
|
|
487
|
+
guild: args.guild,
|
|
488
|
+
json: args.json,
|
|
489
|
+
check: args.check
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
const deploy = defineCommand({
|
|
494
|
+
meta: {
|
|
495
|
+
name: "deploy",
|
|
496
|
+
description: "Deploy the commands the built bot defines, replacing the deployed ones"
|
|
497
|
+
},
|
|
498
|
+
args: {
|
|
499
|
+
...scopeArgs,
|
|
500
|
+
yes: {
|
|
501
|
+
type: "boolean",
|
|
502
|
+
alias: "y",
|
|
503
|
+
description: "Deploy without asking for a confirmation",
|
|
504
|
+
default: false
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
async run({ args }) {
|
|
508
|
+
await runCommandsDeploy({
|
|
509
|
+
config: args.config,
|
|
510
|
+
cwd: args.cwd,
|
|
511
|
+
guild: args.guild,
|
|
512
|
+
json: args.json,
|
|
513
|
+
yes: args.yes
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
const SUBCOMMANDS = [
|
|
518
|
+
"list",
|
|
519
|
+
"clean",
|
|
520
|
+
"diff",
|
|
521
|
+
"deploy"
|
|
522
|
+
];
|
|
275
523
|
var commands_default = defineCommand({
|
|
276
524
|
meta: {
|
|
277
525
|
name: "commands",
|
|
278
|
-
description: "Inspect and clean the application commands deployed to Discord"
|
|
526
|
+
description: "Inspect, compare, deploy and clean the application commands deployed to Discord"
|
|
279
527
|
},
|
|
280
528
|
subCommands: {
|
|
281
529
|
list,
|
|
282
|
-
clean
|
|
530
|
+
clean,
|
|
531
|
+
diff,
|
|
532
|
+
deploy
|
|
283
533
|
},
|
|
284
534
|
args: scopeArgs,
|
|
285
535
|
async run({ args, rawArgs }) {
|
|
286
|
-
if (rawArgs.some((argument) => argument
|
|
536
|
+
if (rawArgs.some((argument) => SUBCOMMANDS.includes(argument))) return;
|
|
287
537
|
await runCommandsList({
|
|
288
538
|
config: args.config,
|
|
289
539
|
cwd: args.cwd,
|
|
@@ -295,4 +545,4 @@ var commands_default = defineCommand({
|
|
|
295
545
|
|
|
296
546
|
//#endregion
|
|
297
547
|
export { commands_default as default };
|
|
298
|
-
//# sourceMappingURL=commands-
|
|
548
|
+
//# sourceMappingURL=commands-DVC7ky6f.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands-DVC7ky6f.js","names":[],"sources":["../src/utils/discord.ts","../src/utils/local-commands.ts","../src/utils/prompts.ts","../src/commands/commands.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { cliDiagnostics } from './diagnostics.js';\nimport { readDiscordCredentials } from '../dev/tunnel.js';\n\nconst API = 'https://discord.com/api/v10';\n\nexport interface ApplicationCommand {\n\tid: string;\n\tapplication_id: string;\n\tname: string;\n\tdescription?: string;\n\ttype?: number;\n\tguild_id?: string;\n\tversion?: string;\n}\n\nexport interface DiscordClient {\n\tapplicationId: string;\n\tlistCommands(guildId: string | null): Promise<ApplicationCommand[]>;\n\tdeleteCommand(guildId: string | null, commandId: string): Promise<void>;\n\t/** Replaces every command of the scope with `commands` (Discord's bulk overwrite): what is not listed is deleted. */\n\tputCommands(guildId: string | null, commands: readonly object[]): Promise<ApplicationCommand[]>;\n}\n\nexport const COMMAND_TYPE_NAMES: Record<number, string> = { 1: 'chat input', 2: 'user', 3: 'message' };\n\n/**\n * A minimal Discord REST client for what `stars commands` manages. The credentials come from the environment or the\n * project's `.env`, the same place the bot reads them from once it starts.\n */\nexport function createDiscordClient(config: ResolvedStarsConfig, env: NodeJS.ProcessEnv = process.env): DiscordClient {\n\tconst credentials = readDiscordCredentials(config, env);\n\tif (!credentials) {\n\t\tthrow cliDiagnostics.DISCORD_TOKEN_MISSING({});\n\t}\n\n\tif (!credentials.applicationId) {\n\t\tthrow cliDiagnostics.DISCORD_APPLICATION_ID_MISSING({});\n\t}\n\n\tconst applicationId = credentials.applicationId;\n\tconst scope = (guildId: string | null) =>\n\t\tguildId ? `/applications/${applicationId}/guilds/${guildId}/commands` : `/applications/${applicationId}/commands`;\n\n\tconst request = async (method: string, path: string, payload?: unknown): Promise<unknown> => {\n\t\tconst response = await fetch(`${API}${path}`, {\n\t\t\tmethod,\n\t\t\theaders: { authorization: `Bot ${credentials.token}`, ...(payload === undefined ? {} : { 'content-type': 'application/json' }) },\n\t\t\t...(payload === undefined ? {} : { body: JSON.stringify(payload) }),\n\t\t\tsignal: AbortSignal.timeout(15_000)\n\t\t});\n\n\t\tif (response.status === 204) return null;\n\n\t\tconst body: unknown = await response.json().catch(() => null);\n\t\tif (!response.ok) {\n\t\t\tconst detail = typeof body === 'object' && body !== null && 'message' in body ? String((body as { message: unknown }).message) : '';\n\t\t\tthrow cliDiagnostics.DISCORD_REQUEST_FAILED({ status: response.status, detail });\n\t\t}\n\n\t\treturn body;\n\t};\n\n\treturn {\n\t\tapplicationId,\n\t\tasync listCommands(guildId) {\n\t\t\tconst body = await request('GET', scope(guildId));\n\t\t\treturn Array.isArray(body) ? (body as ApplicationCommand[]) : [];\n\t\t},\n\t\tasync deleteCommand(guildId, commandId) {\n\t\t\tawait request('DELETE', `${scope(guildId)}/${commandId}`);\n\t\t},\n\t\tasync putCommands(guildId, commands) {\n\t\t\tconst body = await request('PUT', scope(guildId), commands);\n\t\t\treturn Array.isArray(body) ? (body as ApplicationCommand[]) : [];\n\t\t}\n\t};\n}\n","import type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport { displayPath } from '@wolfstar/schema';\nimport { spawn } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { BRIDGE_FRAMEWORK_VERSION, bridgeImportArgs, DUMP_ENV, parseBridgeMessage, type CommandSnapshot } from '../dev/bridge.js';\nimport { cliDiagnostics } from './diagnostics.js';\nimport { envImportArgs, moduleImportArgs } from './env-import.js';\n\nexport interface ReadLocalCommandsOptions {\n\t/** Milliseconds the bot gets to load its pieces. */\n\ttimeout?: number;\n}\n\n/**\n * The application commands the project defines, as the bot itself would register them.\n *\n * Commands are declared with builders and decorators that only exist once the bot's modules ran, so nothing short of\n * running them knows the answer. This starts the built bot with the dev bridge in its \"dump\" mode: it loads its\n * pieces, reports its registry over IPC and exits before it listens or talks to Discord.\n *\n * It is a plain start of the bot, not a `stars dev` session: `STARS_DEV` is not set, so commands a project only\n * registers while developing are not part of what `stars commands deploy` deploys.\n */\nexport async function readLocalCommands(config: ResolvedStarsConfig, options: ReadLocalCommandsOptions = {}): Promise<CommandSnapshot> {\n\tif (!existsSync(config.build.output)) {\n\t\tthrow cliDiagnostics.LOCAL_COMMANDS_UNAVAILABLE({\n\t\t\treason: `${displayPath(config.root, config.build.output)} does not exist`,\n\t\t\tfix: 'Run `stars build` first: the commands are read from the built bot.'\n\t\t});\n\t}\n\n\tconst bridge = bridgeImportArgs(config);\n\tif (bridge.length === 0) {\n\t\tthrow cliDiagnostics.LOCAL_COMMANDS_UNAVAILABLE({\n\t\t\treason: `@wolfstar/http-framework ${BRIDGE_FRAMEWORK_VERSION} or later is not installed in ${config.root}`,\n\t\t\tfix: `Install @wolfstar/http-framework@^${BRIDGE_FRAMEWORK_VERSION} in the project.`\n\t\t});\n\t}\n\n\tconst child = spawn(\n\t\tprocess.execPath,\n\t\t[...envImportArgs(config), ...moduleImportArgs(config), ...bridge, ...config.dev.nodeArgs, config.build.output, ...config.dev.args],\n\t\t{\n\t\t\tcwd: config.root,\n\t\t\t// The environment the commands are read under is the caller's: `NODE_ENV=production stars commands deploy`\n\t\t\t// deploys what a production start registers. Unset, it is development, like the project's env files.\n\t\t\tenv: { ...process.env, ...config.dev.env, NODE_ENV: process.env.NODE_ENV ?? 'development', [DUMP_ENV]: '1' },\n\t\t\tstdio: ['ignore', 'ignore', 'pipe', 'ipc'],\n\t\t\twindowsHide: true\n\t\t}\n\t);\n\n\treturn new Promise<CommandSnapshot>((resolve, reject) => {\n\t\tlet stderr = '';\n\t\tlet settled = false;\n\t\tconst finish = (action: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tclearTimeout(timer);\n\t\t\taction();\n\t\t};\n\t\tconst unavailable = (reason: string) =>\n\t\t\tcliDiagnostics.LOCAL_COMMANDS_UNAVAILABLE({\n\t\t\t\treason,\n\t\t\t\tfix: 'Check that the bot starts with `stars dev`: it has to construct its `Client` and call `client.load()`.'\n\t\t\t});\n\n\t\tconst timer = setTimeout(() => {\n\t\t\tchild.kill('SIGKILL');\n\t\t\tfinish(() => reject(unavailable('the bot did not load its commands in time')));\n\t\t}, options.timeout ?? 30_000);\n\n\t\tchild.stderr?.on('data', (chunk: Buffer) => (stderr = `${stderr}${chunk.toString()}`.slice(-2000)));\n\t\tlet snapshot: CommandSnapshot | null = null;\n\t\tchild.on('message', (message) => {\n\t\t\tconst parsed = parseBridgeMessage(message);\n\t\t\tif (parsed?.type !== 'commands' || snapshot !== null) return;\n\t\t\tsnapshot = { global: parsed.global, guilds: parsed.guilds };\n\t\t\t// The bot exits on its own once the message is flushed. The answer waits for that: until then the process\n\t\t\t// still holds the project directory (its working directory), which Windows refuses to let go of.\n\t\t\tsetTimeout(() => child.kill('SIGKILL'), 2000).unref();\n\t\t});\n\t\tchild.once('error', (error) => finish(() => reject(unavailable(error.message))));\n\t\tchild.once('exit', (code) => {\n\t\t\tif (snapshot !== null) {\n\t\t\t\tconst commands = snapshot;\n\t\t\t\tfinish(() => resolve(commands));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst detail = stderr.trim().split('\\n').at(-1);\n\t\t\tfinish(() => reject(unavailable(`the bot exited with code ${code} before loading its commands${detail ? ` (${detail})` : ''}`)));\n\t\t});\n\t});\n}\n","import type { Diagnostic } from 'nostics';\nimport type { ApplicationCommand } from './discord.js';\nimport { cliDiagnostics } from './diagnostics.js';\n\nexport interface CommandsPrompt {\n\t/** Asks which of the deployed commands to delete. Returns the chosen ids. */\n\tpick(commands: readonly ApplicationCommand[], scope: string): Promise<string[]>;\n\t/** Final go/no-go before anything is deleted. */\n\tconfirm(message: string): Promise<boolean>;\n}\n\n/**\n * The interactive wizard behind `stars commands clean`: a checklist of what Discord has deployed, then a\n * confirmation, so a destructive cleanup is never one keystroke away. `@clack/prompts` is loaded lazily — the\n * non-interactive paths (`--yes`, `--json`, CI) never pay for it.\n */\nexport function createClackPrompt(): CommandsPrompt {\n\treturn {\n\t\tasync pick(commands, scope) {\n\t\t\tconst { isCancel, multiselect } = await import('@clack/prompts');\n\t\t\tconst answer = await multiselect({\n\t\t\t\tmessage: `Which commands should be deleted from ${scope}?`,\n\t\t\t\toptions: commands.map((command) => ({\n\t\t\t\t\tvalue: command.id,\n\t\t\t\t\tlabel: command.name,\n\t\t\t\t\thint: [describeType(command), command.id].filter(Boolean).join(' · ')\n\t\t\t\t})),\n\t\t\t\trequired: false\n\t\t\t});\n\n\t\t\tif (isCancel(answer)) throw aborted();\n\t\t\treturn answer as string[];\n\t\t},\n\t\tasync confirm(message) {\n\t\t\tconst { confirm, isCancel } = await import('@clack/prompts');\n\t\t\tconst answer = await confirm({ message, initialValue: false });\n\n\t\t\tif (isCancel(answer)) throw aborted();\n\t\t\treturn Boolean(answer);\n\t\t}\n\t};\n}\n\nfunction describeType(command: ApplicationCommand): string {\n\tswitch (command.type) {\n\t\tcase 2:\n\t\t\treturn 'user';\n\t\tcase 3:\n\t\t\treturn 'message';\n\t\tdefault:\n\t\t\treturn 'chat input';\n\t}\n}\n\nfunction aborted(): Diagnostic {\n\treturn cliDiagnostics.ABORTED({});\n}\n","import { applyEnvOptions, loadProject, withProjectEnv } from '../utils/hooks.js';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport type { Diagnostic } from 'nostics';\nimport type { ResolvedStarsConfig } from '@wolfstar/schema';\nimport type { CommandData, CommandSnapshot } from '../dev/bridge.js';\nimport { describeCommand, diffCommands, matchesDeployed, type CommandChange } from '../utils/command-diff.js';\nimport { COMMAND_TYPE_NAMES, createDiscordClient, type ApplicationCommand, type DiscordClient } from '../utils/discord.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport { readLocalCommands } from '../utils/local-commands.js';\nimport { shouldUseColor } from '../utils/output-mode.js';\nimport { createClackPrompt, type CommandsPrompt } from '../utils/prompts.js';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\n\nexport interface CommandsTaskOptions extends ProjectArgs {\n\t/** A guild id to work on the guild-scoped commands instead of the global ones. */\n\tguild?: string;\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n\t/** Overrides the client, for tests. */\n\tclient?: DiscordClient;\n}\n\nexport interface CommandsCleanOptions extends CommandsTaskOptions {\n\t/** Names to delete; without any, the wizard asks which of the deployed commands to remove. */\n\tnames?: string[];\n\t/** Deletes without asking. Required in a non-interactive terminal. */\n\tyes?: boolean;\n\tstdin?: NodeJS.ReadableStream & { isTTY?: boolean };\n\t/** Overrides the interactive wizard, for tests. */\n\tprompt?: CommandsPrompt;\n}\n\nexport interface CommandsDiffOptions extends CommandsTaskOptions {\n\t/** Fails when the deployed commands differ, for CI. */\n\tcheck?: boolean;\n\t/** Overrides the commands read from the built bot, for tests. */\n\tlocal?: CommandSnapshot;\n}\n\nexport interface CommandsDeployOptions extends CommandsDiffOptions {\n\t/** Deploys without asking. Required in a non-interactive terminal. */\n\tyes?: boolean;\n\tstdin?: NodeJS.ReadableStream & { isTTY?: boolean };\n\t/** Overrides the confirmation, for tests. */\n\tprompt?: Pick<CommandsPrompt, 'confirm'>;\n}\n\n/**\n * Lists the application commands Discord currently has deployed, which is not necessarily what the project would\n * register today: renamed and removed commands stay until something deletes them.\n */\nexport async function runCommandsList(options: CommandsTaskOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst { client, guild } = await connect(options);\n\tconst commands = await client.listCommands(guild);\n\n\tif (options.json) {\n\t\tstdout.write(`${JSON.stringify({ applicationId: client.applicationId, guildId: guild, commands }, null, 2)}\\n`);\n\t\treturn;\n\t}\n\n\tif (commands.length === 0) {\n\t\tstdout.write(`${colors.dim('stars')} no ${guild ? `commands in guild ${guild}` : 'global commands'} are deployed\\n`);\n\t\treturn;\n\t}\n\n\tstdout.write(`${colors.dim('stars')} ${commands.length} ${guild ? `command(s) in guild ${guild}` : 'global command(s)'}\\n`);\n\tfor (const command of commands) stdout.write(` ${colors.bold(describeName(command))} ${colors.dim(command.id)}\\n`);\n}\n\n/**\n * Deletes deployed application commands. Discord keeps whatever was registered last, so this is the way to clear\n * commands a project no longer defines (or a whole guild's test deployment).\n */\nexport async function runCommandsClean(options: CommandsCleanOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst { client, guild } = await connect(options);\n\tconst deployed = await client.listCommands(guild);\n\tconst wanted = options.names?.filter((name) => name.length > 0) ?? [];\n\n\tconst missing = wanted.filter((name) => !deployed.some((command) => command.name === name));\n\tif (missing.length > 0) {\n\t\tthrow cliDiagnostics.COMMAND_NOT_FOUND({ names: missing.join(', ') });\n\t}\n\n\tif (deployed.length === 0) {\n\t\tif (options.json) stdout.write(`${JSON.stringify({ deleted: [] }, null, 2)}\\n`);\n\t\telse stdout.write(`${colors.dim('stars')} nothing to delete\\n`);\n\t\treturn;\n\t}\n\n\tconst scope = guild ? `guild ${guild}` : 'the global scope';\n\tconst targets = await selectTargets(options, deployed, wanted, scope, stdout, colors);\n\tif (targets.length === 0) {\n\t\tif (options.json) stdout.write(`${JSON.stringify({ deleted: [] }, null, 2)}\\n`);\n\t\telse stdout.write(`${colors.dim('stars')} nothing to delete\\n`);\n\t\treturn;\n\t}\n\n\tfor (const command of targets) {\n\t\tawait client.deleteCommand(guild, command.id);\n\t\tif (!options.json) stdout.write(`${colors.dim('stars')} ${colors.red('deleted')} ${describeName(command)}\\n`);\n\t}\n\n\tif (options.json) stdout.write(`${JSON.stringify({ deleted: targets.map((command) => ({ id: command.id, name: command.name })) }, null, 2)}\\n`);\n}\n\nconst SYMBOLS = { added: '+', removed: '-', changed: '~' } as const;\n\n/**\n * What a deploy of `guild` (or the global scope) would change: the commands the project defines for it against the\n * ones Discord has. A command is `changed` when the project's definition no longer matches (see `matchesDeployed`).\n */\nasync function compare(options: CommandsDiffOptions): Promise<{\n\tclient: DiscordClient;\n\tguild: string | null;\n\tlocal: CommandData[];\n\tchanges: CommandChange[];\n}> {\n\tconst project = await loadProject({ cwd: resolveCwd(options), configFile: options.config });\n\t// What the bot is started with: `env:options` (and varlock) may pick other env files than the defaults.\n\tconst config = withProjectEnv(await applyEnvOptions(project.config, project.hooks));\n\tconst { client, guild } = connectTo(config, options);\n\tconst snapshot = options.local ?? (await readLocalCommands(config));\n\tconst local = guild === null ? snapshot.global : (snapshot.guilds[guild] ?? []);\n\tconst deployed = (await client.listCommands(guild)) as unknown as CommandData[];\n\t// Seen from Discord: what a deploy would add to, change in and remove from the deployed commands.\n\treturn { client, guild, local, changes: diffCommands(deployed, local, guild, (old, next) => matchesDeployed(next, old)) };\n}\n\nfunction writeChanges(stdout: NodeJS.WritableStream, colors: ReturnType<typeof createColors>, changes: readonly CommandChange[]): void {\n\tconst paint = { added: colors.green, removed: colors.red, changed: colors.yellow };\n\tfor (const change of changes) {\n\t\tstdout.write(\n\t\t\t` ${paint[change.kind](`${SYMBOLS[change.kind]} ${describeCommand({ ...change, guild: null })}`)} ${colors.dim(change.kind)}\\n`\n\t\t);\n\t}\n}\n\n/**\n * Compares the commands the project defines with the ones Discord has deployed, without changing anything: what\n * `stars commands deploy` would do. `--check` makes a difference an error, for CI.\n */\nexport async function runCommandsDiff(options: CommandsDiffOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst { client, guild, changes } = await compare(options);\n\n\tif (options.json) {\n\t\tstdout.write(`${JSON.stringify({ applicationId: client.applicationId, guildId: guild, changes }, null, 2)}\\n`);\n\t} else if (changes.length === 0) {\n\t\tstdout.write(`${colors.dim('stars')} ${guild ? `guild ${guild}` : 'the global scope'} is up to date\\n`);\n\t} else {\n\t\tstdout.write(`${colors.dim('stars')} ${changes.length} difference(s) in ${guild ? `guild ${guild}` : 'the global scope'}\\n`);\n\t\twriteChanges(stdout, colors, changes);\n\t}\n\n\tif (options.check && changes.length > 0) throw cliDiagnostics.COMMANDS_DIFFER({ count: changes.length });\n}\n\n/**\n * Deploys the commands the project defines to Discord with a bulk overwrite: a deployed command the project no\n * longer defines is deleted. It shows what will change and asks first; scripts pass `--yes`.\n */\nexport async function runCommandsDeploy(options: CommandsDeployOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst { client, guild, local, changes } = await compare(options);\n\tconst scope = guild ? `guild ${guild}` : 'the global scope';\n\n\tif (changes.length === 0) {\n\t\tif (options.json) stdout.write(`${JSON.stringify({ applicationId: client.applicationId, guildId: guild, deployed: 0, changes }, null, 2)}\\n`);\n\t\telse stdout.write(`${colors.dim('stars')} ${scope} is up to date, nothing to deploy\\n`);\n\t\treturn;\n\t}\n\n\tif (!options.json) {\n\t\tstdout.write(`${colors.dim('stars')} deploying to ${scope}\\n`);\n\t\twriteChanges(stdout, colors, changes);\n\t}\n\n\tif (!options.yes) {\n\t\tconst stdin = options.stdin ?? process.stdin;\n\t\t// `--json` owns stdout: a question printed there would end up in front of the document.\n\t\tif (!options.prompt && (!stdin.isTTY || options.json)) throw cliDiagnostics.DEPLOY_CONFIRMATION_REQUIRED({});\n\t\tconst prompt = options.prompt ?? createClackPrompt();\n\t\tif (!(await prompt.confirm(`Overwrite the commands of ${scope} with the ${local.length} the project defines?`))) {\n\t\t\tthrow cliDiagnostics.ABORTED({});\n\t\t}\n\t}\n\n\tconst deployed = await client.putCommands(guild, local);\n\tif (options.json) {\n\t\tstdout.write(`${JSON.stringify({ applicationId: client.applicationId, guildId: guild, deployed: deployed.length, changes }, null, 2)}\\n`);\n\t} else {\n\t\tstdout.write(`${colors.dim('stars')} ${colors.green('deployed')} ${deployed.length} command(s) to ${scope}\\n`);\n\t}\n}\n\n/**\n * Works out what to delete: `--name` (and `--yes`) keep the command scriptable, while a bare `stars commands clean`\n * on a terminal runs the wizard — a checklist of what Discord has deployed, then a confirmation.\n */\nasync function selectTargets(\n\toptions: CommandsCleanOptions,\n\tdeployed: ApplicationCommand[],\n\twanted: string[],\n\tscope: string,\n\tstdout: NodeJS.WritableStream,\n\tcolors: ReturnType<typeof createColors>\n): Promise<ApplicationCommand[]> {\n\tif (wanted.length > 0) {\n\t\tconst named = deployed.filter((command) => wanted.includes(command.name));\n\t\tif (options.yes) return named;\n\n\t\tawait confirmOrThrow(options, stdout, colors, `delete ${colors.bold(String(named.length))} command(s) from ${scope}?`);\n\t\treturn named;\n\t}\n\n\tif (options.yes) return deployed;\n\n\tconst stdin = options.stdin ?? process.stdin;\n\tif (!options.prompt && !stdin.isTTY) throw confirmationRequired();\n\n\tconst prompt = options.prompt ?? createClackPrompt();\n\tconst chosen = new Set(await prompt.pick(deployed, scope));\n\tconst targets = deployed.filter((command) => chosen.has(command.id));\n\tif (targets.length === 0) return [];\n\n\tconst names = targets.map((command) => command.name).join(', ');\n\tif (!(await prompt.confirm(`Delete ${targets.length} command(s) from ${scope}: ${names}?`))) {\n\t\tthrow cliDiagnostics.ABORTED({});\n\t}\n\n\treturn targets;\n}\n\nasync function connect(options: CommandsTaskOptions): Promise<{ client: DiscordClient; guild: string | null }> {\n\tconst { config } = await loadProject({ cwd: resolveCwd(options), configFile: options.config });\n\treturn connectTo(config, options);\n}\n\nfunction connectTo(config: ResolvedStarsConfig, options: CommandsTaskOptions): { client: DiscordClient; guild: string | null } {\n\treturn { client: options.client ?? createDiscordClient(config), guild: options.guild ?? null };\n}\n\nfunction describeName(command: ApplicationCommand): string {\n\tconst type = command.type && command.type !== 1 ? ` (${COMMAND_TYPE_NAMES[command.type] ?? `type ${command.type}`})` : '';\n\treturn `${command.name}${type}`;\n}\n\n/**\n * Deleting deployed commands is not reversible, so a terminal run asks first; scripts pass `--yes`.\n */\nasync function confirmOrThrow(\n\toptions: CommandsCleanOptions,\n\tstdout: NodeJS.WritableStream,\n\tcolors: ReturnType<typeof createColors>,\n\tquestion: string\n): Promise<void> {\n\tif (options.prompt) {\n\t\tif (await options.prompt.confirm(question)) return;\n\t\tthrow cliDiagnostics.ABORTED({});\n\t}\n\n\tconst stdin = options.stdin ?? process.stdin;\n\tif (!stdin.isTTY) throw confirmationRequired();\n\n\tstdout.write(`${colors.dim('stars')} ${question} [y/N] `);\n\treturn new Promise((resolve, reject) => {\n\t\tstdin.setEncoding?.('utf-8');\n\t\tstdin.once('data', (chunk: string) => {\n\t\t\tstdin.pause?.();\n\t\t\tconst answer = chunk.trim().toLowerCase();\n\t\t\tif (answer === 'y' || answer === 'yes') resolve();\n\t\t\telse reject(cliDiagnostics.ABORTED({}));\n\t\t});\n\t\tstdin.resume?.();\n\t});\n}\n\nfunction confirmationRequired(): Diagnostic {\n\treturn cliDiagnostics.CONFIRMATION_REQUIRED({});\n}\n\nconst scopeArgs = {\n\t...projectArgs,\n\tguild: {\n\t\ttype: 'string',\n\t\tdescription: 'Work on a guild’s commands instead of the global ones'\n\t},\n\tjson: {\n\t\ttype: 'boolean',\n\t\tdescription: 'Print machine-readable JSON',\n\t\tdefault: false\n\t}\n} as const;\n\nconst list = defineCommand({\n\tmeta: { name: 'list', description: 'List the application commands Discord has deployed' },\n\targs: scopeArgs,\n\tasync run({ args }) {\n\t\tawait runCommandsList({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json });\n\t}\n});\n\nconst clean = defineCommand({\n\tmeta: { name: 'clean', description: 'Delete deployed application commands (all of them, or the named ones)' },\n\targs: {\n\t\t...scopeArgs,\n\t\tname: {\n\t\t\ttype: 'string',\n\t\t\tdescription: 'Only delete the command with this name (repeatable)'\n\t\t},\n\t\tyes: {\n\t\t\ttype: 'boolean',\n\t\t\talias: 'y',\n\t\t\tdescription: 'Delete without asking for a confirmation',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tconst names = Array.isArray(args.name) ? args.name : args.name ? [args.name] : [];\n\t\tawait runCommandsClean({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json, names, yes: args.yes });\n\t}\n});\n\nconst diff = defineCommand({\n\tmeta: { name: 'diff', description: 'Compare the commands the built bot defines with the ones Discord has deployed' },\n\targs: {\n\t\t...scopeArgs,\n\t\tcheck: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Fail when the deployed commands differ, for CI',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tawait runCommandsDiff({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json, check: args.check });\n\t}\n});\n\nconst deploy = defineCommand({\n\tmeta: { name: 'deploy', description: 'Deploy the commands the built bot defines, replacing the deployed ones' },\n\targs: {\n\t\t...scopeArgs,\n\t\tyes: {\n\t\t\ttype: 'boolean',\n\t\t\talias: 'y',\n\t\t\tdescription: 'Deploy without asking for a confirmation',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tawait runCommandsDeploy({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json, yes: args.yes });\n\t}\n});\n\nconst SUBCOMMANDS = ['list', 'clean', 'diff', 'deploy'];\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'commands',\n\t\tdescription: 'Inspect, compare, deploy and clean the application commands deployed to Discord'\n\t},\n\tsubCommands: { list, clean, diff, deploy },\n\targs: scopeArgs,\n\tasync run({ args, rawArgs }) {\n\t\t// `stars commands` with no subcommand lists, the way `git branch` does.\n\t\tif (rawArgs.some((argument) => SUBCOMMANDS.includes(argument))) return;\n\n\t\tawait runCommandsList({ config: args.config, cwd: args.cwd, guild: args.guild, json: args.json });\n\t}\n});\n"],"mappings":"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"}
|