@wolfstar/cli 0.7.0 → 1.0.0-next-20260919162943

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.
Files changed (52) hide show
  1. package/README.md +5 -5
  2. package/dist/{_shared-Cxp93Wni.js → _shared-dVR2pKjb.js} +14 -1
  3. package/dist/_shared-dVR2pKjb.js.map +1 -0
  4. package/dist/{build-B7QQzVk8.js → build-BUhQQ1E5.js} +5 -9
  5. package/dist/build-BUhQQ1E5.js.map +1 -0
  6. package/dist/cli.js +1 -1
  7. package/dist/{codegen-Ba2qI4ji.js → codegen-hmnFzRjK.js} +12 -11
  8. package/dist/codegen-hmnFzRjK.js.map +1 -0
  9. package/dist/{commands-DOkMjyT7.js → commands-BApoAbpQ.js} +13 -25
  10. package/dist/commands-BApoAbpQ.js.map +1 -0
  11. package/dist/{dev-Q-FSs-mH.js → dev-B0RlN46N.js} +14 -13
  12. package/dist/dev-B0RlN46N.js.map +1 -0
  13. package/dist/diagnostics-C98hnJB5.js +59 -0
  14. package/dist/diagnostics-C98hnJB5.js.map +1 -0
  15. package/dist/errors-D1UU8atd.js +56 -0
  16. package/dist/errors-D1UU8atd.js.map +1 -0
  17. package/dist/index.d.ts +94 -22
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +5 -4
  20. package/dist/{info-Dt6WW6Px.js → info-DN4vUx1S.js} +4 -3
  21. package/dist/info-DN4vUx1S.js.map +1 -0
  22. package/dist/{locales-CODosUiP.js → locales-khJEemUn.js} +9 -19
  23. package/dist/locales-khJEemUn.js.map +1 -0
  24. package/dist/nitro-Cki2gTpt.js +145 -0
  25. package/dist/nitro-Cki2gTpt.js.map +1 -0
  26. package/dist/{prepare-Dv_8yIbG.js → prepare-wGp-cAa9.js} +4 -7
  27. package/dist/prepare-wGp-cAa9.js.map +1 -0
  28. package/dist/{project-jVFFrLl9.js → project-DT3wg_lf.js} +5 -4
  29. package/dist/project-DT3wg_lf.js.map +1 -0
  30. package/dist/{run-DjjDIYTy.js → run-D_j2tqWF.js} +8 -8
  31. package/dist/{run-DjjDIYTy.js.map → run-D_j2tqWF.js.map} +1 -1
  32. package/dist/{tsc-DeEv6Ce0.js → tsc-Bex5dwzD.js} +6 -5
  33. package/dist/tsc-Bex5dwzD.js.map +1 -0
  34. package/dist/tsc-dzhKrr7T.js +3 -0
  35. package/dist/{tsdown-C9q3H3MK.js → tsdown-scDokwb0.js} +2 -2
  36. package/dist/{tsdown-C9q3H3MK.js.map → tsdown-scDokwb0.js.map} +1 -1
  37. package/dist/{vite-BVXBSWQb.js → vite-C-szLSGb.js} +2 -2
  38. package/dist/{vite-BVXBSWQb.js.map → vite-C-szLSGb.js.map} +1 -1
  39. package/package.json +8 -2
  40. package/dist/_shared-Cxp93Wni.js.map +0 -1
  41. package/dist/build-B7QQzVk8.js.map +0 -1
  42. package/dist/codegen-Ba2qI4ji.js.map +0 -1
  43. package/dist/commands-DOkMjyT7.js.map +0 -1
  44. package/dist/dev-Q-FSs-mH.js.map +0 -1
  45. package/dist/errors-DETRFkoF.js +0 -62
  46. package/dist/errors-DETRFkoF.js.map +0 -1
  47. package/dist/info-Dt6WW6Px.js.map +0 -1
  48. package/dist/locales-CODosUiP.js.map +0 -1
  49. package/dist/prepare-Dv_8yIbG.js.map +0 -1
  50. package/dist/project-jVFFrLl9.js.map +0 -1
  51. package/dist/tsc-DQq_UrBf.js +0 -3
  52. package/dist/tsc-DeEv6Ce0.js.map +0 -1
@@ -0,0 +1,56 @@
1
+ import { i as shouldUseColor } from "./output-mode-Bp7Da8vJ.js";
2
+ import { configDiagnostics } from "@wolfstar/http-framework/config";
3
+ import { createColors } from "colorette";
4
+ import { Diagnostic } from "nostics";
5
+ import { ansiFormatter } from "nostics/formatters/ansi";
6
+
7
+ //#region src/utils/errors.ts
8
+ const ExitCode = {
9
+ Ok: 0,
10
+ Error: 1,
11
+ InvalidConfig: 2,
12
+ BuildFailed: 3,
13
+ Interrupted: 130,
14
+ Terminated: 143
15
+ };
16
+ /** Every `stars.config.*` diagnostic code maps to {@link ExitCode.InvalidConfig}; everything else defaults to `Error`. */
17
+ const CONFIG_DIAGNOSTIC_CODES = new Set(Object.keys(configDiagnostics));
18
+ /** CLI-local diagnostic codes whose exit code isn't the default {@link ExitCode.Error}. */
19
+ const CLI_EXIT_CODES = { BUILD_FAILED: ExitCode.BuildFailed };
20
+ /**
21
+ * Formats an error for the terminal: a `Diagnostic` (from `stars.config.*` validation, via
22
+ * `@wolfstar/http-framework/config`'s `configDiagnostics`, or from the CLI's own `cliDiagnostics`) renders through
23
+ * nostics' own ANSI formatter — message, `fix`, `sources` and `docs` — everything else falls back to a crash report.
24
+ */
25
+ async function formatError(error) {
26
+ if (error instanceof Diagnostic) {
27
+ const colors = createColors({ useColor: shouldUseColor() });
28
+ return ansiFormatter(colors)(error);
29
+ }
30
+ if (error instanceof Error && error.name === "CLIError") return error.message;
31
+ if (error instanceof Error) return renderCrashReport(error);
32
+ return String(error);
33
+ }
34
+ /**
35
+ * Renders an unexpected error (a bug, not something the CLI already explains through a `Diagnostic`) as a
36
+ * sourcemapped, syntax-highlighted report — frames and a snippet of the original source instead of a stack trace
37
+ * pointing into the bundled `dist/cli.js`.
38
+ */
39
+ async function renderCrashReport(error, cwd = process.cwd()) {
40
+ const { createReport, fsLoader, renderAnsi } = await import("my-bad");
41
+ return renderAnsi(await createReport(error, {
42
+ cwd,
43
+ loaders: [fsLoader()]
44
+ }), { cwd });
45
+ }
46
+ function exitCodeOf(error) {
47
+ if (error instanceof Diagnostic) {
48
+ if (CONFIG_DIAGNOSTIC_CODES.has(error.code)) return ExitCode.InvalidConfig;
49
+ return CLI_EXIT_CODES[error.code] ?? ExitCode.Error;
50
+ }
51
+ return ExitCode.Error;
52
+ }
53
+
54
+ //#endregion
55
+ export { renderCrashReport as i, exitCodeOf as n, formatError as r, ExitCode as t };
56
+ //# sourceMappingURL=errors-D1UU8atd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-D1UU8atd.js","names":[],"sources":["../src/utils/errors.ts"],"sourcesContent":["import { configDiagnostics } from '@wolfstar/http-framework/config';\nimport { createColors } from 'colorette';\nimport { Diagnostic } from 'nostics';\nimport { ansiFormatter } from 'nostics/formatters/ansi';\nimport { shouldUseColor } from './output-mode.js';\n\nexport const ExitCode = {\n\tOk: 0,\n\tError: 1,\n\tInvalidConfig: 2,\n\tBuildFailed: 3,\n\tInterrupted: 130,\n\tTerminated: 143\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\n/** Every `stars.config.*` diagnostic code maps to {@link ExitCode.InvalidConfig}; everything else defaults to `Error`. */\nconst CONFIG_DIAGNOSTIC_CODES = new Set<string>(Object.keys(configDiagnostics));\n\n/** CLI-local diagnostic codes whose exit code isn't the default {@link ExitCode.Error}. */\nconst CLI_EXIT_CODES: Partial<Record<string, ExitCode>> = {\n\tBUILD_FAILED: ExitCode.BuildFailed\n};\n\n/**\n * Formats an error for the terminal: a `Diagnostic` (from `stars.config.*` validation, via\n * `@wolfstar/http-framework/config`'s `configDiagnostics`, or from the CLI's own `cliDiagnostics`) renders through\n * nostics' own ANSI formatter — message, `fix`, `sources` and `docs` — everything else falls back to a crash report.\n */\nexport async function formatError(error: unknown): Promise<string> {\n\tif (error instanceof Diagnostic) {\n\t\tconst colors = createColors({ useColor: shouldUseColor() });\n\t\treturn ansiFormatter(colors)(error);\n\t}\n\n\t// citty's CLIError (unknown command, missing argument): the message is enough.\n\tif (error instanceof Error && error.name === 'CLIError') return error.message;\n\tif (error instanceof Error) return renderCrashReport(error);\n\treturn String(error);\n}\n\n/**\n * Renders an unexpected error (a bug, not something the CLI already explains through a `Diagnostic`) as a\n * sourcemapped, syntax-highlighted report — frames and a snippet of the original source instead of a stack trace\n * pointing into the bundled `dist/cli.js`.\n */\nexport async function renderCrashReport(error: unknown, cwd: string = process.cwd()): Promise<string> {\n\tconst { createReport, fsLoader, renderAnsi } = await import('my-bad');\n\tconst report = await createReport(error, { cwd, loaders: [fsLoader()] });\n\treturn renderAnsi(report, { cwd });\n}\n\nexport function exitCodeOf(error: unknown): ExitCode {\n\tif (error instanceof Diagnostic) {\n\t\tif (CONFIG_DIAGNOSTIC_CODES.has(error.code)) return ExitCode.InvalidConfig;\n\t\treturn CLI_EXIT_CODES[error.code] ?? ExitCode.Error;\n\t}\n\n\treturn ExitCode.Error;\n}\n"],"mappings":";;;;;;;AAMA,MAAa,WAAW;CACvB,IAAI;CACJ,OAAO;CACP,eAAe;CACf,aAAa;CACb,aAAa;CACb,YAAY;AACb;;AAKA,MAAM,0BAA0B,IAAI,IAAY,OAAO,KAAK,iBAAiB,CAAC;;AAG9E,MAAM,iBAAoD,EACzD,cAAc,SAAS,YACxB;;;;;;AAOA,eAAsB,YAAY,OAAiC;CAClE,IAAI,iBAAiB,YAAY;EAChC,MAAM,SAAS,aAAa,EAAE,UAAU,eAAe,EAAE,CAAC;EAC1D,OAAO,cAAc,MAAM,CAAC,CAAC,KAAK;CACnC;CAGA,IAAI,iBAAiB,SAAS,MAAM,SAAS,YAAY,OAAO,MAAM;CACtE,IAAI,iBAAiB,OAAO,OAAO,kBAAkB,KAAK;CAC1D,OAAO,OAAO,KAAK;AACpB;;;;;;AAOA,eAAsB,kBAAkB,OAAgB,MAAc,QAAQ,IAAI,GAAoB;CACrG,MAAM,EAAE,cAAc,UAAU,eAAe,MAAM,OAAO;CAE5D,OAAO,WAAW,MADG,aAAa,OAAO;EAAE;EAAK,SAAS,CAAC,SAAS,CAAC;CAAE,CAAC,GAC7C,EAAE,IAAI,CAAC;AAClC;AAEA,SAAgB,WAAW,OAA0B;CACpD,IAAI,iBAAiB,YAAY;EAChC,IAAI,wBAAwB,IAAI,MAAM,IAAI,GAAG,OAAO,SAAS;EAC7D,OAAO,eAAe,MAAM,SAAS,SAAS;CAC/C;CAEA,OAAO,SAAS;AACjB"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ConfigError, ConfigErrorOptions, ResolvedStarsConfig, loadStarsConfig } from "@wolfstar/http-framework/config";
1
+ import { ConfigDiagnosticCode, ResolvedStarsConfig, configDiagnostics, loadStarsConfig } from "@wolfstar/http-framework/config";
2
2
  //#region src/run.d.ts
