@wolfstar/cli 0.7.0-next-20260918190835 → 0.7.0-next-20260918191541
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/dist/{prepare-BjFq1zBC.js → _shared-Cxp93Wni.js} +4 -36
- package/dist/_shared-Cxp93Wni.js.map +1 -0
- package/dist/{args-Ch1KXUMn.js → args-Du59CLXl.js} +2 -2
- package/dist/args-Du59CLXl.js.map +1 -0
- package/dist/{build-CqVlp9y0.js → build-B7QQzVk8.js} +22 -8
- package/dist/build-B7QQzVk8.js.map +1 -0
- package/dist/cli.js +2 -51
- package/dist/cli.js.map +1 -1
- package/dist/{codegen-Do2h4Hl8.js → codegen-Ba2qI4ji.js} +36 -8
- package/dist/codegen-Ba2qI4ji.js.map +1 -0
- package/dist/{commands-DhUEYpDQ.js → commands-DOkMjyT7.js} +87 -9
- package/dist/commands-DOkMjyT7.js.map +1 -0
- package/dist/{dev-Dx9emKiU.js → dev-Q-FSs-mH.js} +48 -21
- package/dist/dev-Q-FSs-mH.js.map +1 -0
- package/dist/{errors-Bket6XFn.js → errors-DETRFkoF.js} +17 -5
- package/dist/errors-DETRFkoF.js.map +1 -0
- package/dist/{external-Bk4EESdT.js → external-DVEYf7yD.js} +3 -3
- package/dist/external-DVEYf7yD.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/{info-Bvt1Jl88.js → info-Dt6WW6Px.js} +30 -8
- package/dist/info-Dt6WW6Px.js.map +1 -0
- package/dist/{locales-C4_03V54.js → locales-CODosUiP.js} +9 -9
- package/dist/locales-CODosUiP.js.map +1 -0
- package/dist/{log-buffer-D-nj2ZEU.js → log-buffer-CY82aqnb.js} +2 -2
- package/dist/log-buffer-CY82aqnb.js.map +1 -0
- package/dist/{none-DEo7zEr9.js → none-uC_wi_l4.js} +2 -2
- package/dist/none-uC_wi_l4.js.map +1 -0
- package/dist/{output-mode-Cxes6YUW.js → output-mode-Bp7Da8vJ.js} +2 -2
- package/dist/output-mode-Bp7Da8vJ.js.map +1 -0
- package/dist/{plain-CEe4X_Cz.js → plain-B6z85uQP.js} +2 -2
- package/dist/plain-B6z85uQP.js.map +1 -0
- package/dist/{plugin-registrations-0YL8vy7b.js → plugin-registrations-4PA_qWXF.js} +2 -2
- package/dist/plugin-registrations-4PA_qWXF.js.map +1 -0
- package/dist/prepare-Dv_8yIbG.js +67 -0
- package/dist/prepare-Dv_8yIbG.js.map +1 -0
- package/dist/{project-DHF3qdm-.js → project-jVFFrLl9.js} +3 -3
- package/dist/project-jVFFrLl9.js.map +1 -0
- package/dist/run-DjjDIYTy.js +65 -0
- package/dist/run-DjjDIYTy.js.map +1 -0
- package/dist/{theme-Bosd2Kk2.js → theme-3Fc_LI-2.js} +2 -2
- package/dist/theme-3Fc_LI-2.js.map +1 -0
- package/dist/tsc-DQq_UrBf.js +3 -0
- package/dist/{tsc-D56BJ6lA.js → tsc-DeEv6Ce0.js} +5 -5
- package/dist/tsc-DeEv6Ce0.js.map +1 -0
- package/dist/{tsdown-DySpwiDI.js → tsdown-C9q3H3MK.js} +4 -4
- package/dist/tsdown-C9q3H3MK.js.map +1 -0
- package/dist/{tui-O94OH1w8.js → tui-BRddrLQP.js} +21 -21
- package/dist/tui-BRddrLQP.js.map +1 -0
- package/dist/{tunnel-DFfC8lJW.js → tunnel-BHHUb9Tq.js} +2 -2
- package/dist/tunnel-BHHUb9Tq.js.map +1 -0
- package/dist/{version-DN6Uho-Y.js → version-BzclCE19.js} +2 -2
- package/dist/version-BzclCE19.js.map +1 -0
- package/dist/{vite-fhNA6MyF.js → vite-BVXBSWQb.js} +4 -4
- package/dist/vite-BVXBSWQb.js.map +1 -0
- package/package.json +2 -1
- package/dist/args-Ch1KXUMn.js.map +0 -1
- package/dist/build-BouwhG0y.js +0 -22
- package/dist/build-BouwhG0y.js.map +0 -1
- package/dist/build-CqVlp9y0.js.map +0 -1
- package/dist/codegen-Do2h4Hl8.js.map +0 -1
- package/dist/codegen-y8gc147n.js +0 -36
- package/dist/codegen-y8gc147n.js.map +0 -1
- package/dist/commands-DhUEYpDQ.js.map +0 -1
- package/dist/commands-MAtrFKkH.js +0 -88
- package/dist/commands-MAtrFKkH.js.map +0 -1
- package/dist/dev-BgpW3Gsr.js +0 -36
- package/dist/dev-BgpW3Gsr.js.map +0 -1
- package/dist/dev-Dx9emKiU.js.map +0 -1
- package/dist/errors-Bket6XFn.js.map +0 -1
- package/dist/external-Bk4EESdT.js.map +0 -1
- package/dist/info-Bvt1Jl88.js.map +0 -1
- package/dist/info-pX-M8R11.js +0 -30
- package/dist/info-pX-M8R11.js.map +0 -1
- package/dist/locales-C4_03V54.js.map +0 -1
- package/dist/log-buffer-D-nj2ZEU.js.map +0 -1
- package/dist/none-DEo7zEr9.js.map +0 -1
- package/dist/output-mode-Cxes6YUW.js.map +0 -1
- package/dist/plain-CEe4X_Cz.js.map +0 -1
- package/dist/plugin-registrations-0YL8vy7b.js.map +0 -1
- package/dist/prepare-B0xgciBK.js +0 -3
- package/dist/prepare-BjFq1zBC.js.map +0 -1
- package/dist/prepare-Glg8-d0r.js +0 -36
- package/dist/prepare-Glg8-d0r.js.map +0 -1
- package/dist/project-DHF3qdm-.js.map +0 -1
- package/dist/theme-Bosd2Kk2.js.map +0 -1
- package/dist/tsc-D3FXjM6P.js +0 -3
- package/dist/tsc-D56BJ6lA.js.map +0 -1
- package/dist/tsdown-DySpwiDI.js.map +0 -1
- package/dist/tui-O94OH1w8.js.map +0 -1
- package/dist/tunnel-DFfC8lJW.js.map +0 -1
- package/dist/version-DN6Uho-Y.js.map +0 -1
- package/dist/vite-fhNA6MyF.js.map +0 -1
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import { n as ExitCode, t as CliError } from "./errors-Bket6XFn.js";
|
|
2
|
-
import { i as shouldUseColor } from "./output-mode-Cxes6YUW.js";
|
|
3
|
-
import { n as resolveCwd } from "./args-Ch1KXUMn.js";
|
|
4
1
|
import { createRequire } from "node:module";
|
|
5
|
-
import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
|
|
6
2
|
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
7
|
-
import { createColors } from "colorette";
|
|
8
3
|
import { generateAutoImportsDts } from "@wolfstar/http-framework/auto-imports";
|
|
9
4
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
10
5
|
|
|
11
|
-
//#region src/
|
|
6
|
+
//#region src/utils/tsconfig.ts
|
|
12
7
|
const require = createRequire(import.meta.url);
|
|
13
8
|
const sapphireOptions = Object.assign({}, ...[
|
|
14
9
|
"@sapphire/ts-config",
|
|
@@ -75,34 +70,7 @@ async function prepareTsconfig(config, check = false) {
|
|
|
75
70
|
}
|
|
76
71
|
|
|
77
72
|
//#endregion
|
|
78
|
-
//#region src/
|
|
79
|
-
/**
|
|
80
|
-
* Generates `.stars/tsconfig.json` and `imports.dts` (see {@link StarsImportsConfig} in `@wolfstar/http-framework/config`), the way `nuxt
|
|
81
|
-
* prepare` regenerates `.nuxt/imports.d.ts`. Run automatically by `stars dev` and `stars build` before the first
|
|
82
|
-
* build; `--check` fails instead of writing, for CI.
|
|
83
|
-
*/
|
|
84
|
-
async function runPrepare(options) {
|
|
85
|
-
const stdout = options.stdout ?? process.stdout;
|
|
86
|
-
const colors = createColors({ useColor: shouldUseColor() && !options.json });
|
|
87
|
-
const config = await loadStarsConfig({
|
|
88
|
-
cwd: resolveCwd(options),
|
|
89
|
-
configFile: options.config
|
|
90
|
-
});
|
|
91
|
-
const result = await prepareProject(config, Boolean(options.check));
|
|
92
|
-
if (options.json) stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
93
|
-
else {
|
|
94
|
-
const paintConfig = result.tsconfig.status === "outdated" ? colors.red : colors.green;
|
|
95
|
-
stdout.write(`${colors.dim("stars")} tsconfig: ${paintConfig(result.tsconfig.status)} ${displayPath(config.root, result.tsconfig.path)}\n`);
|
|
96
|
-
if (result.enabled) {
|
|
97
|
-
const paint = result.status === "outdated" ? colors.red : colors.green;
|
|
98
|
-
stdout.write(`${colors.dim("stars")} imports: ${paint(result.status)} ${displayPath(config.root, result.dts)}\n`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (result.status === "outdated" || result.tsconfig.status === "outdated") throw new CliError("The generated project files are out of date, run `stars prepare` to update it.", {
|
|
102
|
-
code: "PREPARE_OUTDATED",
|
|
103
|
-
exitCode: ExitCode.Error
|
|
104
|
-
});
|
|
105
|
-
}
|
|
73
|
+
//#region src/commands/_shared.ts
|
|
106
74
|
/**
|
|
107
75
|
* Regenerates `imports.dts` unconditionally, used by `stars dev`/`stars build` before the first build so the
|
|
108
76
|
* declaration file exists (and is current) even when the user never ran `stars prepare` themselves.
|
|
@@ -143,5 +111,5 @@ async function prepareProject(config, check = false) {
|
|
|
143
111
|
}
|
|
144
112
|
|
|
145
113
|
//#endregion
|
|
146
|
-
export { prepareProject as
|
|
147
|
-
//# sourceMappingURL=
|
|
114
|
+
export { prepareProject as t };
|
|
115
|
+
//# sourceMappingURL=_shared-Cxp93Wni.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_shared-Cxp93Wni.js","names":[],"sources":["../src/utils/tsconfig.ts","../src/commands/_shared.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { createRequire } from 'node:module';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join, relative, resolve } from 'node:path';\n\nconst require = createRequire(import.meta.url);\nconst sapphireOptions = Object.assign(\n\t{},\n\t...['@sapphire/ts-config', '@sapphire/ts-config/extra-strict', '@sapphire/ts-config/decorators'].map(\n\t\t(id) => (require(id) as { compilerOptions: Record<string, unknown> }).compilerOptions\n\t)\n) as Record<string, unknown>;\n\n/** Generates an extendable config without changing the project's own tsconfig. */\nexport async function prepareTsconfig(config: ResolvedStarsConfig, check = false) {\n\tconst path = join(config.root, '.stars', 'tsconfig.json');\n\tconst fromGenerated = (target: string) => `./${relative(dirname(path), target).replaceAll('\\\\', '/')}`;\n\tconst paths: Record<string, string[]> = {};\n\tif (config.build.tool === 'tsdown') {\n\t\tconst source = dirname(config.entry);\n\t\tconst defaults = config.build.configFile === null ? { '~': source, '@': source, '~~': config.root, '@@': config.root } : {};\n\t\tconst aliases = { ...defaults, ...(config.tsdown.alias as Record<string, unknown> | undefined) };\n\t\tfor (const [alias, target] of Object.entries(aliases)) {\n\t\t\t// Module redirects belong to the bundler; only filesystem targets become TypeScript paths.\n\t\t\tif (typeof target !== 'string' || (!isAbsolute(target) && !/^\\.\\.?[/\\\\]/.test(target))) continue;\n\t\t\tconst resolved = fromGenerated(resolve(config.root, target));\n\t\t\tpaths[alias] = [resolved];\n\t\t\tpaths[`${alias}/*`] = [`${resolved}/*`];\n\t\t}\n\t}\n\tconst content = `${JSON.stringify(\n\t\t{\n\t\t\tcompilerOptions: {\n\t\t\t\t...sapphireOptions,\n\t\t\t\t// Bundlers emit the application; TypeScript only checks it. Keep Node16 emit for tsc.\n\t\t\t\t...(config.build.tool === 'tsdown' || config.build.tool === 'vite'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tmodule: 'ESNext',\n\t\t\t\t\t\t\tmoduleResolution: 'Bundler',\n\t\t\t\t\t\t\tmoduleDetection: 'force',\n\t\t\t\t\t\t\tisolatedModules: true,\n\t\t\t\t\t\t\tverbatimModuleSyntax: true,\n\t\t\t\t\t\t\tallowJs: true,\n\t\t\t\t\t\t\tallowImportingTsExtensions: true,\n\t\t\t\t\t\t\tresolvePackageJsonImports: true,\n\t\t\t\t\t\t\tlib: ['ESNext', 'DOM'],\n\t\t\t\t\t\t\tnoEmit: true\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t\ttarget: 'ES2022',\n\t\t\t\tforceConsistentCasingInFileNames: true,\n\t\t\t\tskipLibCheck: true,\n\t\t\t\ttsBuildInfoFile: './tsconfig.tsbuildinfo',\n\t\t\t\tpaths\n\t\t\t},\n\t\t\tinclude: [`${fromGenerated(dirname(config.entry))}/**/*`, ...(config.imports.enabled ? [fromGenerated(config.imports.dts)] : [])],\n\t\t\texclude: [fromGenerated(join(config.root, 'node_modules')), fromGenerated(config.build.outDir)]\n\t\t},\n\t\tnull,\n\t\t2\n\t)}\\n`;\n\tif (check) {\n\t\tconst existing = await readFile(path, 'utf-8').catch(() => null);\n\t\treturn { path, status: existing === content ? ('up-to-date' as const) : ('outdated' as const) };\n\t}\n\tawait mkdir(dirname(path), { recursive: true });\n\tawait writeFile(path, content);\n\treturn { path, status: 'written' as const };\n}\n","import { generateAutoImportsDts } from '@wolfstar/http-framework/auto-imports';\nimport type { ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { prepareTsconfig } from '../utils/tsconfig.js';\n\nexport type PrepareResult =\n\t| { enabled: false; dts: null; status: null }\n\t| { enabled: true; dts: string; status: 'written' | 'up-to-date' | 'outdated' };\n\n/**\n * Regenerates `imports.dts` unconditionally, used by `stars dev`/`stars build` before the first build so the\n * declaration file exists (and is current) even when the user never ran `stars prepare` themselves.\n */\nexport async function prepareAutoImports(config: ResolvedStarsConfig, check = false): Promise<PrepareResult> {\n\tif (!config.imports.enabled) return { enabled: false, dts: null, status: null };\n\n\tconst { dirs, presets, exclude, dts } = config.imports;\n\tconst content = await generateAutoImportsDts({ root: config.root, dirs, presets, exclude });\n\n\tif (check) {\n\t\tconst existing = await readFile(dts, 'utf-8').catch(() => null);\n\t\treturn { enabled: true, dts, status: existing === content ? 'up-to-date' : 'outdated' };\n\t}\n\n\tawait mkdir(dirname(dts), { recursive: true });\n\tawait writeFile(dts, content);\n\treturn { enabled: true, dts, status: 'written' };\n}\n\n/** Prepares TypeScript configuration and auto import declarations before building. */\nexport async function prepareProject(config: ResolvedStarsConfig, check = false) {\n\tconst tsconfig = await prepareTsconfig(config, check);\n\treturn { ...(await prepareAutoImports(config, check)), tsconfig };\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
2
|
|
|
3
|
-
//#region src/
|
|
3
|
+
//#region src/utils/args.ts
|
|
4
4
|
/**
|
|
5
5
|
* Arguments shared by every command that reads the project configuration.
|
|
6
6
|
*/
|
|
@@ -21,4 +21,4 @@ function resolveCwd(args) {
|
|
|
21
21
|
|
|
22
22
|
//#endregion
|
|
23
23
|
export { resolveCwd as n, projectArgs as t };
|
|
24
|
-
//# sourceMappingURL=args-
|
|
24
|
+
//# sourceMappingURL=args-Du59CLXl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args-Du59CLXl.js","names":[],"sources":["../src/utils/args.ts"],"sourcesContent":["import type { ArgsDef } from 'citty';\nimport { resolve } from 'node:path';\n\n/**\n * Arguments shared by every command that reads the project configuration.\n */\nexport const projectArgs = {\n\tconfig: {\n\t\ttype: 'string',\n\t\talias: 'c',\n\t\tdescription: 'Path to the configuration file (defaults to stars.config.* in the working directory)'\n\t},\n\tcwd: {\n\t\ttype: 'string',\n\t\tdescription: 'Working directory to run from (defaults to the current directory)'\n\t}\n} as const satisfies ArgsDef;\n\nexport interface ProjectArgs {\n\tconfig?: string;\n\tcwd?: string;\n}\n\nexport function resolveCwd(args: ProjectArgs): string {\n\treturn args.cwd ? resolve(process.cwd(), args.cwd) : process.cwd();\n}\n"],"mappings":";;;;;;AAMA,MAAa,cAAc;CAC1B,QAAQ;EACP,MAAM;EACN,OAAO;EACP,aAAa;CACd;CACA,KAAK;EACJ,MAAM;EACN,aAAa;CACd;AACD;AAOA,SAAgB,WAAW,MAA2B;CACrD,OAAO,KAAK,MAAM,QAAQ,QAAQ,IAAI,GAAG,KAAK,GAAG,IAAI,QAAQ,IAAI;AAClE"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { n as ExitCode, t as CliError } from "./errors-
|
|
2
|
-
import { i as shouldUseColor } from "./output-mode-
|
|
3
|
-
import { n as
|
|
4
|
-
import { n as
|
|
5
|
-
import {
|
|
1
|
+
import { n as ExitCode, t as CliError } from "./errors-DETRFkoF.js";
|
|
2
|
+
import { i as shouldUseColor } from "./output-mode-Bp7Da8vJ.js";
|
|
3
|
+
import { n as assertSupportedExperiments, r as createBuilder, t as Locales } from "./locales-CODosUiP.js";
|
|
4
|
+
import { n as resolveCwd, t as projectArgs } from "./args-Du59CLXl.js";
|
|
5
|
+
import { t as prepareProject } from "./_shared-Cxp93Wni.js";
|
|
6
|
+
import { defineCommand } from "citty";
|
|
6
7
|
import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
|
|
7
8
|
import { createColors } from "colorette";
|
|
8
9
|
|
|
9
|
-
//#region src/
|
|
10
|
+
//#region src/commands/build.ts
|
|
10
11
|
async function runBuild(options) {
|
|
11
12
|
const stdout = options.stdout ?? process.stdout;
|
|
12
13
|
const colors = createColors({ useColor: shouldUseColor() });
|
|
@@ -34,7 +35,20 @@ async function runBuild(options) {
|
|
|
34
35
|
new Locales(config).copy();
|
|
35
36
|
stdout.write(`${colors.dim("stars")} ${colors.green(`built in ${outcome.durationMs}ms`)} → ${displayPath(config.root, config.build.output)}\n`);
|
|
36
37
|
}
|
|
38
|
+
var build_default = defineCommand({
|
|
39
|
+
meta: {
|
|
40
|
+
name: "build",
|
|
41
|
+
description: "Build the project once with the configured build tool"
|
|
42
|
+
},
|
|
43
|
+
args: { ...projectArgs },
|
|
44
|
+
async run({ args }) {
|
|
45
|
+
await runBuild({
|
|
46
|
+
config: args.config,
|
|
47
|
+
cwd: args.cwd
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
37
51
|
|
|
38
52
|
//#endregion
|
|
39
|
-
export {
|
|
40
|
-
//# sourceMappingURL=build-
|
|
53
|
+
export { build_default as default };
|
|
54
|
+
//# sourceMappingURL=build-B7QQzVk8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-B7QQzVk8.js","names":[],"sources":["../src/commands/build.ts"],"sourcesContent":["import { displayPath, loadStarsConfig } from '@wolfstar/http-framework/config';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport { assertSupportedExperiments, createBuilder } from '../builders/index.js';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { CliError, ExitCode } from '../utils/errors.js';\nimport { Locales } from '../utils/locales.js';\nimport { shouldUseColor } from '../utils/output-mode.js';\nimport { prepareProject } from './_shared.js';\n\nexport interface BuildTaskOptions extends ProjectArgs {\n\tstdout?: NodeJS.WritableStream;\n}\n\nexport async function runBuild(options: BuildTaskOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() });\n\tconst config = await loadStarsConfig({ cwd: resolveCwd(options), configFile: options.config });\n\tassertSupportedExperiments(config);\n\tawait prepareProject(config);\n\n\tif (config.build.tool === 'none') {\n\t\tstdout.write(`${colors.dim('stars')} nothing to build, ${displayPath(config.root, config.entry)} runs as-is (build.tool is 'none')\\n`);\n\t\treturn;\n\t}\n\n\tconst builder = await createBuilder(config);\n\tbuilder.on('log', (level, text) => {\n\t\tconst paint = level === 'error' ? colors.red : level === 'warn' ? colors.yellow : (value: string) => value;\n\t\tstdout.write(`${paint(text)}\\n`);\n\t});\n\n\tstdout.write(`${colors.dim('stars')} building with ${colors.bold(config.build.tool)}…\\n`);\n\tconst outcome = await builder.build();\n\tif (!outcome.ok) {\n\t\tthrow new CliError(`Build failed${outcome.message ? `: ${outcome.message}` : ''}`, { code: 'BUILD_FAILED', exitCode: ExitCode.BuildFailed });\n\t}\n\tnew Locales(config).copy();\n\n\tstdout.write(`${colors.dim('stars')} ${colors.green(`built in ${outcome.durationMs}ms`)} → ${displayPath(config.root, config.build.output)}\\n`);\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'build',\n\t\tdescription: 'Build the project once with the configured build tool'\n\t},\n\targs: { ...projectArgs },\n\tasync run({ args }) {\n\t\tawait runBuild({ config: args.config, cwd: args.cwd });\n\t}\n});\n"],"mappings":";;;;;;;;;;AAcA,eAAsB,SAAS,SAA0C;CACxE,MAAM,SAAS,QAAQ,UAAU,QAAQ;CACzC,MAAM,SAAS,aAAa,EAAE,UAAU,eAAe,EAAE,CAAC;CAC1D,MAAM,SAAS,MAAM,gBAAgB;EAAE,KAAK,WAAW,OAAO;EAAG,YAAY,QAAQ;CAAO,CAAC;CAC7F,2BAA2B,MAAM;CACjC,MAAM,eAAe,MAAM;CAE3B,IAAI,OAAO,MAAM,SAAS,QAAQ;EACjC,OAAO,MAAM,GAAG,OAAO,IAAI,OAAO,EAAE,qBAAqB,YAAY,OAAO,MAAM,OAAO,KAAK,EAAE,qCAAqC;EACrI;CACD;CAEA,MAAM,UAAU,MAAM,cAAc,MAAM;CAC1C,QAAQ,GAAG,QAAQ,OAAO,SAAS;EAClC,MAAM,QAAQ,UAAU,UAAU,OAAO,MAAM,UAAU,SAAS,OAAO,UAAU,UAAkB;EACrG,OAAO,MAAM,GAAG,MAAM,IAAI,EAAE,GAAG;CAChC,CAAC;CAED,OAAO,MAAM,GAAG,OAAO,IAAI,OAAO,EAAE,iBAAiB,OAAO,KAAK,OAAO,MAAM,IAAI,EAAE,IAAI;CACxF,MAAM,UAAU,MAAM,QAAQ,MAAM;CACpC,IAAI,CAAC,QAAQ,IACZ,MAAM,IAAI,SAAS,eAAe,QAAQ,UAAU,KAAK,QAAQ,YAAY,MAAM;EAAE,MAAM;EAAgB,UAAU,SAAS;CAAY,CAAC;CAE5I,IAAI,QAAQ,MAAM,CAAC,CAAC,KAAK;CAEzB,OAAO,MAAM,GAAG,OAAO,IAAI,OAAO,EAAE,GAAG,OAAO,MAAM,YAAY,QAAQ,WAAW,GAAG,EAAE,KAAK,YAAY,OAAO,MAAM,OAAO,MAAM,MAAM,EAAE,GAAG;AAC/I;AAEA,oBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM,EAAE,GAAG,YAAY;CACvB,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,SAAS;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;EAAI,CAAC;CACtD;AACD,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -1,57 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { t as readOwnPackageJson } from "./version-DN6Uho-Y.js";
|
|
4
|
-
import { defineCommand, renderUsage, runCommand } from "citty";
|
|
2
|
+
import { t as runMain } from "./run-DjjDIYTy.js";
|
|
5
3
|
|
|
6
4
|
//#region src/cli.ts
|
|
7
|
-
|
|
8
|
-
const subCommands = {
|
|
9
|
-
dev: () => import("./dev-BgpW3Gsr.js").then((module) => module.default),
|
|
10
|
-
build: () => import("./build-BouwhG0y.js").then((module) => module.default),
|
|
11
|
-
info: () => import("./info-pX-M8R11.js").then((module) => module.default),
|
|
12
|
-
codegen: () => import("./codegen-y8gc147n.js").then((module) => module.default),
|
|
13
|
-
prepare: () => import("./prepare-Glg8-d0r.js").then((module) => module.default),
|
|
14
|
-
commands: () => import("./commands-MAtrFKkH.js").then((module) => module.default)
|
|
15
|
-
};
|
|
16
|
-
const main = defineCommand({
|
|
17
|
-
meta: {
|
|
18
|
-
name: "stars",
|
|
19
|
-
version: packageJson.version,
|
|
20
|
-
description: packageJson.description
|
|
21
|
-
},
|
|
22
|
-
subCommands
|
|
23
|
-
});
|
|
24
|
-
const rawArgs = process.argv.slice(2);
|
|
25
|
-
if (rawArgs.includes("--version") || rawArgs.includes("-V")) {
|
|
26
|
-
console.log(packageJson.version);
|
|
27
|
-
process.exit(0);
|
|
28
|
-
}
|
|
29
|
-
if (rawArgs.length === 0 || rawArgs.includes("--help") || rawArgs.includes("-h")) {
|
|
30
|
-
const command = await resolveHelpTarget(rawArgs.filter((argument) => !argument.startsWith("-")));
|
|
31
|
-
console.log(await (command ? renderUsage(command, main) : renderUsage(main)));
|
|
32
|
-
process.exit(0);
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Walks the command names of `stars <command> [<subcommand>] --help` so nested commands (`stars commands clean`)
|
|
36
|
-
* render their own usage instead of their parent's.
|
|
37
|
-
*/
|
|
38
|
-
async function resolveHelpTarget(names) {
|
|
39
|
-
const [first, ...rest] = names;
|
|
40
|
-
if (!first || !Object.hasOwn(subCommands, first)) return null;
|
|
41
|
-
let command = await subCommands[first]();
|
|
42
|
-
for (const name of rest) {
|
|
43
|
-
const child = (typeof command.subCommands === "function" ? await command.subCommands() : await command.subCommands)?.[name];
|
|
44
|
-
if (!child) break;
|
|
45
|
-
command = typeof child === "function" ? await child() : child;
|
|
46
|
-
}
|
|
47
|
-
return command;
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
await runCommand(main, { rawArgs });
|
|
51
|
-
} catch (error) {
|
|
52
|
-
console.error(formatError(error));
|
|
53
|
-
process.exit(exitCodeOf(error));
|
|
54
|
-
}
|
|
5
|
+
await runMain();
|
|
55
6
|
|
|
56
7
|
//#endregion
|
|
57
8
|
export { };
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport {
|
|
1
|
+
{"version":3,"file":"cli.js","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { runMain } from './run.js';\n\nawait runMain();\n"],"mappings":";;;;AAIA,MAAM,QAAQ"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { n as ExitCode, t as CliError } from "./errors-
|
|
2
|
-
import { i as shouldUseColor } from "./output-mode-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { n as ExitCode, t as CliError } from "./errors-DETRFkoF.js";
|
|
2
|
+
import { i as shouldUseColor } from "./output-mode-Bp7Da8vJ.js";
|
|
3
|
+
import { i as resolveFromProject } from "./project-jVFFrLl9.js";
|
|
4
|
+
import { n as resolveCwd, t as projectArgs } from "./args-Du59CLXl.js";
|
|
5
|
+
import { defineCommand } from "citty";
|
|
6
6
|
import { join } from "node:path";
|
|
7
|
+
import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
|
|
7
8
|
import { tmpdir } from "node:os";
|
|
8
9
|
import { spawn } from "node:child_process";
|
|
9
10
|
import { createColors } from "colorette";
|
|
10
11
|
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
|
11
12
|
|
|
12
|
-
//#region src/
|
|
13
|
+
//#region src/commands/codegen.ts
|
|
13
14
|
async function runCodegen(options) {
|
|
14
15
|
const stdout = options.stdout ?? process.stdout;
|
|
15
16
|
const colors = createColors({ useColor: shouldUseColor() && !options.json });
|
|
@@ -89,7 +90,34 @@ function generate(root, cli, locales, output) {
|
|
|
89
90
|
});
|
|
90
91
|
});
|
|
91
92
|
}
|
|
93
|
+
var codegen_default = defineCommand({
|
|
94
|
+
meta: {
|
|
95
|
+
name: "codegen",
|
|
96
|
+
description: "Run the configured code generators (i18next types)"
|
|
97
|
+
},
|
|
98
|
+
args: {
|
|
99
|
+
...projectArgs,
|
|
100
|
+
check: {
|
|
101
|
+
type: "boolean",
|
|
102
|
+
description: "Fail when the generated files are out of date instead of writing them",
|
|
103
|
+
default: false
|
|
104
|
+
},
|
|
105
|
+
json: {
|
|
106
|
+
type: "boolean",
|
|
107
|
+
description: "Print machine-readable JSON",
|
|
108
|
+
default: false
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
async run({ args }) {
|
|
112
|
+
await runCodegen({
|
|
113
|
+
config: args.config,
|
|
114
|
+
cwd: args.cwd,
|
|
115
|
+
check: args.check,
|
|
116
|
+
json: args.json
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
});
|
|
92
120
|
|
|
93
121
|
//#endregion
|
|
94
|
-
export {
|
|
95
|
-
//# sourceMappingURL=codegen-
|
|
122
|
+
export { codegen_default as default };
|
|
123
|
+
//# sourceMappingURL=codegen-Ba2qI4ji.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codegen-Ba2qI4ji.js","names":[],"sources":["../src/commands/codegen.ts"],"sourcesContent":["import { displayPath, loadStarsConfig, type ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport { spawn } from 'node:child_process';\nimport { mkdtemp, readFile, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { CliError, ExitCode } from '../utils/errors.js';\nimport { shouldUseColor } from '../utils/output-mode.js';\nimport { resolveFromProject } from '../utils/project.js';\n\nexport interface CodegenTaskOptions extends ProjectArgs {\n\tcheck?: boolean;\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n}\n\nexport interface CodegenResult {\n\tgenerator: 'i18n';\n\toutput: string;\n\tstatus: 'written' | 'up-to-date' | 'outdated';\n}\n\nexport async function runCodegen(options: CodegenTaskOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst colors = createColors({ useColor: shouldUseColor() && !options.json });\n\tconst config = await loadStarsConfig({ cwd: resolveCwd(options), configFile: options.config });\n\tconst results: CodegenResult[] = [];\n\n\tif (config.codegen.i18n) results.push(await runI18n(config, Boolean(options.check)));\n\n\tif (options.json) {\n\t\tstdout.write(`${JSON.stringify({ check: Boolean(options.check), results }, null, 2)}\\n`);\n\t} else if (results.length === 0) {\n\t\tstdout.write(`${colors.dim('stars')} nothing to generate (no code generators are configured)\\n`);\n\t} else {\n\t\tfor (const result of results) {\n\t\t\tconst paint = result.status === 'outdated' ? colors.red : colors.green;\n\t\t\tstdout.write(`${colors.dim('stars')} ${result.generator}: ${paint(result.status)} ${displayPath(config.root, result.output)}\\n`);\n\t\t}\n\t}\n\n\tif (results.some((result) => result.status === 'outdated')) {\n\t\tthrow new CliError('Generated files are out of date, run `stars codegen` to update them.', {\n\t\t\tcode: 'CODEGEN_OUTDATED',\n\t\t\texitCode: ExitCode.Error\n\t\t});\n\t}\n}\n\nasync function runI18n(config: ResolvedStarsConfig, check: boolean): Promise<CodegenResult> {\n\tconst { locales, output } = config.codegen.i18n!;\n\tconst cli = resolveFromProject(config.root, '@wolfstar/i18next-type-generator');\n\tif (!cli) {\n\t\tthrow new CliError(`\"@wolfstar/i18next-type-generator\" is not installed in ${config.root}`, {\n\t\t\tcode: 'DEPENDENCY_MISSING',\n\t\t\thint: 'Install it with `pnpm add -D @wolfstar/i18next-type-generator`, or set `codegen.i18n` to false.'\n\t\t});\n\t}\n\n\tif (!check) {\n\t\tawait generate(config.root, cli, locales, output);\n\t\treturn { generator: 'i18n', output, status: 'written' };\n\t}\n\n\tconst directory = await mkdtemp(join(tmpdir(), 'stars-codegen-'));\n\ttry {\n\t\tconst candidate = join(directory, 'i18next.d.ts');\n\t\tawait generate(config.root, cli, locales, candidate);\n\t\tconst [expected, actual] = await Promise.all([readFile(candidate, 'utf-8'), readFile(output, 'utf-8').catch(() => null)]);\n\t\treturn { generator: 'i18n', output, status: expected === actual ? 'up-to-date' : 'outdated' };\n\t} finally {\n\t\tawait rm(directory, { recursive: true, force: true });\n\t}\n}\n\nfunction generate(root: string, cli: string, locales: string, output: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst child = spawn(process.execPath, [cli, locales, output], { cwd: root, stdio: ['ignore', 'ignore', 'pipe'], windowsHide: true });\n\t\tlet stderr = '';\n\t\tchild.stderr?.on('data', (chunk: Buffer) => (stderr += chunk.toString()));\n\t\tchild.once('error', reject);\n\t\tchild.once('exit', (code) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse\n\t\t\t\treject(\n\t\t\t\t\tnew CliError(`i18next-type-generator exited with code ${code}${stderr ? `: ${stderr.trim()}` : ''}`, { code: 'CODEGEN_FAILED' })\n\t\t\t\t);\n\t\t});\n\t});\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'codegen',\n\t\tdescription: 'Run the configured code generators (i18next types)'\n\t},\n\targs: {\n\t\t...projectArgs,\n\t\tcheck: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Fail when the generated files are out of date instead of writing them',\n\t\t\tdefault: false\n\t\t},\n\t\tjson: {\n\t\t\ttype: 'boolean',\n\t\t\tdescription: 'Print machine-readable JSON',\n\t\t\tdefault: false\n\t\t}\n\t},\n\tasync run({ args }) {\n\t\tawait runCodegen({ config: args.config, cwd: args.cwd, check: args.check, json: args.json });\n\t}\n});\n"],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { t as CliError } from "./errors-
|
|
2
|
-
import { i as shouldUseColor } from "./output-mode-
|
|
3
|
-
import { n as resolveCwd } from "./args-
|
|
4
|
-
import { n as readDiscordCredentials } from "./tunnel-
|
|
1
|
+
import { t as CliError } from "./errors-DETRFkoF.js";
|
|
2
|
+
import { i as shouldUseColor } from "./output-mode-Bp7Da8vJ.js";
|
|
3
|
+
import { n as resolveCwd, t as projectArgs } from "./args-Du59CLXl.js";
|
|
4
|
+
import { n as readDiscordCredentials } from "./tunnel-BHHUb9Tq.js";
|
|
5
|
+
import { defineCommand } from "citty";
|
|
5
6
|
import { loadStarsConfig } from "@wolfstar/http-framework/config";
|
|
6
7
|
import { createColors } from "colorette";
|
|
7
8
|
|
|
8
|
-
//#region src/
|
|
9
|
+
//#region src/utils/discord.ts
|
|
9
10
|
const API = "https://discord.com/api/v10";
|
|
10
11
|
const COMMAND_TYPE_NAMES = {
|
|
11
12
|
1: "chat input",
|
|
@@ -58,7 +59,7 @@ function createDiscordClient(config, env = process.env) {
|
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
//#endregion
|
|
61
|
-
//#region src/
|
|
62
|
+
//#region src/utils/prompts.ts
|
|
62
63
|
/**
|
|
63
64
|
* The interactive wizard behind `stars commands clean`: a checklist of what Discord has deployed, then a
|
|
64
65
|
* confirmation, so a destructive cleanup is never one keystroke away. `@clack/prompts` is loaded lazily — the
|
|
@@ -103,7 +104,7 @@ function aborted() {
|
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
//#endregion
|
|
106
|
-
//#region src/
|
|
107
|
+
//#region src/commands/commands.ts
|
|
107
108
|
/**
|
|
108
109
|
* Lists the application commands Discord currently has deployed, which is not necessarily what the project would
|
|
109
110
|
* register today: renamed and removed commands stay until something deletes them.
|
|
@@ -227,7 +228,84 @@ function confirmationRequired() {
|
|
|
227
228
|
hint: "Pass --yes to delete them, or --name to pick one, from a script."
|
|
228
229
|
});
|
|
229
230
|
}
|
|
231
|
+
const scopeArgs = {
|
|
232
|
+
...projectArgs,
|
|
233
|
+
guild: {
|
|
234
|
+
type: "string",
|
|
235
|
+
description: "Work on a guild’s commands instead of the global ones"
|
|
236
|
+
},
|
|
237
|
+
json: {
|
|
238
|
+
type: "boolean",
|
|
239
|
+
description: "Print machine-readable JSON",
|
|
240
|
+
default: false
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const list = defineCommand({
|
|
244
|
+
meta: {
|
|
245
|
+
name: "list",
|
|
246
|
+
description: "List the application commands Discord has deployed"
|
|
247
|
+
},
|
|
248
|
+
args: scopeArgs,
|
|
249
|
+
async run({ args }) {
|
|
250
|
+
await runCommandsList({
|
|
251
|
+
config: args.config,
|
|
252
|
+
cwd: args.cwd,
|
|
253
|
+
guild: args.guild,
|
|
254
|
+
json: args.json
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
const clean = defineCommand({
|
|
259
|
+
meta: {
|
|
260
|
+
name: "clean",
|
|
261
|
+
description: "Delete deployed application commands (all of them, or the named ones)"
|
|
262
|
+
},
|
|
263
|
+
args: {
|
|
264
|
+
...scopeArgs,
|
|
265
|
+
name: {
|
|
266
|
+
type: "string",
|
|
267
|
+
description: "Only delete the command with this name (repeatable)"
|
|
268
|
+
},
|
|
269
|
+
yes: {
|
|
270
|
+
type: "boolean",
|
|
271
|
+
alias: "y",
|
|
272
|
+
description: "Delete without asking for a confirmation",
|
|
273
|
+
default: false
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
async run({ args }) {
|
|
277
|
+
const names = Array.isArray(args.name) ? args.name : args.name ? [args.name] : [];
|
|
278
|
+
await runCommandsClean({
|
|
279
|
+
config: args.config,
|
|
280
|
+
cwd: args.cwd,
|
|
281
|
+
guild: args.guild,
|
|
282
|
+
json: args.json,
|
|
283
|
+
names,
|
|
284
|
+
yes: args.yes
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
var commands_default = defineCommand({
|
|
289
|
+
meta: {
|
|
290
|
+
name: "commands",
|
|
291
|
+
description: "Inspect and clean the application commands deployed to Discord"
|
|
292
|
+
},
|
|
293
|
+
subCommands: {
|
|
294
|
+
list,
|
|
295
|
+
clean
|
|
296
|
+
},
|
|
297
|
+
args: scopeArgs,
|
|
298
|
+
async run({ args, rawArgs }) {
|
|
299
|
+
if (rawArgs.some((argument) => argument === "list" || argument === "clean")) return;
|
|
300
|
+
await runCommandsList({
|
|
301
|
+
config: args.config,
|
|
302
|
+
cwd: args.cwd,
|
|
303
|
+
guild: args.guild,
|
|
304
|
+
json: args.json
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
});
|
|
230
308
|
|
|
231
309
|
//#endregion
|
|
232
|
-
export {
|
|
233
|
-
//# sourceMappingURL=commands-
|
|
310
|
+
export { commands_default as default };
|
|
311
|
+
//# sourceMappingURL=commands-DOkMjyT7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands-DOkMjyT7.js","names":[],"sources":["../src/utils/discord.ts","../src/utils/prompts.ts","../src/commands/commands.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { CliError } from './errors.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}\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 new CliError('DISCORD_TOKEN is not set', {\n\t\t\tcode: 'DISCORD_TOKEN_MISSING',\n\t\t\thint: 'Set DISCORD_TOKEN in the environment or in the project .env file.'\n\t\t});\n\t}\n\n\tif (!credentials.applicationId) {\n\t\tthrow new CliError('The Discord application id is not set', {\n\t\t\tcode: 'DISCORD_APPLICATION_ID_MISSING',\n\t\t\thint: 'Set DISCORD_APPLICATION_ID (or APPLICATION_ID) in the environment or in the project .env file.'\n\t\t});\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): Promise<unknown> => {\n\t\tconst response = await fetch(`${API}${path}`, {\n\t\t\tmethod,\n\t\t\theaders: { authorization: `Bot ${credentials.token}` },\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 new CliError(`Discord answered ${response.status}${detail ? `: ${detail}` : ''}`, {\n\t\t\t\tcode: 'DISCORD_REQUEST_FAILED',\n\t\t\t\thint: response.status === 401 ? 'Check DISCORD_TOKEN.' : 'Check the application id and the bot permissions.'\n\t\t\t});\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};\n}\n","import type { ApplicationCommand } from './discord.js';\nimport { CliError } from './errors.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(): CliError {\n\treturn new CliError('Aborted', { code: 'ABORTED' });\n}\n","import { loadStarsConfig } from '@wolfstar/http-framework/config';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport { COMMAND_TYPE_NAMES, createDiscordClient, type ApplicationCommand, type DiscordClient } from '../utils/discord.js';\nimport { CliError } from '../utils/errors.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\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 new CliError(`No deployed command is named ${missing.join(', ')}`, {\n\t\t\tcode: 'COMMAND_NOT_FOUND',\n\t\t\thint: 'Run `stars commands list` to see what is deployed.'\n\t\t});\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\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 new CliError('Aborted', { code: 'ABORTED' });\n\t}\n\n\treturn targets;\n}\n\nasync function connect(options: CommandsTaskOptions): Promise<{ client: DiscordClient; guild: string | null }> {\n\tconst config = await loadStarsConfig({ cwd: resolveCwd(options), configFile: options.config });\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 new CliError('Aborted', { code: '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(new CliError('Aborted', { code: 'ABORTED' }));\n\t\t});\n\t\tstdin.resume?.();\n\t});\n}\n\nfunction confirmationRequired(): CliError {\n\treturn new CliError('Refusing to delete commands without a confirmation', {\n\t\tcode: 'CONFIRMATION_REQUIRED',\n\t\thint: 'Pass --yes to delete them, or --name to pick one, from a script.'\n\t});\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\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'commands',\n\t\tdescription: 'Inspect and clean the application commands deployed to Discord'\n\t},\n\tsubCommands: { list, clean },\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) => argument === 'list' || argument === 'clean')) 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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"}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import { n as ExitCode, t as CliError } from "./errors-
|
|
2
|
-
import { i as shouldUseColor, n as prefersReducedMotion, r as resolveOutputMode } from "./output-mode-
|
|
3
|
-
import { a as readSavedTheme, c as saveTheme, i as isThemeSetting, n as THEME_SETTINGS, s as resolveThemeSetting } from "./theme-
|
|
4
|
-
import { n as
|
|
5
|
-
import {
|
|
6
|
-
import { r as
|
|
7
|
-
import { n as
|
|
8
|
-
import {
|
|
9
|
-
import { t as Tunnel } from "./tunnel-
|
|
10
|
-
import { n as classifyAppLine, t as LogBuffer } from "./log-buffer-
|
|
11
|
-
import {
|
|
1
|
+
import { a as renderCrashReport, n as ExitCode, t as CliError } from "./errors-DETRFkoF.js";
|
|
2
|
+
import { i as shouldUseColor, n as prefersReducedMotion, r as resolveOutputMode } from "./output-mode-Bp7Da8vJ.js";
|
|
3
|
+
import { a as readSavedTheme, c as saveTheme, i as isThemeSetting, n as THEME_SETTINGS, s as resolveThemeSetting } from "./theme-3Fc_LI-2.js";
|
|
4
|
+
import { i as createLineSplitter, n as resolveTscBinary, r as ProcessSupervisor } from "./tsc-DeEv6Ce0.js";
|
|
5
|
+
import { r as resolveBinary } from "./project-jVFFrLl9.js";
|
|
6
|
+
import { n as assertSupportedExperiments, r as createBuilder, t as Locales } from "./locales-CODosUiP.js";
|
|
7
|
+
import { n as resolveCwd, t as projectArgs } from "./args-Du59CLXl.js";
|
|
8
|
+
import { t as prepareProject } from "./_shared-Cxp93Wni.js";
|
|
9
|
+
import { t as Tunnel } from "./tunnel-BHHUb9Tq.js";
|
|
10
|
+
import { n as classifyAppLine, t as LogBuffer } from "./log-buffer-CY82aqnb.js";
|
|
11
|
+
import { defineCommand } from "citty";
|
|
12
12
|
import { createWriteStream, mkdirSync } from "node:fs";
|
|
13
13
|
import { dirname } from "node:path";
|
|
14
|
+
import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
|
|
14
15
|
import { EventEmitter } from "node:events";
|
|
15
16
|
import { spawn } from "node:child_process";
|
|
16
17
|
import { lookup } from "node:dns/promises";
|
|
17
18
|
|
|
18
|
-
//#region src/
|
|
19
|
+
//#region src/dev/typechecker.ts
|
|
19
20
|
const WATCH_START = /Starting (incremental )?compilation/;
|
|
20
21
|
const WATCH_DONE = /Found (\d+) errors?\. Watching for file changes/;
|
|
21
22
|
const ONE_SHOT_DONE = /Found (\d+) errors?/;
|
|
@@ -216,7 +217,7 @@ function missing(config, name, install) {
|
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
//#endregion
|
|
219
|
-
//#region src/
|
|
220
|
+
//#region src/dev/dev-service.ts
|
|
220
221
|
/**
|
|
221
222
|
* The headless heart of `stars dev`: builds, (re)starts the bot and exposes state and logs.
|
|
222
223
|
* Renderers (plain or TUI) only subscribe to it, they never own behaviour.
|
|
@@ -523,7 +524,7 @@ function describeReason(reason) {
|
|
|
523
524
|
}
|
|
524
525
|
|
|
525
526
|
//#endregion
|
|
526
|
-
//#region src/
|
|
527
|
+
//#region src/dev/host.ts
|
|
527
528
|
/**
|
|
528
529
|
* Resolves `localhost` the way Vite's dev server does: Node's default DNS result order (`dns.lookup('localhost')`)
|
|
529
530
|
* can disagree with the OS's own, "verbatim" resolution order — a well known source of a dev URL that prints fine
|
|
@@ -552,7 +553,7 @@ async function withResolvedLocalhost(url) {
|
|
|
552
553
|
}
|
|
553
554
|
|
|
554
555
|
//#endregion
|
|
555
|
-
//#region src/
|
|
556
|
+
//#region src/dev/log-file.ts
|
|
556
557
|
/**
|
|
557
558
|
* Mirrors a dev session's logs into a file, so a run can be read back after the terminal UI is gone (the TUI takes
|
|
558
559
|
* over the alternate screen and its scrollback disappears on exit). Seedcord keeps a `logs/` directory for the same
|
|
@@ -590,7 +591,7 @@ function format(entry) {
|
|
|
590
591
|
}
|
|
591
592
|
|
|
592
593
|
//#endregion
|
|
593
|
-
//#region src/
|
|
594
|
+
//#region src/commands/dev.ts
|
|
594
595
|
async function runDev(options) {
|
|
595
596
|
if (options.theme !== void 0 && !isThemeSetting(options.theme)) throw new CliError(`Unknown theme \`${options.theme}\`.`, {
|
|
596
597
|
code: "INVALID_THEME",
|
|
@@ -615,14 +616,14 @@ async function runDev(options) {
|
|
|
615
616
|
const service = new DevService(config, { builder: await createBuilder(config) });
|
|
616
617
|
const logFile = config.dev.logFile ? new LogFileWriter(config.dev.logFile, service.logs) : null;
|
|
617
618
|
logFile?.open();
|
|
618
|
-
const renderer = mode === "tui" ? (await import("./tui-
|
|
619
|
+
const renderer = mode === "tui" ? (await import("./tui-BRddrLQP.js")).createTuiRenderer(service, {
|
|
619
620
|
color,
|
|
620
621
|
theme,
|
|
621
622
|
reducedMotion: prefersReducedMotion(),
|
|
622
623
|
onThemeSave: (setting) => {
|
|
623
624
|
if (!saveTheme(setting)) service.log("stars", "warn", "Could not save the theme preference.");
|
|
624
625
|
}
|
|
625
|
-
}) : (await import("./plain-
|
|
626
|
+
}) : (await import("./plain-B6z85uQP.js")).createPlainRenderer(service, { color });
|
|
626
627
|
let exiting = null;
|
|
627
628
|
const shutdown = (code) => {
|
|
628
629
|
exiting ??= (async () => {
|
|
@@ -653,7 +654,7 @@ async function runDev(options) {
|
|
|
653
654
|
await prepareProject(config);
|
|
654
655
|
await service.start();
|
|
655
656
|
} catch (error) {
|
|
656
|
-
service.log("stars", "error", error instanceof Error ? error
|
|
657
|
+
service.log("stars", "error", error instanceof Error ? await renderCrashReport(error, config.root) : String(error));
|
|
657
658
|
await shutdown(ExitCode.Error);
|
|
658
659
|
}
|
|
659
660
|
await finished;
|
|
@@ -674,7 +675,33 @@ async function resolveDevConfig(config) {
|
|
|
674
675
|
}
|
|
675
676
|
};
|
|
676
677
|
}
|
|
678
|
+
var dev_default = defineCommand({
|
|
679
|
+
meta: {
|
|
680
|
+
name: "dev",
|
|
681
|
+
description: "Build, run and restart the bot on changes"
|
|
682
|
+
},
|
|
683
|
+
args: {
|
|
684
|
+
...projectArgs,
|
|
685
|
+
tui: {
|
|
686
|
+
type: "boolean",
|
|
687
|
+
description: "Interactive terminal UI; use --no-tui (or STARS_TUI=plain) for plain line output",
|
|
688
|
+
default: true
|
|
689
|
+
},
|
|
690
|
+
theme: {
|
|
691
|
+
type: "string",
|
|
692
|
+
description: `Colour theme of the interactive UI: ${THEME_SETTINGS.join(", ")} (or STARS_THEME; press T in the UI to pick one)`
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
async run({ args }) {
|
|
696
|
+
await runDev({
|
|
697
|
+
config: args.config,
|
|
698
|
+
cwd: args.cwd,
|
|
699
|
+
tui: args.tui ? void 0 : false,
|
|
700
|
+
theme: args.theme
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
});
|
|
677
704
|
|
|
678
705
|
//#endregion
|
|
679
|
-
export {
|
|
680
|
-
//# sourceMappingURL=dev-
|
|
706
|
+
export { dev_default as default };
|
|
707
|
+
//# sourceMappingURL=dev-Q-FSs-mH.js.map
|