3
3
  export declare function runMain(argv?: string[]): Promise<void>;
4
4
  //#endregion
@@ -12,31 +12,103 @@ export declare const ExitCode: {
12
12
  readonly Terminated: 143;
13
13
  };
14
14
  export type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];
15
- interface CliErrorOptions {
16
- /** A stable, machine readable code. */
17
- code: string;
18
- /** A short, actionable suggestion. */
19
- hint?: string;
20
- exitCode?: ExitCode;
21
- cause?: unknown;
22
- }
23
15
  /**
24
- * An error the CLI reports to the user without a stack trace.
16
+ * Formats an error for the terminal: a `Diagnostic` (from `stars.config.*` validation, via
17
+ * `@wolfstar/http-framework/config`'s `configDiagnostics`, or from the CLI's own `cliDiagnostics`) renders through
18
+ * nostics' own ANSI formatter — message, `fix`, `sources` and `docs` — everything else falls back to a crash report.
25
19
  */
26
- export declare class CliError extends Error {
27
- readonly code: string;
28
- readonly hint: string | null;
29
- readonly exitCode: ExitCode;
30
- constructor(message: string, options: CliErrorOptions);
31
- }
20
+ export declare function formatError(error: unknown): Promise<string>;
21
+ export declare function exitCodeOf(error: unknown): ExitCode;
22
+ //#endregion
23
+ //#region src/utils/diagnostics.d.ts
32
24
  /**
33
- * Formats an error for the terminal: message, optional location and hint.
25
+ * Structured, stable diagnostic codes for everything `@wolfstar/cli` itself rejects (as opposed to `stars.config.*`
26
+ * validation, which is `@wolfstar/http-framework`'s own {@link import('@wolfstar/http-framework/config').configDiagnostics}).
27
+ *
28
+ * `reporters` stays empty: `runMain` (`src/run.ts`) is the single place that renders a caught `Diagnostic` to the
29
+ * terminal (`formatError`) and picks its exit code (`exitCodeOf`), so nothing here should print on its own — a
30
+ * command that calls e.g. `runBuild` directly (as the test suite does) gets a plain thrown value instead of stray
31
+ * console output.
34
32
  *
35
- * `ConfigError` comes from `@wolfstar/http-framework/config`: the framework validates `stars.config.*` and throws a
36
- * plain data error, the CLI decides how it looks on a terminal and which exit code it gets ({@link exitCodeOf}).
33
+ * `why` and `fix` are always given the same, fully-typed params object, even when one of them ignores part of it or
34
+ * neither takes any: a bare `() => value` next to a typed sibling loses nostics' param-type inference (a zero-arg
35
+ * function widens to `unknown` params, erasing the sibling's fields from the merged type).
37
36
  */
38
- export declare function formatError(error: unknown): Promise<string>;
39
- export declare function exitCodeOf(error: unknown): ExitCode;
37
+ export declare const cliDiagnostics: import("nostics").Diagnostics<{
38
+ readonly PREPARE_OUTDATED: {
39
+ why: (_p: {}) => string;
40
+ };
41
+ readonly DISCORD_TOKEN_MISSING: {
42
+ why: (_p: {}) => string;
43
+ fix: (_p: {}) => string;
44
+ };
45
+ readonly DISCORD_APPLICATION_ID_MISSING: {
46
+ why: (_p: {}) => string;
47
+ fix: (_p: {}) => string;
48
+ };
49
+ readonly DISCORD_REQUEST_FAILED: {
50
+ why: (p: {
51
+ status: number;
52
+ detail: string;
53
+ }) => string;
54
+ fix: (p: {
55
+ status: number;
56
+ detail: string;
57
+ }) => "Check DISCORD_TOKEN." | "Check the application id and the bot permissions.";
58
+ };
59
+ readonly BUILD_FAILED: {
60
+ why: (p: {
61
+ message: string;
62
+ }) => string;
63
+ };
64
+ readonly COMMAND_NOT_FOUND: {
65
+ why: (p: {
66
+ names: string;
67
+ }) => string;
68
+ fix: (_p: {
69
+ names: string;
70
+ }) => string;
71
+ };
72
+ readonly ABORTED: {
73
+ why: (_p: {}) => string;
74
+ };
75
+ readonly CONFIRMATION_REQUIRED: {
76
+ why: (_p: {}) => string;
77
+ fix: (_p: {}) => string;
78
+ };
79
+ readonly INVALID_THEME: {
80
+ why: (p: {
81
+ theme: string;
82
+ themes: string;
83
+ }) => string;
84
+ fix: (p: {
85
+ theme: string;
86
+ themes: string;
87
+ }) => string;
88
+ };
89
+ readonly CODEGEN_OUTDATED: {
90
+ why: (_p: {}) => string;
91
+ };
92
+ readonly DEPENDENCY_MISSING: {
93
+ why: (p: {
94
+ name: string;
95
+ root: string;
96
+ hint: string;
97
+ }) => string;
98
+ fix: (p: {
99
+ name: string;
100
+ root: string;
101
+ hint: string;
102
+ }) => string;
103
+ };
104
+ readonly CODEGEN_FAILED: {
105
+ why: (p: {
106
+ code: number | null;
107
+ stderr: string;
108
+ }) => string;
109
+ };
110
+ }, readonly []>;
111
+ type CliDiagnosticCode = keyof typeof cliDiagnostics;
40
112
  //#endregion
41
113
  //#region src/utils/output-mode.d.ts
42
114
  type OutputMode = 'tui' | 'plain';
@@ -110,5 +182,5 @@ interface ThemeSettingSources {
110
182
  */
111
183
  export declare function resolveThemeSetting({ flag, env, saved }: ThemeSettingSources): ThemeSetting;
112
184
  //#endregion
113
- export { type CliErrorOptions, ConfigError, type ConfigErrorOptions, type OutputMode, type ResolveOutputModeOptions, type ResolvedStarsConfig, type Theme, type ThemeName, type ThemeSetting, type ThemeToken, loadStarsConfig };
185
+ export { type CliDiagnosticCode, type ConfigDiagnosticCode, type OutputMode, type ResolveOutputModeOptions, type ResolvedStarsConfig, type Theme, type ThemeName, type ThemeSetting, type ThemeToken, configDiagnostics, loadStarsConfig };
114
186
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/run.ts","../src/utils/errors.ts","../src/utils/output-mode.ts","../src/utils/theme.ts"],"mappings":";;wBA8BsB,QAAQ,kBAAyC;;;qBC5B1D;WACZ;WACA;WACA;WACA;WACA;WACA;;YAGW,mBAAmB,uBAAuB;UAErC;;EAEhB;;EAEA;EACA,WAAW;EACX;;;;;qBAMY,iBAAiB;WACb;WACA;WACA,UAAU;EAE1B,YAAmB,iBAAiB,SAAS;;;;;;;;wBAexB,YAAY,iBAAiB;wBA2BnC,WAAW,iBAAiB;;;KCxEhC;UAEK;;EAEhB;EACA,MAAM,OAAO;;EAEb;;EAEA;EACA;EACA;;EAEA;;;;;;;wBAUe,kBAAkB,UAAS,2BAAgC;wBAkB3D,gBAAgB,MAAK,OAAO;;;;wBAU5B,eAAe,MAAK,OAAO,YAA0B;;;;wBASrD,qBAAqB,MAAK,OAAO;;;;qBCvDpC;KACD,uBAAuB;KACvB,YAAY,QAAQ;;;;;UAMf;;EAEhB;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;;EAEA;;EAEA;;KAGW,mBAAmB;qBAElB,QAAQ,SAAS,OAAO,WAAW;wBA4FhC,aAAa,SAAS,cAAc,MAAK,OAAO,aAA2B;UAI1E;;EAEhB;EACA,MAAM,OAAO;;EAEb,QAAQ;;;;;;wBAOO,sBAAsB,MAAM,KAAmB,SAAS,sBAAsB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/run.ts","../src/utils/errors.ts","../src/utils/diagnostics.ts","../src/utils/output-mode.ts","../src/utils/theme.ts"],"mappings":";;wBA8BsB,QAAQ,kBAAyC;;;qBCxB1D;WACZ;WACA;WACA;WACA;WACA;WACA;;YAGW,mBAAmB,uBAAuB;;;;;;wBAehC,YAAY,iBAAiB;wBAuBnC,WAAW,iBAAiB;;;;;;;;;;;;;;;;qBCtC/B,kCAAc;;IAKxB,MAAG;;;IAGH,MAAG;IACH,MAAG;;;IAGH,MAAG;IACH,MAAG;;;IAGH,MAAG;MAAQ;MAAgB;;IAC3B,MAAG;MAAQ;MAAgB;;;;IAI3B,MAAG;MAAQ;;;;IAGX,MAAG;MAAQ;;IACX,MAAG;MAAS;;;;IAGZ,MAAG;;;IAGH,MAAG;IACH,MAAG;;;IAGH,MAAG;MAAQ;MAAe;;IAC1B,MAAG;MAAQ;MAAe;;;;IAG1B,MAAG;;;IAGH,MAAG;MAAQ;MAAc;MAAc;;IACvC,MAAG;MAAQ;MAAc;MAAc;;;;IAGvC,MAAG;MAAQ;MAAqB;;;;KAKvB,iCAAiC;;;KClEjC;UAEK;;EAEhB;EACA,MAAM,OAAO;;EAEb;;EAEA;EACA;EACA;;EAEA;;;;;;;wBAUe,kBAAkB,UAAS,2BAAgC;wBAkB3D,gBAAgB,MAAK,OAAO;;;;wBAU5B,eAAe,MAAK,OAAO,YAA0B;;;;wBASrD,qBAAqB,MAAK,OAAO;;;;qBCvDpC;KACD,uBAAuB;KACvB,YAAY,QAAQ;;;;;UAMf;;EAEhB;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;;EAEA;;EAEA;;KAGW,mBAAmB;qBAElB,QAAQ,SAAS,OAAO,WAAW;wBA4FhC,aAAa,SAAS,cAAc,MAAK,OAAO,aAA2B;UAI1E;;EAEhB;EACA,MAAM,OAAO;;EAEb,QAAQ;;;;;;wBAOO,sBAAsB,MAAM,KAAmB,SAAS,sBAAsB"}
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
- import { t as runMain } from "./run-DjjDIYTy.js";
2
- import { i as formatError, n as ExitCode, r as exitCodeOf, t as CliError } from "./errors-DETRFkoF.js";
1
+ import { t as runMain } from "./run-D_j2tqWF.js";
3
2
  import { i as shouldUseColor, n as prefersReducedMotion, r as resolveOutputMode, t as isCIEnvironment } from "./output-mode-Bp7Da8vJ.js";
3
+ import { n as exitCodeOf, r as formatError, t as ExitCode } from "./errors-D1UU8atd.js";
4
+ import { t as cliDiagnostics } from "./diagnostics-C98hnJB5.js";
4
5
  import { n as THEME_SETTINGS, o as resolveTheme, s as resolveThemeSetting, t as THEMES } from "./theme-3Fc_LI-2.js";
5
- import { ConfigError, loadStarsConfig } from "@wolfstar/http-framework/config";
6
+ import { configDiagnostics, loadStarsConfig } from "@wolfstar/http-framework/config";
6
7
 
7
- export { CliError, ConfigError, ExitCode, THEMES, THEME_SETTINGS, exitCodeOf, formatError, isCIEnvironment, loadStarsConfig, prefersReducedMotion, resolveOutputMode, resolveTheme, resolveThemeSetting, runMain, shouldUseColor };
8
+ export { ExitCode, THEMES, THEME_SETTINGS, cliDiagnostics, configDiagnostics, exitCodeOf, formatError, isCIEnvironment, loadStarsConfig, prefersReducedMotion, resolveOutputMode, resolveTheme, resolveThemeSetting, runMain, shouldUseColor };
@@ -1,12 +1,12 @@
1
1
  import { t as readOwnPackageJson } from "./version-BzclCE19.js";
2
2
  import { i as shouldUseColor, r as resolveOutputMode } from "./output-mode-Bp7Da8vJ.js";
3
- import { t as findInstalledVersion } from "./project-jVFFrLl9.js";
3
+ import { t as findInstalledVersion } from "./project-DT3wg_lf.js";
4
4
  import { n as resolveCwd, t as projectArgs } from "./args-Du59CLXl.js";
5
5
  import { defineCommand } from "citty";
6
6
  import { relative } from "node:path";
7
7
  import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
8
- import { arch, platform } from "node:os";
9
8
  import { createColors } from "colorette";
9
+ import { arch, platform } from "node:os";
10
10
 
11
11
  //#region src/commands/info.ts
12
12
  function collectInfo(config) {
@@ -81,6 +81,7 @@ function formatInfo(info, useColor) {
81
81
  section("Experimental", [
82
82
  row("vite", flag(info.experimental.enableVite, colors)),
83
83
  row("nitro", flag(info.experimental.enableNitro, colors)),
84
+ ...info.experimental.enableNitro ? [row("nitro preset", info.experimental.nitro.preset)] : [],
84
85
  row("external", flag(info.experimental.enableExternalVite, colors))
85
86
  ]),
86
87
  section("Imports", [
@@ -137,4 +138,4 @@ var info_default = defineCommand({
137
138
 
138
139
  //#endregion
139
140
  export { info_default as default };
140
- //# sourceMappingURL=info-Dt6WW6Px.js.map
141
+ //# sourceMappingURL=info-DN4vUx1S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info-DN4vUx1S.js","names":[],"sources":["../src/commands/info.ts"],"sourcesContent":["import { displayPath, loadStarsConfig, type ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport { arch, platform } from 'node:os';\nimport { relative } from 'node:path';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { resolveOutputMode, shouldUseColor } from '../utils/output-mode.js';\nimport { findInstalledVersion } from '../utils/project.js';\nimport { readOwnPackageJson } from '../utils/version.js';\n\nexport interface InfoOptions extends ProjectArgs {\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n}\n\nexport interface ProjectInfo {\n\tcli: { version: string; node: string; platform: string; outputMode: 'tui' | 'plain' };\n\tproject: {\n\t\tcwd: string;\n\t\troot: string;\n\t\tconfigFile: string | null;\n\t\tname: string | null;\n\t\tversion: string | null;\n\t\tentry: string;\n\t\tframeworkVersion: string | null;\n\t};\n\tbuild: ResolvedStarsConfig['build'];\n\tdev: ResolvedStarsConfig['dev'];\n\tcodegen: ResolvedStarsConfig['codegen'];\n\timports: ResolvedStarsConfig['imports'];\n\texperimental: ResolvedStarsConfig['experimental'];\n\tfuture: ResolvedStarsConfig['future'];\n\t/**\n\t * The option names set in the `tsdown`/`vite` blocks. Only the names: the values hold plugins and callbacks,\n\t * which neither serialize to JSON nor read usefully on a terminal.\n\t */\n\toptions: { tsdown: string[]; vite: string[] };\n}\n\nexport function collectInfo(config: ResolvedStarsConfig): ProjectInfo {\n\treturn {\n\t\tcli: {\n\t\t\tversion: readOwnPackageJson().version,\n\t\t\tnode: process.version,\n\t\t\tplatform: `${platform()} ${arch()}`,\n\t\t\toutputMode: resolveOutputMode()\n\t\t},\n\t\tproject: {\n\t\t\tcwd: config.cwd,\n\t\t\troot: config.root,\n\t\t\tconfigFile: config.configFile,\n\t\t\tname: config.packageJson?.name ?? null,\n\t\t\tversion: config.packageJson?.version ?? null,\n\t\t\tentry: config.entry,\n\t\t\tframeworkVersion: findInstalledVersion(config.root, '@wolfstar/http-framework')\n\t\t},\n\t\tbuild: config.build,\n\t\tdev: config.dev,\n\t\tcodegen: config.codegen,\n\t\timports: config.imports,\n\t\texperimental: config.experimental,\n\t\tfuture: config.future,\n\t\toptions: { tsdown: Object.keys(config.tsdown), vite: Object.keys(config.vite) }\n\t};\n}\n\nexport function formatInfo(info: ProjectInfo, useColor: boolean): string {\n\tconst colors = createColors({ useColor });\n\tconst { root } = info.project;\n\tconst show = (path: string | null) => (path === null ? colors.dim('none') : displayPath(root, path));\n\tconst row = (label: string, value: string) => ` ${colors.dim(label.padEnd(12))}${value}`;\n\tconst section = (title: string, rows: string[]) => [colors.bold(title), ...rows].join('\\n');\n\n\treturn [\n\t\tsection(`stars ${colors.green(`v${info.cli.version}`)}`, [\n\t\t\trow('node', info.cli.node),\n\t\t\trow('platform', info.cli.platform),\n\t\t\trow('output', info.cli.outputMode),\n\t\t\trow(\n\t\t\t\t'framework',\n\t\t\t\tinfo.project.frameworkVersion\n\t\t\t\t\t? `@wolfstar/http-framework v${info.project.frameworkVersion}`\n\t\t\t\t\t: colors.yellow('@wolfstar/http-framework not installed')\n\t\t\t)\n\t\t]),\n\t\tsection('Project', [\n\t\t\trow(\n\t\t\t\t'name',\n\t\t\t\tinfo.project.name\n\t\t\t\t\t? `${info.project.name}${info.project.version ? colors.dim(` v${info.project.version}`) : ''}`\n\t\t\t\t\t: colors.dim('unnamed')\n\t\t\t),\n\t\t\trow('root', root),\n\t\t\trow(\n\t\t\t\t'config',\n\t\t\t\tinfo.project.configFile ? relative(root, info.project.configFile) || info.project.configFile : colors.dim('none (defaults)')\n\t\t\t),\n\t\t\trow('entry', show(info.project.entry))\n\t\t]),\n\t\tsection('Build', [\n\t\t\trow('tool', info.build.tool),\n\t\t\t// Which file the build tool is configured from: its own, or this project's `stars.config`.\n\t\t\trow('config', info.build.configFile ? show(info.build.configFile) : colors.dim('stars.config')),\n\t\t\trow('options', describeOptions(info, colors)),\n\t\t\trow('outDir', show(info.build.outDir)),\n\t\t\trow('tsconfig', show(info.build.tsconfig)),\n\t\t\trow('runs', show(info.build.output))\n\t\t]),\n\t\tsection('Dev', [\n\t\t\trow('watch', info.dev.watch.map(show).join(', ')),\n\t\t\trow('debounce', `${info.dev.debounce}ms`),\n\t\t\trow('node args', info.dev.nodeArgs.join(' ') || colors.dim('none')),\n\t\t\trow('args', info.dev.args.join(' ') || colors.dim('none')),\n\t\t\trow('url', info.dev.url ?? colors.dim('unknown, set dev.url or HTTP_PORT')),\n\t\t\trow('health', info.dev.health ?? colors.dim('none')),\n\t\t\trow(\n\t\t\t\t'typecheck',\n\t\t\t\tinfo.dev.typecheck.enabled ? `${info.dev.typecheck.checker} → ${show(info.dev.typecheck.tsconfig)}` : colors.dim('disabled')\n\t\t\t),\n\t\t\trow('tunnel', describeTunnel(info.dev.tunnel, colors)),\n\t\t\trow('log file', info.dev.logFile ? show(info.dev.logFile) : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Codegen', [\n\t\t\trow('i18n', info.codegen.i18n ? `${show(info.codegen.i18n.locales)} → ${show(info.codegen.i18n.output)}` : colors.dim('disabled'))\n\t\t]),\n\t\tsection('Future', [row('compat', `v${info.future.compatibilityVersion} defaults`)]),\n\t\tsection('Experimental', [\n\t\t\trow('vite', flag(info.experimental.enableVite, colors)),\n\t\t\trow('nitro', flag(info.experimental.enableNitro, colors)),\n\t\t\t...(info.experimental.enableNitro ? [row('nitro preset', info.experimental.nitro.preset)] : []),\n\t\t\trow('external', flag(info.experimental.enableExternalVite, colors))\n\t\t]),\n\t\tsection('Imports', [\n\t\t\trow('auto', info.imports.enabled ? colors.green('enabled') : colors.dim('disabled')),\n\t\t\trow('dirs', info.imports.dirs.map(show).join(', ')),\n\t\t\trow('presets', info.imports.presets.join(', ') || colors.dim('none')),\n\t\t\trow('dts', show(info.imports.dts))\n\t\t])\n\t].join('\\n\\n');\n}\n\nfunction describeOptions(info: ProjectInfo, colors: ReturnType<typeof createColors>): string {\n\tconst names = info.build.tool === 'vite' ? info.options.vite : info.options.tsdown;\n\treturn names.length > 0 ? names.join(', ') : colors.dim('none');\n}\n\nfunction flag(enabled: boolean, colors: ReturnType<typeof createColors>): string {\n\treturn enabled ? colors.green('enabled') : colors.dim('disabled');\n}\n\nfunction describeTunnel(tunnel: ResolvedStarsConfig['dev']['tunnel'], colors: ReturnType<typeof createColors>): string {\n\tswitch (tunnel.mode) {\n\t\tcase 'quick':\n\t\t\treturn 'cloudflared quick tunnel';\n\t\tcase 'url':\n\t\t\treturn tunnel.url;\n\t\tdefault:\n\t\t\treturn colors.dim('disabled');\n\t}\n}\n\nexport async function runInfo(options: InfoOptions): Promise<void> {\n\tconst stdout = options.stdout ?? process.stdout;\n\tconst config = await loadStarsConfig({ cwd: resolveCwd(options), configFile: options.config });\n\tconst info = collectInfo(config);\n\tstdout.write(`${options.json ? JSON.stringify(info, null, 2) : formatInfo(info, shouldUseColor())}\\n`);\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'info',\n\t\tdescription: 'Print the resolved project configuration and environment'\n\t},\n\targs: {\n\t\t...projectArgs,\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 runInfo({ config: args.config, cwd: args.cwd, json: args.json });\n\t}\n});\n"],"mappings":"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"}
@@ -1,38 +1,28 @@
1
- import { t as CliError } from "./errors-DETRFkoF.js";
2
1
  import { cpSync, existsSync, mkdirSync, rmSync } from "node:fs";
3
2
  import { dirname, join, relative } from "node:path";
4
3
  import { EventEmitter } from "node:events";
5
4
 
6
5
  //#region src/builders/index.ts
7
- /**
8
- * Fails on experiments the CLI cannot honour yet, before a command gets far enough to look like it worked.
9
- *
10
- * Called by `stars dev`/`stars build` up front, since a project whose build tool needs no build at all would
11
- * otherwise return early and never reach {@link createBuilder}.
12
- */
13
- function assertSupportedExperiments(config) {
14
- if (config.experimental.enableNitro) throw new CliError("`experimental.enableNitro` is not implemented yet", {
15
- code: "EXPERIMENT_UNAVAILABLE",
16
- hint: "Nitro needs the framework's Fetch adapter (wolfstar-project/stars-components#81); until it lands, use `build.tool` 'tsdown', 'vite' or 'tsc'."
17
- });
18
- }
19
6
  async function createBuilder(config) {
20
- assertSupportedExperiments(config);
21
7
  if (config.experimental.enableExternalVite) {
22
8
  const { ExternalBuilder } = await import("./external-DVEYf7yD.js");
23
9
  return new ExternalBuilder(config);
24
10
  }
11
+ if (config.experimental.enableNitro) {
12
+ const { NitroBuilder } = await import("./nitro-Cki2gTpt.js");
13
+ return new NitroBuilder(config);
14
+ }
25
15
  switch (config.build.tool) {
26
16
  case "tsdown": {
27
- const { TsdownBuilder } = await import("./tsdown-C9q3H3MK.js");
17
+ const { TsdownBuilder } = await import("./tsdown-scDokwb0.js");
28
18
  return new TsdownBuilder(config);
29
19
  }
30
20
  case "vite": {
31
- const { ViteBuilder } = await import("./vite-BVXBSWQb.js");
21
+ const { ViteBuilder } = await import("./vite-C-szLSGb.js");
32
22
  return new ViteBuilder(config);
33
23
  }
34
24
  case "tsc": {
35
- const { TscBuilder } = await import("./tsc-DQq_UrBf.js");
25
+ const { TscBuilder } = await import("./tsc-dzhKrr7T.js");
36
26
  return new TscBuilder(config);
37
27
  }
38
28
  case "none": {
@@ -100,5 +90,5 @@ var Locales = class extends EventEmitter {
100
90
  };
101
91
 
102
92
  //#endregion
103
- export { assertSupportedExperiments as n, createBuilder as r, Locales as t };
104
- //# sourceMappingURL=locales-CODosUiP.js.map
93
+ export { createBuilder as n, Locales as t };
94
+ //# sourceMappingURL=locales-khJEemUn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locales-khJEemUn.js","names":[],"sources":["../src/builders/index.ts","../src/utils/locales.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport type { Builder } from './types.js';\n\nexport async function createBuilder(config: ResolvedStarsConfig): Promise<Builder> {\n\t// The project runs its own build, so the CLI only watches what it writes (see `ExternalBuilder`) — including when\n\t// it is driving `vite build` with its own `nitro()` plugin itself; `build.output` already points at Nitro's\n\t// `server/index.mjs` in that case (see `resolveBuild`).\n\tif (config.experimental.enableExternalVite) {\n\t\tconst { ExternalBuilder } = await import('./external.js');\n\t\treturn new ExternalBuilder(config);\n\t}\n\n\t// Nitro is itself a Vite plugin — there is no separate `nitro build` step — so it is handled before the\n\t// `build.tool` switch below, the same way `enableExternalVite` is.\n\tif (config.experimental.enableNitro) {\n\t\tconst { NitroBuilder } = await import('./nitro.js');\n\t\treturn new NitroBuilder(config);\n\t}\n\n\tswitch (config.build.tool) {\n\t\tcase 'tsdown': {\n\t\t\tconst { TsdownBuilder } = await import('./tsdown.js');\n\t\t\treturn new TsdownBuilder(config);\n\t\t}\n\t\tcase 'vite': {\n\t\t\tconst { ViteBuilder } = await import('./vite.js');\n\t\t\treturn new ViteBuilder(config);\n\t\t}\n\t\tcase 'tsc': {\n\t\t\tconst { TscBuilder } = await import('./tsc.js');\n\t\t\treturn new TscBuilder(config);\n\t\t}\n\t\tcase 'none': {\n\t\t\tconst { NoneBuilder } = await import('./none.js');\n\t\t\treturn new NoneBuilder(config);\n\t\t}\n\t}\n}\n\nexport type { Builder, BuilderEvents, BuildOutcome } from './types.js';\n","import { EventEmitter } from 'node:events';\nimport { cpSync, existsSync, mkdirSync, rmSync } from 'node:fs';\nimport { dirname, join, relative } from 'node:path';\nimport type { ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport type { LogLevel } from './log-buffer.js';\n\nexport interface LocalesEvents {\n\tchange: [];\n\tlog: [level: LogLevel, text: string];\n}\n\n/** Keeps the conventional `src/locales` data directory next to the compiled application. */\nexport class Locales extends EventEmitter<LocalesEvents> {\n\treadonly source: string;\n\treadonly destination: string;\n\t#watcher: { close(): Promise<void> } | null = null;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t\tthis.source = join(config.root, 'src', 'locales');\n\t\tthis.destination = join(config.build.outDir, 'locales');\n\t}\n\n\tpublic copy(): boolean {\n\t\tif (this.config.build.tool === 'none' || !existsSync(this.source)) return false;\n\t\tmkdirSync(this.destination, { recursive: true });\n\t\tcpSync(this.source, this.destination, { recursive: true, force: true });\n\t\treturn true;\n\t}\n\n\tpublic async watch(): Promise<void> {\n\t\tif (this.config.build.tool === 'none' || !existsSync(this.source) || this.#watcher) return;\n\t\tconst { watch } = await import('chokidar');\n\t\tconst watcher = watch(this.source, { ignoreInitial: true });\n\t\tthis.#watcher = watcher;\n\n\t\twatcher.on('all', (event, path) => {\n\t\t\ttry {\n\t\t\t\tconst target = join(this.destination, relative(this.source, path));\n\t\t\t\tif (event === 'unlink' || event === 'unlinkDir') rmSync(target, { recursive: event === 'unlinkDir', force: true });\n\t\t\t\telse if (existsSync(path)) {\n\t\t\t\t\tmkdirSync(dirname(target), { recursive: true });\n\t\t\t\t\tcpSync(path, target, { recursive: event === 'addDir', force: true });\n\t\t\t\t}\n\t\t\t\tthis.emit('change');\n\t\t\t} catch (error) {\n\t\t\t\tthis.emit('log', 'error', `Failed to copy locales: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t});\n\t\twatcher.on('error', (error) => this.emit('log', 'error', error instanceof Error ? error.message : String(error)));\n\t\tawait new Promise<void>((resolve) => watcher.once('ready', resolve));\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tconst watcher = this.#watcher;\n\t\tthis.#watcher = null;\n\t\tawait watcher?.close();\n\t}\n}\n"],"mappings":";;;;;AAGA,eAAsB,cAAc,QAA+C;CAIlF,IAAI,OAAO,aAAa,oBAAoB;EAC3C,MAAM,EAAE,oBAAoB,MAAM,OAAO;EACzC,OAAO,IAAI,gBAAgB,MAAM;CAClC;CAIA,IAAI,OAAO,aAAa,aAAa;EACpC,MAAM,EAAE,iBAAiB,MAAM,OAAO;EACtC,OAAO,IAAI,aAAa,MAAM;CAC/B;CAEA,QAAQ,OAAO,MAAM,MAArB;EACC,KAAK,UAAU;GACd,MAAM,EAAE,kBAAkB,MAAM,OAAO;GACvC,OAAO,IAAI,cAAc,MAAM;EAChC;EACA,KAAK,QAAQ;GACZ,MAAM,EAAE,gBAAgB,MAAM,OAAO;GACrC,OAAO,IAAI,YAAY,MAAM;EAC9B;EACA,KAAK,OAAO;GACX,MAAM,EAAE,eAAe,MAAM,OAAO;GACpC,OAAO,IAAI,WAAW,MAAM;EAC7B;EACA,KAAK,QAAQ;GACZ,MAAM,EAAE,gBAAgB,MAAM,OAAO;GACrC,OAAO,IAAI,YAAY,MAAM;EAC9B;CACD;AACD;;;;;ACzBA,IAAa,UAAb,cAA6B,aAA4B;CAKpB;CAJpC,AAAS;CACT,AAAS;CACT,WAA8C;CAE9C,AAAO,YAAY,AAAiB,QAA6B;EAChE,MAAM;EAD6B;EAEnC,KAAK,SAAS,KAAK,OAAO,MAAM,OAAO,SAAS;EAChD,KAAK,cAAc,KAAK,OAAO,MAAM,QAAQ,SAAS;CACvD;CAEA,AAAO,OAAgB;EACtB,IAAI,KAAK,OAAO,MAAM,SAAS,UAAU,CAAC,WAAW,KAAK,MAAM,GAAG,OAAO;EAC1E,UAAU,KAAK,aAAa,EAAE,WAAW,KAAK,CAAC;EAC/C,OAAO,KAAK,QAAQ,KAAK,aAAa;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACtE,OAAO;CACR;CAEA,MAAa,QAAuB;EACnC,IAAI,KAAK,OAAO,MAAM,SAAS,UAAU,CAAC,WAAW,KAAK,MAAM,KAAK,KAAK,UAAU;EACpF,MAAM,EAAE,UAAU,MAAM,OAAO;EAC/B,MAAM,UAAU,MAAM,KAAK,QAAQ,EAAE,eAAe,KAAK,CAAC;EAC1D,KAAK,WAAW;EAEhB,QAAQ,GAAG,QAAQ,OAAO,SAAS;GAClC,IAAI;IACH,MAAM,SAAS,KAAK,KAAK,aAAa,SAAS,KAAK,QAAQ,IAAI,CAAC;IACjE,IAAI,UAAU,YAAY,UAAU,aAAa,OAAO,QAAQ;KAAE,WAAW,UAAU;KAAa,OAAO;IAAK,CAAC;SAC5G,IAAI,WAAW,IAAI,GAAG;KAC1B,UAAU,QAAQ,MAAM,GAAG,EAAE,WAAW,KAAK,CAAC;KAC9C,OAAO,MAAM,QAAQ;MAAE,WAAW,UAAU;MAAU,OAAO;KAAK,CAAC;IACpE;IACA,KAAK,KAAK,QAAQ;GACnB,SAAS,OAAO;IACf,KAAK,KAAK,OAAO,SAAS,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;GAC9G;EACD,CAAC;EACD,QAAQ,GAAG,UAAU,UAAU,KAAK,KAAK,OAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;EAChH,MAAM,IAAI,SAAe,YAAY,QAAQ,KAAK,SAAS,OAAO,CAAC;CACpE;CAEA,MAAa,QAAuB;EACnC,MAAM,UAAU,KAAK;EACrB,KAAK,WAAW;EAChB,MAAM,SAAS,MAAM;CACtB;AACD"}
@@ -0,0 +1,145 @@
1
+ import { t as pluginRegistrations } from "./plugin-registrations-4PA_qWXF.js";
2
+ import { n as importFromProject } from "./project-DT3wg_lf.js";
3
+ import { EventEmitter } from "node:events";
4
+
5
+ //#region src/builders/nitro.ts
6
+ const VITE_INSTALL_HINT = "Install it with `pnpm add -D vite`, or turn off `experimental.enableNitro`.";
7
+ const NITRO_INSTALL_HINT = "Install it with `pnpm add -D nitro`, or turn off `experimental.enableNitro`.";
8
+ /**
9
+ * The virtual module registered as Nitro's `serverEntry` (see `nitro.build/docs/server-entry`): a `#`-prefixed id
10
+ * is never resolved against the filesystem (`resolveNitroPath` in Nitro itself special-cases it), so this never
11
+ * collides with a real project file.
12
+ */
13
+ const ENTRY_VIRTUAL_ID = "#stars/nitro-entry";
14
+ /**
15
+ * Builds the bot through [Nitro](https://nitro.build)'s Vite plugin (`nitro/vite`), the way `enableNitro` promises:
16
+ * `stars build` produces `build.outDir` (`.output` by default) laid out for the configured preset, deployable to
17
+ * anything Nitro targets, instead of a `node:http` process.
18
+ *
19
+ * Nitro v3 is itself a Vite plugin — there is no separate `nitro build` step — so this reuses the project's own
20
+ * `vite.config.*`/`stars.config#vite` the same way {@link import('./vite.js').ViteBuilder} does, and only adds the
21
+ * `nitro()` plugin and a generated server entry on top. That entry imports the project's `Client` instance (the
22
+ * entry's default export, already `load()`ed — see {@link import('@wolfstar/http-framework/config').StarsExperimentalConfig.enableNitro})
23
+ * and calls its `fetch(request)` method, in the plain `{ fetch(Request): Promise<Response> }` shape Nitro's own
24
+ * server entry convention expects — no separate adapter module to maintain, `Client` handles Fetch requests itself.
25
+ */
26
+ var NitroBuilder = class extends EventEmitter {
27
+ config;
28
+ tool = "vite";
29
+ #startedAt = 0;
30
+ #watcher = null;
31
+ constructor(config) {
32
+ super();
33
+ this.config = config;
34
+ }
35
+ async build() {
36
+ const { vite, nitro } = await this.#load();
37
+ this.#begin();
38
+ try {
39
+ await (await vite.createBuilder(this.#options(vite, nitro), null)).buildApp();
40
+ return this.#finish(null);
41
+ } catch (error) {
42
+ return this.#finish(error instanceof Error ? error.message : String(error));
43
+ }
44
+ }
45
+ async watch() {
46
+ const { watch } = await import("chokidar");
47
+ const watcher = watch([...this.config.dev.watch], {
48
+ ignored: [...this.config.dev.ignore],
49
+ ignoreInitial: true
50
+ });
51
+ this.#watcher = watcher;
52
+ watcher.on("all", () => void this.build());
53
+ watcher.on("error", (error) => this.emit("log", "error", error instanceof Error ? error.message : String(error)));
54
+ await new Promise((resolve) => watcher.once("ready", resolve));
55
+ await this.build();
56
+ }
57
+ async close() {
58
+ const watcher = this.#watcher;
59
+ this.#watcher = null;
60
+ await watcher?.close();
61
+ }
62
+ async #load() {
63
+ const [vite, nitro] = await Promise.all([importFromProject(this.config.root, "vite", VITE_INSTALL_HINT), importFromProject(this.config.root, "nitro/vite", NITRO_INSTALL_HINT)]);
64
+ return {
65
+ vite,
66
+ nitro
67
+ };
68
+ }
69
+ /**
70
+ * Same merge `ViteBuilder` uses (`stars.config#vite` layered over the project's own `vite.config.*`), with the
71
+ * `nitro()` plugin appended — after the project's own plugins, so a `nitro:` block a project adds itself to
72
+ * `vite.config.*` is still free to run its own `setup` hooks against the instance this creates — and Vite's
73
+ * native `resolve.tsconfigPaths` turned on (see https://nitro.build/examples/import-alias): the project's own
74
+ * `tsconfig.json#paths`/package.json `imports` aliases (including `.stars/tsconfig.json`'s generated ones) just
75
+ * work under Nitro, without a `vite-tsconfig-paths` plugin. `false` in the project's own `vite.resolve` still
76
+ * wins, the same as every other default here.
77
+ */
78
+ #options(vite, nitroVite) {
79
+ return {
80
+ root: this.config.root,
81
+ logLevel: "warn",
82
+ customLogger: this.#logger(vite),
83
+ ...this.config.vite,
84
+ resolve: {
85
+ tsconfigPaths: true,
86
+ ...this.config.vite.resolve
87
+ },
88
+ plugins: [
89
+ pluginRegistrations(this.config),
90
+ ...toArray(this.config.vite.plugins),
91
+ nitroVite.nitro({
92
+ preset: this.config.experimental.nitro.preset,
93
+ output: { dir: this.config.build.outDir },
94
+ serverEntry: ENTRY_VIRTUAL_ID,
95
+ virtual: { [ENTRY_VIRTUAL_ID]: () => this.#entryCode() }
96
+ })
97
+ ]
98
+ };
99
+ }
100
+ /**
101
+ * `client.fetch` imports the Discord public key once and reuses it across every call — the same lifetime
102
+ * `Client.listen()` gives its own `node:http` server — so the generated entry only has to forward the request.
103
+ */
104
+ #entryCode() {
105
+ return [
106
+ `import client from ${JSON.stringify(this.config.entry)};`,
107
+ "",
108
+ "export default {",
109
+ " fetch: (request) => client.fetch(request)",
110
+ "};",
111
+ ""
112
+ ].join("\n");
113
+ }
114
+ #logger(vite) {
115
+ return {
116
+ ...vite.createLogger("warn", { allowClearScreen: false }),
117
+ info: (message) => this.emit("log", "info", message),
118
+ warn: (message) => this.emit("log", "warn", message),
119
+ warnOnce: (message) => this.emit("log", "warn", message),
120
+ error: (message) => this.emit("log", "error", message)
121
+ };
122
+ }
123
+ #begin() {
124
+ this.#startedAt = performance.now();
125
+ this.emit("start");
126
+ }
127
+ #finish(message) {
128
+ const outcome = {
129
+ ok: message === null,
130
+ durationMs: Math.round(performance.now() - this.#startedAt),
131
+ message
132
+ };
133
+ this.#startedAt = 0;
134
+ this.emit(outcome.ok ? "success" : "failure", outcome);
135
+ return outcome;
136
+ }
137
+ };
138
+ function toArray(value) {
139
+ if (value === void 0 || value === null || value === false) return [];
140
+ return Array.isArray(value) ? value : [value];
141
+ }
142
+
143
+ //#endregion
144
+ export { NitroBuilder };
145
+ //# sourceMappingURL=nitro-Cki2gTpt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nitro-Cki2gTpt.js","names":[],"sources":["../src/builders/nitro.ts"],"sourcesContent":["import type { ResolvedStarsConfig } from '@wolfstar/http-framework/config';\nimport { EventEmitter } from 'node:events';\nimport { pluginRegistrations } from '../utils/plugin-registrations.js';\nimport { importFromProject } from '../utils/project.js';\nimport type { Builder, BuilderEvents, BuildOutcome } from './types.js';\n\ntype ViteModule = typeof import('vite');\ntype NitroViteModule = typeof import('nitro/vite');\n\nconst VITE_INSTALL_HINT = 'Install it with `pnpm add -D vite`, or turn off `experimental.enableNitro`.';\nconst NITRO_INSTALL_HINT = 'Install it with `pnpm add -D nitro`, or turn off `experimental.enableNitro`.';\n\n/**\n * The virtual module registered as Nitro's `serverEntry` (see `nitro.build/docs/server-entry`): a `#`-prefixed id\n * is never resolved against the filesystem (`resolveNitroPath` in Nitro itself special-cases it), so this never\n * collides with a real project file.\n */\nconst ENTRY_VIRTUAL_ID = '#stars/nitro-entry';\n\n/**\n * Builds the bot through [Nitro](https://nitro.build)'s Vite plugin (`nitro/vite`), the way `enableNitro` promises:\n * `stars build` produces `build.outDir` (`.output` by default) laid out for the configured preset, deployable to\n * anything Nitro targets, instead of a `node:http` process.\n *\n * Nitro v3 is itself a Vite plugin — there is no separate `nitro build` step — so this reuses the project's own\n * `vite.config.*`/`stars.config#vite` the same way {@link import('./vite.js').ViteBuilder} does, and only adds the\n * `nitro()` plugin and a generated server entry on top. That entry imports the project's `Client` instance (the\n * entry's default export, already `load()`ed — see {@link import('@wolfstar/http-framework/config').StarsExperimentalConfig.enableNitro})\n * and calls its `fetch(request)` method, in the plain `{ fetch(Request): Promise<Response> }` shape Nitro's own\n * server entry convention expects — no separate adapter module to maintain, `Client` handles Fetch requests itself.\n */\nexport class NitroBuilder extends EventEmitter<BuilderEvents> implements Builder {\n\tpublic readonly tool = 'vite' as const;\n\t#startedAt = 0;\n\t#watcher: { close(): Promise<void> } | null = null;\n\n\tpublic constructor(private readonly config: ResolvedStarsConfig) {\n\t\tsuper();\n\t}\n\n\tpublic async build(): Promise<BuildOutcome> {\n\t\tconst { vite, nitro } = await this.#load();\n\t\tthis.#begin();\n\n\t\ttry {\n\t\t\tconst builder = await vite.createBuilder(this.#options(vite, nitro), null);\n\t\t\tawait builder.buildApp();\n\t\t\treturn this.#finish(null);\n\t\t} catch (error) {\n\t\t\treturn this.#finish(error instanceof Error ? error.message : String(error));\n\t\t}\n\t}\n\n\tpublic async watch(): Promise<void> {\n\t\tconst { watch } = await import('chokidar');\n\n\t\tconst watcher = watch([...this.config.dev.watch], { ignored: [...this.config.dev.ignore], ignoreInitial: true });\n\t\tthis.#watcher = watcher;\n\t\twatcher.on('all', () => void this.build());\n\t\twatcher.on('error', (error) => this.emit('log', 'error', error instanceof Error ? error.message : String(error)));\n\n\t\tawait new Promise<void>((resolve) => watcher.once('ready', resolve));\n\t\tawait this.build();\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tconst watcher = this.#watcher;\n\t\tthis.#watcher = null;\n\t\tawait watcher?.close();\n\t}\n\n\tasync #load(): Promise<{ vite: ViteModule; nitro: NitroViteModule }> {\n\t\tconst [vite, nitro] = await Promise.all([\n\t\t\timportFromProject<ViteModule>(this.config.root, 'vite', VITE_INSTALL_HINT),\n\t\t\timportFromProject<NitroViteModule>(this.config.root, 'nitro/vite', NITRO_INSTALL_HINT)\n\t\t]);\n\t\treturn { vite, nitro };\n\t}\n\n\t/**\n\t * Same merge `ViteBuilder` uses (`stars.config#vite` layered over the project's own `vite.config.*`), with the\n\t * `nitro()` plugin appended — after the project's own plugins, so a `nitro:` block a project adds itself to\n\t * `vite.config.*` is still free to run its own `setup` hooks against the instance this creates — and Vite's\n\t * native `resolve.tsconfigPaths` turned on (see https://nitro.build/examples/import-alias): the project's own\n\t * `tsconfig.json#paths`/package.json `imports` aliases (including `.stars/tsconfig.json`'s generated ones) just\n\t * work under Nitro, without a `vite-tsconfig-paths` plugin. `false` in the project's own `vite.resolve` still\n\t * wins, the same as every other default here.\n\t */\n\t#options(vite: ViteModule, nitroVite: NitroViteModule): Parameters<ViteModule['createBuilder']>[0] {\n\t\treturn {\n\t\t\troot: this.config.root,\n\t\t\tlogLevel: 'warn',\n\t\t\tcustomLogger: this.#logger(vite),\n\t\t\t...this.config.vite,\n\t\t\tresolve: { tsconfigPaths: true, ...(this.config.vite.resolve as Record<string, unknown> | undefined) },\n\t\t\tplugins: [\n\t\t\t\tpluginRegistrations(this.config),\n\t\t\t\t...toArray(this.config.vite.plugins),\n\t\t\t\tnitroVite.nitro({\n\t\t\t\t\tpreset: this.config.experimental.nitro.preset,\n\t\t\t\t\toutput: { dir: this.config.build.outDir },\n\t\t\t\t\tserverEntry: ENTRY_VIRTUAL_ID,\n\t\t\t\t\tvirtual: { [ENTRY_VIRTUAL_ID]: () => this.#entryCode() }\n\t\t\t\t})\n\t\t\t]\n\t\t} as Parameters<ViteModule['createBuilder']>[0];\n\t}\n\n\t/**\n\t * `client.fetch` imports the Discord public key once and reuses it across every call — the same lifetime\n\t * `Client.listen()` gives its own `node:http` server — so the generated entry only has to forward the request.\n\t */\n\t#entryCode(): string {\n\t\treturn [\n\t\t\t`import client from ${JSON.stringify(this.config.entry)};`,\n\t\t\t'',\n\t\t\t'export default {',\n\t\t\t'\\tfetch: (request) => client.fetch(request)',\n\t\t\t'};',\n\t\t\t''\n\t\t].join('\\n');\n\t}\n\n\t#logger(vite: ViteModule) {\n\t\tconst logger = vite.createLogger('warn', { allowClearScreen: false });\n\t\treturn {\n\t\t\t...logger,\n\t\t\tinfo: (message: string) => this.emit('log', 'info', message),\n\t\t\twarn: (message: string) => this.emit('log', 'warn', message),\n\t\t\twarnOnce: (message: string) => this.emit('log', 'warn', message),\n\t\t\terror: (message: string) => this.emit('log', 'error', message)\n\t\t};\n\t}\n\n\t#begin(): void {\n\t\tthis.#startedAt = performance.now();\n\t\tthis.emit('start');\n\t}\n\n\t#finish(message: string | null): BuildOutcome {\n\t\tconst outcome: BuildOutcome = { ok: message === null, durationMs: Math.round(performance.now() - this.#startedAt), message };\n\t\tthis.#startedAt = 0;\n\t\tthis.emit(outcome.ok ? 'success' : 'failure', outcome);\n\t\treturn outcome;\n\t}\n}\n\nfunction toArray(value: unknown): unknown[] {\n\tif (value === undefined || value === null || value === false) return [];\n\treturn Array.isArray(value) ? value : [value];\n}\n"],"mappings":";;;;;AASA,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;;;;;;AAO3B,MAAM,mBAAmB;;;;;;;;;;;;;AAczB,IAAa,eAAb,cAAkC,aAA+C;CAK5C;CAJpC,AAAgB,OAAO;CACvB,aAAa;CACb,WAA8C;CAE9C,AAAO,YAAY,AAAiB,QAA6B;EAChE,MAAM;EAD6B;CAEpC;CAEA,MAAa,QAA+B;EAC3C,MAAM,EAAE,MAAM,UAAU,MAAM,KAAK,MAAM;EACzC,KAAK,OAAO;EAEZ,IAAI;GAEH,OAAM,MADgB,KAAK,cAAc,KAAK,SAAS,MAAM,KAAK,GAAG,IAAI,EAC5D,CAAC,SAAS;GACvB,OAAO,KAAK,QAAQ,IAAI;EACzB,SAAS,OAAO;GACf,OAAO,KAAK,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EAC3E;CACD;CAEA,MAAa,QAAuB;EACnC,MAAM,EAAE,UAAU,MAAM,OAAO;EAE/B,MAAM,UAAU,MAAM,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,GAAG;GAAE,SAAS,CAAC,GAAG,KAAK,OAAO,IAAI,MAAM;GAAG,eAAe;EAAK,CAAC;EAC/G,KAAK,WAAW;EAChB,QAAQ,GAAG,aAAa,KAAK,KAAK,MAAM,CAAC;EACzC,QAAQ,GAAG,UAAU,UAAU,KAAK,KAAK,OAAO,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;EAEhH,MAAM,IAAI,SAAe,YAAY,QAAQ,KAAK,SAAS,OAAO,CAAC;EACnE,MAAM,KAAK,MAAM;CAClB;CAEA,MAAa,QAAuB;EACnC,MAAM,UAAU,KAAK;EACrB,KAAK,WAAW;EAChB,MAAM,SAAS,MAAM;CACtB;CAEA,MAAM,QAA+D;EACpE,MAAM,CAAC,MAAM,SAAS,MAAM,QAAQ,IAAI,CACvC,kBAA8B,KAAK,OAAO,MAAM,QAAQ,iBAAiB,GACzE,kBAAmC,KAAK,OAAO,MAAM,cAAc,kBAAkB,CACtF,CAAC;EACD,OAAO;GAAE;GAAM;EAAM;CACtB;;;;;;;;;;CAWA,SAAS,MAAkB,WAAwE;EAClG,OAAO;GACN,MAAM,KAAK,OAAO;GAClB,UAAU;GACV,cAAc,KAAK,QAAQ,IAAI;GAC/B,GAAG,KAAK,OAAO;GACf,SAAS;IAAE,eAAe;IAAM,GAAI,KAAK,OAAO,KAAK;GAAgD;GACrG,SAAS;IACR,oBAAoB,KAAK,MAAM;IAC/B,GAAG,QAAQ,KAAK,OAAO,KAAK,OAAO;IACnC,UAAU,MAAM;KACf,QAAQ,KAAK,OAAO,aAAa,MAAM;KACvC,QAAQ,EAAE,KAAK,KAAK,OAAO,MAAM,OAAO;KACxC,aAAa;KACb,SAAS,GAAG,yBAAyB,KAAK,WAAW,EAAE;IACxD,CAAC;GACF;EACD;CACD;;;;;CAMA,aAAqB;EACpB,OAAO;GACN,sBAAsB,KAAK,UAAU,KAAK,OAAO,KAAK,EAAE;GACxD;GACA;GACA;GACA;GACA;EACD,CAAC,CAAC,KAAK,IAAI;CACZ;CAEA,QAAQ,MAAkB;EAEzB,OAAO;GACN,GAFc,KAAK,aAAa,QAAQ,EAAE,kBAAkB,MAAM,CAE1D;GACR,OAAO,YAAoB,KAAK,KAAK,OAAO,QAAQ,OAAO;GAC3D,OAAO,YAAoB,KAAK,KAAK,OAAO,QAAQ,OAAO;GAC3D,WAAW,YAAoB,KAAK,KAAK,OAAO,QAAQ,OAAO;GAC/D,QAAQ,YAAoB,KAAK,KAAK,OAAO,SAAS,OAAO;EAC9D;CACD;CAEA,SAAe;EACd,KAAK,aAAa,YAAY,IAAI;EAClC,KAAK,KAAK,OAAO;CAClB;CAEA,QAAQ,SAAsC;EAC7C,MAAM,UAAwB;GAAE,IAAI,YAAY;GAAM,YAAY,KAAK,MAAM,YAAY,IAAI,IAAI,KAAK,UAAU;GAAG;EAAQ;EAC3H,KAAK,aAAa;EAClB,KAAK,KAAK,QAAQ,KAAK,YAAY,WAAW,OAAO;EACrD,OAAO;CACR;AACD;AAEA,SAAS,QAAQ,OAA2B;CAC3C,IAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,OAAO,OAAO,CAAC;CACtE,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC7C"}
@@ -1,7 +1,7 @@
1
- import { n as ExitCode, t as CliError } from "./errors-DETRFkoF.js";
2
1
  import { i as shouldUseColor } from "./output-mode-Bp7Da8vJ.js";
2
+ import { t as cliDiagnostics } from "./diagnostics-C98hnJB5.js";
3
3
  import { n as resolveCwd, t as projectArgs } from "./args-Du59CLXl.js";
4
- import { t as prepareProject } from "./_shared-Cxp93Wni.js";
4
+ import { t as prepareProject } from "./_shared-dVR2pKjb.js";
5
5
  import { defineCommand } from "citty";
6
6
  import { displayPath, loadStarsConfig } from "@wolfstar/http-framework/config";
7
7
  import { createColors } from "colorette";
@@ -29,10 +29,7 @@ async function runPrepare(options) {
29
29
  stdout.write(`${colors.dim("stars")} imports: ${paint(result.status)} ${displayPath(config.root, result.dts)}\n`);
30
30
  }
31
31
  }
32
- 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.", {
33
- code: "PREPARE_OUTDATED",
34
- exitCode: ExitCode.Error
35
- });
32
+ if (result.status === "outdated" || result.tsconfig.status === "outdated") throw cliDiagnostics.PREPARE_OUTDATED({});
36
33
  }
37
34
  var prepare_default = defineCommand({
38
35
  meta: {
@@ -64,4 +61,4 @@ var prepare_default = defineCommand({
64
61
 
65
62
  //#endregion
66
63
  export { prepare_default as default };
67
- //# sourceMappingURL=prepare-Dv_8yIbG.js.map
64
+ //# sourceMappingURL=prepare-wGp-cAa9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepare-wGp-cAa9.js","names":[],"sources":["../src/commands/prepare.ts"],"sourcesContent":["import { displayPath, loadStarsConfig } from '@wolfstar/http-framework/config';\nimport { defineCommand } from 'citty';\nimport { createColors } from 'colorette';\nimport { projectArgs, resolveCwd, type ProjectArgs } from '../utils/args.js';\nimport { cliDiagnostics } from '../utils/diagnostics.js';\nimport { shouldUseColor } from '../utils/output-mode.js';\nimport { prepareProject } from './_shared.js';\n\nexport { prepareProject } from './_shared.js';\n\nexport interface PrepareTaskOptions extends ProjectArgs {\n\tcheck?: boolean;\n\tjson?: boolean;\n\tstdout?: NodeJS.WritableStream;\n}\n\n/**\n * Generates `.stars/tsconfig.json` and `imports.dts` (see {@link StarsImportsConfig} in `@wolfstar/http-framework/config`), the way `nuxt\n * prepare` regenerates `.nuxt/imports.d.ts`. Run automatically by `stars dev` and `stars build` before the first\n * build; `--check` fails instead of writing, for CI.\n */\nexport async function runPrepare(options: PrepareTaskOptions): 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 result = await prepareProject(config, Boolean(options.check));\n\n\tif (options.json) {\n\t\tstdout.write(`${JSON.stringify(result, null, 2)}\\n`);\n\t} else {\n\t\tconst paintConfig = result.tsconfig.status === 'outdated' ? colors.red : colors.green;\n\t\tstdout.write(`${colors.dim('stars')} tsconfig: ${paintConfig(result.tsconfig.status)} ${displayPath(config.root, result.tsconfig.path)}\\n`);\n\t\tif (result.enabled) {\n\t\t\tconst paint = result.status === 'outdated' ? colors.red : colors.green;\n\t\t\tstdout.write(`${colors.dim('stars')} imports: ${paint(result.status)} ${displayPath(config.root, result.dts)}\\n`);\n\t\t}\n\t}\n\n\tif (result.status === 'outdated' || result.tsconfig.status === 'outdated') {\n\t\tthrow cliDiagnostics.PREPARE_OUTDATED({});\n\t}\n}\n\nexport default defineCommand({\n\tmeta: {\n\t\tname: 'prepare',\n\t\tdescription: 'Generate TypeScript configuration and auto imports declarations'\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 it',\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 runPrepare({ config: args.config, cwd: args.cwd, check: args.check, json: args.json });\n\t}\n});\n"],"mappings":";;;;;;;;;;;;;;AAqBA,eAAsB,WAAW,SAA4C;CAC5E,MAAM,SAAS,QAAQ,UAAU,QAAQ;CACzC,MAAM,SAAS,aAAa,EAAE,UAAU,eAAe,KAAK,CAAC,QAAQ,KAAK,CAAC;CAC3E,MAAM,SAAS,MAAM,gBAAgB;EAAE,KAAK,WAAW,OAAO;EAAG,YAAY,QAAQ;CAAO,CAAC;CAC7F,MAAM,SAAS,MAAM,eAAe,QAAQ,QAAQ,QAAQ,KAAK,CAAC;CAElE,IAAI,QAAQ,MACX,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,GAAG;MAC7C;EACN,MAAM,cAAc,OAAO,SAAS,WAAW,aAAa,OAAO,MAAM,OAAO;EAChF,OAAO,MAAM,GAAG,OAAO,IAAI,OAAO,EAAE,aAAa,YAAY,OAAO,SAAS,MAAM,EAAE,GAAG,YAAY,OAAO,MAAM,OAAO,SAAS,IAAI,EAAE,GAAG;EAC1I,IAAI,OAAO,SAAS;GACnB,MAAM,QAAQ,OAAO,WAAW,aAAa,OAAO,MAAM,OAAO;GACjE,OAAO,MAAM,GAAG,OAAO,IAAI,OAAO,EAAE,YAAY,MAAM,OAAO,MAAM,EAAE,GAAG,YAAY,OAAO,MAAM,OAAO,GAAG,EAAE,GAAG;EACjH;CACD;CAEA,IAAI,OAAO,WAAW,cAAc,OAAO,SAAS,WAAW,YAC9D,MAAM,eAAe,iBAAiB,CAAC,CAAC;AAE1C;AAEA,sBAAe,cAAc;CAC5B,MAAM;EACL,MAAM;EACN,aAAa;CACd;CACA,MAAM;EACL,GAAG;EACH,OAAO;GACN,MAAM;GACN,aAAa;GACb,SAAS;EACV;EACA,MAAM;GACL,MAAM;GACN,aAAa;GACb,SAAS;EACV;CACD;CACA,MAAM,IAAI,EAAE,QAAQ;EACnB,MAAM,WAAW;GAAE,QAAQ,KAAK;GAAQ,KAAK,KAAK;GAAK,OAAO,KAAK;GAAO,MAAM,KAAK;EAAK,CAAC;CAC5F;AACD,CAAC"}
@@ -1,4 +1,4 @@
1
- import { t as CliError } from "./errors-DETRFkoF.js";
1
+ import { t as cliDiagnostics } from "./diagnostics-C98hnJB5.js";
2
2
  import { createRequire } from "node:module";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
@@ -20,8 +20,9 @@ function resolveFromProject(root, id) {
20
20
  */
21
21
  async function importFromProject(root, id, hint) {
22
22
  const resolved = resolveFromProject(root, id);
23
- if (!resolved) throw new CliError(`"${id}" is not installed in ${root}`, {
24
- code: "DEPENDENCY_MISSING",
23
+ if (!resolved) throw cliDiagnostics.DEPENDENCY_MISSING({
24
+ name: id,
25
+ root,
25
26
  hint
26
27
  });
27
28
  return await import(pathToFileURL(resolved).href);
@@ -63,4 +64,4 @@ function findInstalledVersion(root, name) {
63
64
 
64
65
  //#endregion
65
66
  export { resolveFromProject as i, importFromProject as n, resolveBinary as r, findInstalledVersion as t };
66
- //# sourceMappingURL=project-jVFFrLl9.js.map
67
+ //# sourceMappingURL=project-DT3wg_lf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-DT3wg_lf.js","names":[],"sources":["../src/utils/project.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { cliDiagnostics } from './diagnostics.js';\n\n/**\n * Resolves a module id from the project root, the way the project itself would.\n */\nexport function resolveFromProject(root: string, id: string): string | null {\n\ttry {\n\t\treturn createRequire(join(root, 'package.json')).resolve(id);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Imports a module from the project root, failing with an actionable error when it is not installed.\n */\nexport async function importFromProject<T>(root: string, id: string, hint: string): Promise<T> {\n\tconst resolved = resolveFromProject(root, id);\n\tif (!resolved) {\n\t\tthrow cliDiagnostics.DEPENDENCY_MISSING({ name: id, root, hint });\n\t}\n\n\treturn (await import(pathToFileURL(resolved).href)) as T;\n}\n\n/**\n * Resolves an executable a package declares in its `package.json#bin`, from the project's own `node_modules`.\n *\n * Going through `bin` rather than a hardcoded path is what makes this work across layouts: TypeScript 7 hides\n * `lib/tsc.js` behind its `exports` map, and packages move their entry points between releases.\n */\nexport function resolveBinary(root: string, packageName: string, binName: string): string | null {\n\tconst packageJsonPath = resolveFromProject(root, `${packageName}/package.json`);\n\tif (!packageJsonPath) return null;\n\n\ttry {\n\t\tconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as { bin?: string | Record<string, string> };\n\t\tconst bin = typeof packageJson.bin === 'string' ? packageJson.bin : packageJson.bin?.[binName];\n\t\treturn bin ? join(dirname(packageJsonPath), bin) : null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Finds the version of an installed package by walking `node_modules` up from `root`.\n */\nexport function findInstalledVersion(root: string, name: string): string | null {\n\tlet directory = root;\n\tfor (;;) {\n\t\tconst file = join(directory, 'node_modules', name, 'package.json');\n\t\tif (existsSync(file)) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(readFileSync(file, 'utf-8')) as { version?: string };\n\t\t\t\treturn parsed.version ?? null;\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\n\t\tconst parent = dirname(directory);\n\t\tif (parent === directory) return null;\n\t\tdirectory = parent;\n\t}\n}\n"],"mappings":";;;;;;;;;;AASA,SAAgB,mBAAmB,MAAc,IAA2B;CAC3E,IAAI;EACH,OAAO,cAAc,KAAK,MAAM,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC5D,QAAQ;EACP,OAAO;CACR;AACD;;;;AAKA,eAAsB,kBAAqB,MAAc,IAAY,MAA0B;CAC9F,MAAM,WAAW,mBAAmB,MAAM,EAAE;CAC5C,IAAI,CAAC,UACJ,MAAM,eAAe,mBAAmB;EAAE,MAAM;EAAI;EAAM;CAAK,CAAC;CAGjE,OAAQ,MAAM,OAAO,cAAc,QAAQ,CAAC,CAAC;AAC9C;;;;;;;AAQA,SAAgB,cAAc,MAAc,aAAqB,SAAgC;CAChG,MAAM,kBAAkB,mBAAmB,MAAM,GAAG,YAAY,cAAc;CAC9E,IAAI,CAAC,iBAAiB,OAAO;CAE7B,IAAI;EACH,MAAM,cAAc,KAAK,MAAM,aAAa,iBAAiB,OAAO,CAAC;EACrE,MAAM,MAAM,OAAO,YAAY,QAAQ,WAAW,YAAY,MAAM,YAAY,MAAM;EACtF,OAAO,MAAM,KAAK,QAAQ,eAAe,GAAG,GAAG,IAAI;CACpD,QAAQ;EACP,OAAO;CACR;AACD;;;;AAKA,SAAgB,qBAAqB,MAAc,MAA6B;CAC/E,IAAI,YAAY;CAChB,SAAS;EACR,MAAM,OAAO,KAAK,WAAW,gBAAgB,MAAM,cAAc;EACjE,IAAI,WAAW,IAAI,GAClB,IAAI;GAEH,OADe,KAAK,MAAM,aAAa,MAAM,OAAO,CACxC,CAAC,CAAC,WAAW;EAC1B,QAAQ;GACP,OAAO;EACR;EAGD,MAAM,SAAS,QAAQ,SAAS;EAChC,IAAI,WAAW,WAAW,OAAO;EACjC,YAAY;CACb;AACD"}
@@ -1,16 +1,16 @@
1
1
  import { t as readOwnPackageJson } from "./version-BzclCE19.js";
2
- import { i as formatError, r as exitCodeOf } from "./errors-DETRFkoF.js";
2
+ import { n as exitCodeOf, r as formatError } from "./errors-D1UU8atd.js";
3
3
  import { defineCommand, renderUsage, runCommand } from "citty";
4
4
  import process from "node:process";
5
5
 
6
6
  //#region src/commands/index.ts
7
7
  const commands = {
8
- dev: () => import("./dev-Q-FSs-mH.js").then((module) => module.default),
9
- build: () => import("./build-B7QQzVk8.js").then((module) => module.default),
10
- info: () => import("./info-Dt6WW6Px.js").then((module) => module.default),
11
- codegen: () => import("./codegen-Ba2qI4ji.js").then((module) => module.default),
12
- prepare: () => import("./prepare-Dv_8yIbG.js").then((module) => module.default),
13
- commands: () => import("./commands-DOkMjyT7.js").then((module) => module.default)
8
+ dev: () => import("./dev-B0RlN46N.js").then((module) => module.default),
9
+ build: () => import("./build-BUhQQ1E5.js").then((module) => module.default),
10
+ info: () => import("./info-DN4vUx1S.js").then((module) => module.default),
11
+ codegen: () => import("./codegen-hmnFzRjK.js").then((module) => module.default),
12
+ prepare: () => import("./prepare-wGp-cAa9.js").then((module) => module.default),
13
+ commands: () => import("./commands-BApoAbpQ.js").then((module) => module.default)
14
14
  };
15
15
 
16
16
  //#endregion
@@ -62,4 +62,4 @@ async function runMain(argv = process.argv.slice(2)) {
62
62
 
63
63
  //#endregion
64
64
  export { runMain as t };
65
- //# sourceMappingURL=run-DjjDIYTy.js.map
65
+ //# sourceMappingURL=run-D_j2tqWF.js.map