@znight/cli 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +482 -2
- package/bin/znight.mjs +17 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +13 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/dev/orphan-guard.d.mts +1 -0
- package/dist/dev/orphan-guard.mjs +47 -0
- package/dist/dev/orphan-guard.mjs.map +1 -0
- package/dist/index.d.mts +679 -0
- package/dist/index.mjs +1 -0
- package/dist/main-BWsiUsxN.mjs +3865 -0
- package/dist/main-BWsiUsxN.mjs.map +1 -0
- package/dist/orphan-Dn-2xMBd.mjs +45 -0
- package/dist/orphan-Dn-2xMBd.mjs.map +1 -0
- package/package.json +71 -4
- package/src/cli.ts +11 -0
- package/src/command.ts +217 -0
- package/src/commands/build.ts +159 -0
- package/src/commands/dev.ts +249 -0
- package/src/commands/generate.ts +304 -0
- package/src/commands/new.ts +245 -0
- package/src/commands/openapi.ts +160 -0
- package/src/commands/schematic.ts +110 -0
- package/src/commands/shared.ts +106 -0
- package/src/commands/start.ts +79 -0
- package/src/context.ts +126 -0
- package/src/dev/orphan-guard.ts +49 -0
- package/src/dev/orphan.ts +74 -0
- package/src/dev/supervisor.ts +175 -0
- package/src/errors.ts +64 -0
- package/src/index.ts +73 -0
- package/src/integrations/compiler.ts +360 -0
- package/src/integrations/openapi.ts +97 -0
- package/src/integrations/process.ts +180 -0
- package/src/integrations/prompts.ts +108 -0
- package/src/integrations/resolve.ts +38 -0
- package/src/integrations/vite.ts +362 -0
- package/src/integrations/watch.ts +243 -0
- package/src/main.ts +195 -0
- package/src/names.ts +106 -0
- package/src/output.ts +110 -0
- package/src/runtime.ts +86 -0
- package/src/scaffold/create.ts +65 -0
- package/src/scaffold/options.ts +103 -0
- package/src/scaffold/templates.ts +771 -0
- package/src/scaffold/versions.ts +25 -0
- package/src/schematics/index.ts +422 -0
- package/src/version.ts +20 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
import { ArgsDef, ParsedArgs } from "citty";
|
|
2
|
+
import picocolors from "picocolors";
|
|
3
|
+
import { InlineConfig, Plugin } from "vite";
|
|
4
|
+
/** Location of a diagnostic (`Diagnostic.location`, §6.2). */
|
|
5
|
+
interface DiagnosticLocation {
|
|
6
|
+
readonly file: string;
|
|
7
|
+
readonly line: number;
|
|
8
|
+
readonly column: number;
|
|
9
|
+
}
|
|
10
|
+
/** A compiler diagnostic (§6.2). */
|
|
11
|
+
interface Diagnostic {
|
|
12
|
+
readonly code: string;
|
|
13
|
+
readonly severity: "error" | "warning";
|
|
14
|
+
readonly message: string;
|
|
15
|
+
readonly location?: DiagnosticLocation | undefined;
|
|
16
|
+
readonly hints?: readonly string[] | undefined;
|
|
17
|
+
readonly related?: readonly {
|
|
18
|
+
readonly message: string;
|
|
19
|
+
readonly location: DiagnosticLocation;
|
|
20
|
+
}[] | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** A string alias of Vite's `resolve.alias` (`CompileOptions.aliases` of the compiler). */
|
|
23
|
+
interface StringAliasLike {
|
|
24
|
+
readonly find: string;
|
|
25
|
+
readonly replacement: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Compiler options (`ZnightOptions`, §6.2, plus the `CompileOptions` the Vite plugin derives from the
|
|
29
|
+
* Vite config). The CLI reads `root`, `include` and `outFile`; the others are passed through.
|
|
30
|
+
*/
|
|
31
|
+
interface ZnightOptions {
|
|
32
|
+
readonly root?: string | undefined;
|
|
33
|
+
readonly include?: readonly string[] | undefined;
|
|
34
|
+
readonly outFile?: string | undefined;
|
|
35
|
+
/** String aliases of the Vite config (`resolve.alias`). */
|
|
36
|
+
readonly aliases?: readonly StringAliasLike[] | undefined;
|
|
37
|
+
readonly [option: string]: unknown;
|
|
38
|
+
}
|
|
39
|
+
/** What the CLI reads from a compile result (`CompileResult`, §6.2). */
|
|
40
|
+
interface CompileResultLike {
|
|
41
|
+
/** Content of the generated module (with errors: a module throwing them, or empty). */
|
|
42
|
+
readonly code: string;
|
|
43
|
+
/** Absolute path of the generated module. */
|
|
44
|
+
readonly outFile: string;
|
|
45
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
46
|
+
readonly stats?: {
|
|
47
|
+
readonly files?: number;
|
|
48
|
+
readonly providers?: number;
|
|
49
|
+
readonly durationMs?: number;
|
|
50
|
+
} | undefined;
|
|
51
|
+
/** Files the result depends on (`createCompiler()` results). */
|
|
52
|
+
readonly watchFiles?: readonly string[] | undefined;
|
|
53
|
+
}
|
|
54
|
+
/** Result of {@link CompilerApi.generate}. */
|
|
55
|
+
interface GenerateResultLike extends CompileResultLike {
|
|
56
|
+
/** Whether the generated module was written (its content changed). */
|
|
57
|
+
readonly written: boolean;
|
|
58
|
+
}
|
|
59
|
+
/** Result of {@link CompilerApi.check}. */
|
|
60
|
+
interface CheckResultLike extends CompileResultLike {
|
|
61
|
+
/** The generated files on disk are missing or differ from what would be generated. */
|
|
62
|
+
readonly stale: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* The generated files that are missing or out of date (the module, and `znight.providers.json` in
|
|
65
|
+
* library mode). Empty when `stale` is `false`; empty or absent with `stale` when the compiler
|
|
66
|
+
* does not say which file is stale.
|
|
67
|
+
*/
|
|
68
|
+
readonly staleFiles?: readonly string[] | undefined;
|
|
69
|
+
}
|
|
70
|
+
/** Files changed since the previous compile of an {@link IncrementalCompiler}. */
|
|
71
|
+
interface CompilerChanges {
|
|
72
|
+
readonly changed?: readonly string[];
|
|
73
|
+
readonly added?: readonly string[];
|
|
74
|
+
readonly removed?: readonly string[];
|
|
75
|
+
}
|
|
76
|
+
/** Kind of a file system event (`ChangeKind` of the compiler). */
|
|
77
|
+
type ChangeKind = "changed" | "added" | "removed";
|
|
78
|
+
/** A compiler keeping its parse cache between compiles (`createCompiler()`), for watch mode. */
|
|
79
|
+
interface IncrementalCompiler {
|
|
80
|
+
/** Compiles (only `changes` are re-read, everything without) and writes the module when it changed. */
|
|
81
|
+
generate(changes?: CompilerChanges): Promise<GenerateResultLike>;
|
|
82
|
+
/** Whether `file` is the generated module (watchers ignore it). */
|
|
83
|
+
isOutFile(file: string): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Directories where a created or deleted source changes the scan (`includeRoots()` of the
|
|
86
|
+
* compiler: the bases of the `include` globs in the project and in every source library, known once
|
|
87
|
+
* compiled), to watch recursively. The project root when the compiler does not tell.
|
|
88
|
+
*/
|
|
89
|
+
includeRoots(): readonly string[];
|
|
90
|
+
/**
|
|
91
|
+
* Whether a file event can change the next compile (`isRelevantChange()` of the compiler): `watched`
|
|
92
|
+
* are the `watchFiles` of the last compile, `roots` its {@link includeRoots}. When the compiler does
|
|
93
|
+
* not tell, every event but the generated module is.
|
|
94
|
+
*/
|
|
95
|
+
isRelevantChange(kind: ChangeKind, file: string, watched: ReadonlySet<string>, roots: readonly string[]): boolean;
|
|
96
|
+
}
|
|
97
|
+
/** Options of {@link CompilerApi.formatDiagnostics}. */
|
|
98
|
+
interface FormatDiagnosticsOptions {
|
|
99
|
+
readonly color?: boolean;
|
|
100
|
+
readonly cwd?: string;
|
|
101
|
+
/** Append the summary line (`Build failed with 2 errors`). */
|
|
102
|
+
readonly summary?: boolean;
|
|
103
|
+
}
|
|
104
|
+
/** Options read from `znight.config.*` (`loadZnightConfig()`, §6.3). */
|
|
105
|
+
interface ZnightConfigLike {
|
|
106
|
+
/** The config file, `undefined` when the project has none. */
|
|
107
|
+
readonly file: string | undefined;
|
|
108
|
+
/** Its options, `root` resolved against the config file directory. */
|
|
109
|
+
readonly options: ZnightOptions;
|
|
110
|
+
}
|
|
111
|
+
/** The part of `@znight/compiler` used by the CLI. */
|
|
112
|
+
interface CompilerApi {
|
|
113
|
+
/** Compiles and writes the generated module when its content changed (`generate()`). */
|
|
114
|
+
generate(options: ZnightOptions): Promise<GenerateResultLike>;
|
|
115
|
+
/** Compiles without writing and compares with the files on disk (`generate({ check: true })`). */
|
|
116
|
+
check(options: ZnightOptions): Promise<CheckResultLike>;
|
|
117
|
+
/** An incremental compiler (`createCompiler()`). */
|
|
118
|
+
createIncremental(options: ZnightOptions): IncrementalCompiler;
|
|
119
|
+
/** Code frames for diagnostics (`formatDiagnostics()`). */
|
|
120
|
+
formatDiagnostics(diagnostics: readonly Diagnostic[], options?: FormatDiagnosticsOptions): string;
|
|
121
|
+
/**
|
|
122
|
+
* The options of `znight.config.*` (or of the file named by `ZNIGHT_CONFIG`) in `root`
|
|
123
|
+
* (`loadZnightConfig()`). Absent for compilers without it.
|
|
124
|
+
*/
|
|
125
|
+
loadConfig?(root: string): Promise<ZnightConfigLike>;
|
|
126
|
+
}
|
|
127
|
+
/** A compile result as returned by any `@znight/compiler` version (extra fields are optional). */
|
|
128
|
+
interface ModuleResult extends CompileResultLike {
|
|
129
|
+
/** The disk copy of the module (`code` before it existed; they differ in `build` mode only). */
|
|
130
|
+
readonly diskCode?: string;
|
|
131
|
+
readonly written?: readonly string[];
|
|
132
|
+
readonly stale?: boolean;
|
|
133
|
+
/** The stale generated files (check mode), when the compiler tells. */
|
|
134
|
+
readonly staleFiles?: readonly string[];
|
|
135
|
+
/** Library mode: `znight.providers.json` (`library` of a `CompileResult`). */
|
|
136
|
+
readonly library?: {
|
|
137
|
+
readonly file?: unknown;
|
|
138
|
+
readonly content?: unknown;
|
|
139
|
+
} | undefined;
|
|
140
|
+
}
|
|
141
|
+
/** The parts of a `ZnightCompiler` (`createCompiler()`) the CLI uses; all optional. */
|
|
142
|
+
interface ModuleIncrementalCompiler {
|
|
143
|
+
generate?: (changes?: CompilerChanges, options?: {
|
|
144
|
+
check?: boolean;
|
|
145
|
+
}) => Promise<ModuleResult>;
|
|
146
|
+
isOutFile?: (file: string) => boolean;
|
|
147
|
+
}
|
|
148
|
+
/** The shape of the `@znight/compiler` module (every export optional: partial versions are adapted). */
|
|
149
|
+
interface CompilerModule {
|
|
150
|
+
compile?: (options?: ZnightOptions) => Promise<ModuleResult>;
|
|
151
|
+
generate?: (options?: ZnightOptions & {
|
|
152
|
+
check?: boolean;
|
|
153
|
+
}) => Promise<ModuleResult>;
|
|
154
|
+
createCompiler?: (options?: ZnightOptions) => ModuleIncrementalCompiler;
|
|
155
|
+
formatDiagnostics?: (diagnostics: readonly Diagnostic[], options?: FormatDiagnosticsOptions) => string;
|
|
156
|
+
loadZnightConfig?: (cwd?: string) => Promise<ZnightConfigLike>;
|
|
157
|
+
/** The watch roots of a compiler (`includeRoots(compiler)`). */
|
|
158
|
+
includeRoots?: (compiler: ModuleIncrementalCompiler) => readonly string[];
|
|
159
|
+
/** Whether a file event can change the next compile of a compiler (`isRelevantChange(compiler, ...)`). */
|
|
160
|
+
isRelevantChange?: (compiler: ModuleIncrementalCompiler, kind: ChangeKind, file: string, watched: ReadonlySet<string>, roots: readonly string[]) => boolean;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Loads `@znight/compiler` as installed in the project (falls back to the CLI's own peer) and adapts
|
|
164
|
+
* it to {@link CompilerApi}.
|
|
165
|
+
*/
|
|
166
|
+
export declare function loadCompiler(root: string): Promise<CompilerApi>;
|
|
167
|
+
/**
|
|
168
|
+
* Adapts a loaded compiler module: `generate()` / `generate({ check })` / `createCompiler()` when
|
|
169
|
+
* available, otherwise the same behaviour built on `compile()`.
|
|
170
|
+
*/
|
|
171
|
+
export declare function adaptCompilerModule(module: CompilerModule): CompilerApi;
|
|
172
|
+
/** Options of `emitOpenApi()` (`@znight/openapi/emit`). */
|
|
173
|
+
interface OpenApiEmitOptionsLike {
|
|
174
|
+
readonly root: string;
|
|
175
|
+
readonly output: readonly string[];
|
|
176
|
+
readonly check?: boolean;
|
|
177
|
+
readonly prefix?: string;
|
|
178
|
+
readonly runtime?: "auto" | "node" | "bun";
|
|
179
|
+
readonly converters?: string;
|
|
180
|
+
readonly config?: string;
|
|
181
|
+
readonly configLoader?: string;
|
|
182
|
+
readonly compilerOptions?: ZnightOptions;
|
|
183
|
+
}
|
|
184
|
+
/** A warning of the assembly. */
|
|
185
|
+
interface OpenApiWarningLike {
|
|
186
|
+
readonly code: string;
|
|
187
|
+
readonly message: string;
|
|
188
|
+
}
|
|
189
|
+
/** What the CLI reads from the result of `emitOpenApi()`. */
|
|
190
|
+
interface OpenApiEmitResultLike {
|
|
191
|
+
readonly ok: boolean;
|
|
192
|
+
readonly written: readonly string[];
|
|
193
|
+
readonly stale: boolean;
|
|
194
|
+
readonly staleFiles: readonly string[];
|
|
195
|
+
readonly diagnostics: readonly Diagnostic[];
|
|
196
|
+
readonly warnings: readonly OpenApiWarningLike[];
|
|
197
|
+
readonly outputs: readonly string[];
|
|
198
|
+
readonly runtime: "node" | "bun";
|
|
199
|
+
readonly document?: {
|
|
200
|
+
readonly paths?: Readonly<Record<string, object>>;
|
|
201
|
+
} | undefined;
|
|
202
|
+
}
|
|
203
|
+
/** `@znight/openapi/emit`. */
|
|
204
|
+
interface OpenApiEmitApi {
|
|
205
|
+
emitOpenApi(options: OpenApiEmitOptionsLike): Promise<OpenApiEmitResultLike>;
|
|
206
|
+
}
|
|
207
|
+
/** Options of the `openapi()` Vite plugin. */
|
|
208
|
+
interface OpenApiVitePluginOptionsLike {
|
|
209
|
+
readonly output?: string;
|
|
210
|
+
/** HTTP prefix (`servers` default when `@OpenApiDocument` declares none). */
|
|
211
|
+
readonly prefix?: string;
|
|
212
|
+
}
|
|
213
|
+
/** `@znight/openapi/vite`. */
|
|
214
|
+
interface OpenApiViteApi {
|
|
215
|
+
openapi(options?: OpenApiVitePluginOptionsLike): Plugin;
|
|
216
|
+
}
|
|
217
|
+
/** How a child process ended. */
|
|
218
|
+
interface ExitStatus {
|
|
219
|
+
/** Exit code, `null` when killed by a signal or when the process could not start. */
|
|
220
|
+
readonly code: number | null;
|
|
221
|
+
readonly signal: NodeJS.Signals | null;
|
|
222
|
+
/** Spawn failure (`ENOENT`...). */
|
|
223
|
+
readonly error?: Error | undefined;
|
|
224
|
+
}
|
|
225
|
+
/** A running child process. */
|
|
226
|
+
interface ChildHandle {
|
|
227
|
+
readonly pid: number | undefined;
|
|
228
|
+
/** Sends a signal (to its process group when it runs detached). Returns `false` when it already exited. */
|
|
229
|
+
kill(signal: NodeJS.Signals): boolean;
|
|
230
|
+
/** Resolves once the process exited (never rejects). */
|
|
231
|
+
readonly exited: Promise<ExitStatus>;
|
|
232
|
+
}
|
|
233
|
+
/** Options of {@link ProcessService.spawn}. */
|
|
234
|
+
interface SpawnOptions {
|
|
235
|
+
readonly cwd: string;
|
|
236
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
237
|
+
/** Default `'inherit'`. */
|
|
238
|
+
readonly stdio?: "inherit" | "ignore";
|
|
239
|
+
/**
|
|
240
|
+
* POSIX only: run the process in its own process group, so that a terminal Ctrl+C reaches the CLI
|
|
241
|
+
* only (the CLI then forwards exactly one signal). The process is killed when the CLI exits.
|
|
242
|
+
*/
|
|
243
|
+
readonly detached?: boolean;
|
|
244
|
+
}
|
|
245
|
+
/** Result of {@link ProcessService.run}. */
|
|
246
|
+
interface RunResult extends ExitStatus {
|
|
247
|
+
readonly stdout: string;
|
|
248
|
+
readonly stderr: string;
|
|
249
|
+
}
|
|
250
|
+
/** Options of {@link ProcessService.run}. */
|
|
251
|
+
interface RunOptions {
|
|
252
|
+
readonly cwd: string;
|
|
253
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Replaces the current process image (`execve(2)`) after changing the working directory to `cwd`.
|
|
257
|
+
* `args[0]` is the program name. Never returns on success.
|
|
258
|
+
*/
|
|
259
|
+
type ExecveFunction = (file: string, args: readonly string[], env: Readonly<Record<string, string>>, cwd: string) => void;
|
|
260
|
+
/** Process primitives used by the commands. */
|
|
261
|
+
interface ProcessService {
|
|
262
|
+
spawn(command: string, args: readonly string[], options: SpawnOptions): ChildHandle;
|
|
263
|
+
/** Runs a command to completion, capturing its output. */
|
|
264
|
+
run(command: string, args: readonly string[], options: RunOptions): Promise<RunResult>;
|
|
265
|
+
/** `process.execve` when the runtime supports it (POSIX). */
|
|
266
|
+
readonly execve?: ExecveFunction | undefined;
|
|
267
|
+
}
|
|
268
|
+
/** A choice of a select / multiselect prompt. */
|
|
269
|
+
interface PromptChoice<T extends string> {
|
|
270
|
+
readonly value: T;
|
|
271
|
+
readonly label: string;
|
|
272
|
+
readonly hint?: string;
|
|
273
|
+
}
|
|
274
|
+
/** Prompts used by the CLI. */
|
|
275
|
+
interface Prompts {
|
|
276
|
+
intro(title: string): void;
|
|
277
|
+
outro(message: string): void;
|
|
278
|
+
text(options: {
|
|
279
|
+
message: string;
|
|
280
|
+
placeholder?: string;
|
|
281
|
+
initialValue?: string;
|
|
282
|
+
validate?: (value: string) => string | undefined;
|
|
283
|
+
}): Promise<string>;
|
|
284
|
+
select<T extends string>(options: {
|
|
285
|
+
message: string;
|
|
286
|
+
choices: readonly PromptChoice<T>[];
|
|
287
|
+
initialValue?: T;
|
|
288
|
+
}): Promise<T>;
|
|
289
|
+
multiselect<T extends string>(options: {
|
|
290
|
+
message: string;
|
|
291
|
+
choices: readonly PromptChoice<T>[];
|
|
292
|
+
initialValues?: readonly T[];
|
|
293
|
+
}): Promise<T[]>;
|
|
294
|
+
confirm(options: {
|
|
295
|
+
message: string;
|
|
296
|
+
initialValue?: boolean;
|
|
297
|
+
}): Promise<boolean>;
|
|
298
|
+
/** A spinner; `stop` prints the final message. */
|
|
299
|
+
spinner(): {
|
|
300
|
+
start(message: string): void;
|
|
301
|
+
stop(message: string, failed?: boolean): void;
|
|
302
|
+
};
|
|
303
|
+
note(message: string, title?: string): void;
|
|
304
|
+
}
|
|
305
|
+
/** What the CLI reads from a config resolved by Vite (`ResolvedConfig`). */
|
|
306
|
+
interface ResolvedConfigLike {
|
|
307
|
+
/** Absolute root. */
|
|
308
|
+
readonly root: string;
|
|
309
|
+
/** The config file that was loaded. */
|
|
310
|
+
readonly configFile?: string | undefined;
|
|
311
|
+
/** Every plugin, flattened. */
|
|
312
|
+
readonly plugins: readonly unknown[];
|
|
313
|
+
readonly resolve?: {
|
|
314
|
+
readonly alias?: unknown;
|
|
315
|
+
} | undefined;
|
|
316
|
+
}
|
|
317
|
+
/** Subset of the `vite` module used by the CLI. */
|
|
318
|
+
interface ViteApi {
|
|
319
|
+
build(config: InlineConfig): Promise<unknown>;
|
|
320
|
+
/** Resolves the config as a build would, without building (absent: `znight generate` uses defaults). */
|
|
321
|
+
resolveConfig?: (config: InlineConfig, command: "build" | "serve", defaultMode?: string, defaultNodeEnv?: string) => Promise<ResolvedConfigLike>;
|
|
322
|
+
}
|
|
323
|
+
/** A directory to watch. */
|
|
324
|
+
interface WatchTarget {
|
|
325
|
+
readonly path: string;
|
|
326
|
+
readonly recursive: boolean;
|
|
327
|
+
}
|
|
328
|
+
/** A running watcher. */
|
|
329
|
+
interface FileWatcher {
|
|
330
|
+
close(): void;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Starts watching `targets`; `onChange` receives the absolute path of every changed file or
|
|
334
|
+
* directory (created, modified, deleted or renamed), except in ignored directories
|
|
335
|
+
* ({@link isIgnoredPath}).
|
|
336
|
+
*/
|
|
337
|
+
type WatchFactory = (targets: readonly WatchTarget[], onChange: (file: string) => void) => FileWatcher;
|
|
338
|
+
/** picocolors formatters (`colors.red('x')`...). */
|
|
339
|
+
type Colors = ReturnType<typeof picocolors.createColors>;
|
|
340
|
+
/** A writable text stream (`process.stdout`, or a test double). */
|
|
341
|
+
interface OutputStream {
|
|
342
|
+
write(chunk: string): unknown;
|
|
343
|
+
readonly isTTY?: boolean | undefined;
|
|
344
|
+
readonly columns?: number | undefined;
|
|
345
|
+
}
|
|
346
|
+
/** Writes consistent status lines. Errors and warnings go to stderr, everything else to stdout. */
|
|
347
|
+
interface Reporter {
|
|
348
|
+
readonly colors: Colors;
|
|
349
|
+
/** A raw line on stdout. */
|
|
350
|
+
log(message?: string): void;
|
|
351
|
+
/** `› message` */
|
|
352
|
+
info(message: string): void;
|
|
353
|
+
/** `✓ message` */
|
|
354
|
+
success(message: string): void;
|
|
355
|
+
/** `! message` (stderr) */
|
|
356
|
+
warn(message: string, hints?: readonly string[]): void;
|
|
357
|
+
/** `✗ message` (stderr) */
|
|
358
|
+
error(message: string, hints?: readonly string[]): void;
|
|
359
|
+
/** A raw line on stderr. */
|
|
360
|
+
logError(message?: string): void;
|
|
361
|
+
}
|
|
362
|
+
/** Runtime of the application process. */
|
|
363
|
+
type RuntimeName = "node" | "bun";
|
|
364
|
+
/** `--runtime` values: `auto` picks Bun when the CLI itself runs on Bun, Node.js otherwise. */
|
|
365
|
+
type RuntimeOption = RuntimeName | "auto";
|
|
366
|
+
/** The runtime executing the CLI. */
|
|
367
|
+
interface HostRuntime {
|
|
368
|
+
readonly name: RuntimeName;
|
|
369
|
+
/** Absolute path of the running executable (`process.execPath`). */
|
|
370
|
+
readonly execPath: string;
|
|
371
|
+
readonly platform: NodeJS.Platform;
|
|
372
|
+
}
|
|
373
|
+
/** A source of process signals (`process` by default). */
|
|
374
|
+
interface SignalSource {
|
|
375
|
+
on(signal: NodeJS.Signals, listener: () => void): void;
|
|
376
|
+
off(signal: NodeJS.Signals, listener: () => void): void;
|
|
377
|
+
}
|
|
378
|
+
/** External services, lazily loaded. */
|
|
379
|
+
interface CliServices {
|
|
380
|
+
/** Loads `@znight/compiler` for the project at `root`. */
|
|
381
|
+
loadCompiler(root: string): Promise<CompilerApi>;
|
|
382
|
+
/** Loads `vite` for the project at `root`. */
|
|
383
|
+
loadVite(root: string): Promise<ViteApi>;
|
|
384
|
+
/** Loads the interactive prompts. */
|
|
385
|
+
loadPrompts(): Promise<Prompts>;
|
|
386
|
+
/** Loads `@znight/openapi/emit` for the project at `root` (`znight openapi`). */
|
|
387
|
+
loadOpenApi(root: string): Promise<OpenApiEmitApi>;
|
|
388
|
+
/** Loads `@znight/openapi/vite` for the project at `root` (`znight build --openapi`). */
|
|
389
|
+
loadOpenApiVite(root: string): Promise<OpenApiViteApi>;
|
|
390
|
+
readonly processes: ProcessService;
|
|
391
|
+
readonly watch: WatchFactory;
|
|
392
|
+
}
|
|
393
|
+
/** The execution context of a command. */
|
|
394
|
+
interface CliContext {
|
|
395
|
+
readonly cwd: string;
|
|
396
|
+
readonly env: Readonly<Record<string, string | undefined>>;
|
|
397
|
+
readonly stdout: OutputStream;
|
|
398
|
+
readonly stderr: OutputStream;
|
|
399
|
+
/** Whether prompts may be shown (stdin and stdout are TTYs, not in CI). */
|
|
400
|
+
readonly interactive: boolean;
|
|
401
|
+
readonly colors: Colors;
|
|
402
|
+
readonly reporter: Reporter;
|
|
403
|
+
readonly runtime: HostRuntime;
|
|
404
|
+
/** Version of `@znight/cli`. */
|
|
405
|
+
readonly version: string;
|
|
406
|
+
readonly signals: SignalSource;
|
|
407
|
+
readonly services: CliServices;
|
|
408
|
+
/** Print stack traces of unexpected errors. */
|
|
409
|
+
readonly debug: boolean;
|
|
410
|
+
}
|
|
411
|
+
/** Overrides accepted by {@link createContext}. */
|
|
412
|
+
interface CliContextOptions {
|
|
413
|
+
readonly cwd?: string;
|
|
414
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
415
|
+
readonly stdout?: OutputStream;
|
|
416
|
+
readonly stderr?: OutputStream;
|
|
417
|
+
readonly interactive?: boolean;
|
|
418
|
+
/** `--color` / `--no-color`. */
|
|
419
|
+
readonly color?: boolean | undefined;
|
|
420
|
+
readonly runtime?: HostRuntime;
|
|
421
|
+
readonly version?: string;
|
|
422
|
+
readonly signals?: SignalSource;
|
|
423
|
+
readonly services?: Partial<CliServices>;
|
|
424
|
+
readonly debug?: boolean;
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Creates a context from the current process, with optional overrides. The environment is a copy
|
|
428
|
+
* of `process.env` taken now: tools running in the CLI process (Vite sets `NODE_ENV`) do not change
|
|
429
|
+
* what the commands see and pass to the application.
|
|
430
|
+
*/
|
|
431
|
+
export declare function createContext(options?: CliContextOptions): CliContext;
|
|
432
|
+
/** What a command receives. */
|
|
433
|
+
interface CommandRunContext<A extends ArgsDef = ArgsDef> {
|
|
434
|
+
readonly args: ParsedArgs<A>;
|
|
435
|
+
readonly cli: CliContext;
|
|
436
|
+
/** Arguments of the command as typed (before `--`). */
|
|
437
|
+
readonly rawArgs: readonly string[];
|
|
438
|
+
/** Arguments after `--` (forwarded to the application by `dev` and `start`). */
|
|
439
|
+
readonly passthrough: readonly string[];
|
|
440
|
+
}
|
|
441
|
+
/** Description of a command. */
|
|
442
|
+
interface CommandMeta {
|
|
443
|
+
readonly name: string;
|
|
444
|
+
readonly description: string;
|
|
445
|
+
readonly aliases?: readonly string[];
|
|
446
|
+
/** Usage line after `znight <name>` (default: computed from the arguments). */
|
|
447
|
+
readonly usage?: string;
|
|
448
|
+
readonly examples?: readonly string[];
|
|
449
|
+
/** Extra help paragraph printed after the options. */
|
|
450
|
+
readonly details?: string | ((colors: Colors) => string);
|
|
451
|
+
}
|
|
452
|
+
/** Definition of a command: typed arguments and the implementation. */
|
|
453
|
+
interface CommandDefinition<A extends ArgsDef> {
|
|
454
|
+
readonly meta: CommandMeta;
|
|
455
|
+
readonly args: A;
|
|
456
|
+
/** Runs the command; the returned number is the exit code (default 0). */
|
|
457
|
+
run(context: CommandRunContext<A>): number | undefined | Promise<number | undefined>;
|
|
458
|
+
}
|
|
459
|
+
/** A CLI command, ready to execute. */
|
|
460
|
+
interface Command {
|
|
461
|
+
readonly meta: CommandMeta;
|
|
462
|
+
readonly args: ArgsDef;
|
|
463
|
+
/**
|
|
464
|
+
* Parses `argv` (the arguments after the command name, without `--` pass-through arguments) and
|
|
465
|
+
* runs the command. Resolves with the exit code.
|
|
466
|
+
*/
|
|
467
|
+
execute(argv: readonly string[], passthrough: readonly string[], cli: CliContext): Promise<number>;
|
|
468
|
+
}
|
|
469
|
+
/** Creates a {@link Command}; `args` keep their literal types in `run`. */
|
|
470
|
+
export declare function defineCommand<const A extends ArgsDef>(definition: CommandDefinition<A>): Command;
|
|
471
|
+
/** Notifications of an {@link AppSupervisor}. */
|
|
472
|
+
interface SupervisorEvents {
|
|
473
|
+
/** A process was started (`restart` is false for the first one). */
|
|
474
|
+
onStart?(child: ChildHandle, restart: boolean): void;
|
|
475
|
+
/** A process stopped by the supervisor exited (`forced`: it needed SIGKILL). */
|
|
476
|
+
onStop?(status: ExitStatus, forced: boolean): void;
|
|
477
|
+
/** The current process exited by itself (crash, or the application ended). */
|
|
478
|
+
onExit?(status: ExitStatus): void;
|
|
479
|
+
/** Starting a process failed synchronously. */
|
|
480
|
+
onError?(error: unknown): void;
|
|
481
|
+
}
|
|
482
|
+
/** Options of {@link AppSupervisor}. */
|
|
483
|
+
interface AppSupervisorOptions {
|
|
484
|
+
/** Starts a new application process. */
|
|
485
|
+
readonly spawn: () => ChildHandle;
|
|
486
|
+
/** Delay applied by {@link AppSupervisor.scheduleRestart}. Default 100 ms. */
|
|
487
|
+
readonly debounceMs?: number;
|
|
488
|
+
/** Time a process gets to exit after SIGTERM before SIGKILL. Default 5000 ms. */
|
|
489
|
+
readonly killTimeoutMs?: number;
|
|
490
|
+
readonly events?: SupervisorEvents;
|
|
491
|
+
}
|
|
492
|
+
/** Keeps one application process running and restarts it on demand. */
|
|
493
|
+
export declare class AppSupervisor {
|
|
494
|
+
#private;
|
|
495
|
+
constructor(options: AppSupervisorOptions);
|
|
496
|
+
/** Whether an application process is running. */
|
|
497
|
+
get running(): boolean;
|
|
498
|
+
/** The running process. */
|
|
499
|
+
get current(): ChildHandle | undefined;
|
|
500
|
+
/** Number of processes started so far. */
|
|
501
|
+
get starts(): number;
|
|
502
|
+
/** Restarts after `debounceMs`; calls in between postpone it. */
|
|
503
|
+
scheduleRestart(): void;
|
|
504
|
+
/**
|
|
505
|
+
* Cancels a restart scheduled by {@link scheduleRestart} and not started yet (the output it would
|
|
506
|
+
* run turned out to be broken, e.g. a failed compilation). Returns whether one was pending.
|
|
507
|
+
*/
|
|
508
|
+
cancelRestart(): boolean;
|
|
509
|
+
/**
|
|
510
|
+
* Stops the current process (if any) and starts a new one. Restarts never overlap; a restart
|
|
511
|
+
* requested while another one is waiting to run is merged with it.
|
|
512
|
+
*/
|
|
513
|
+
restart(): Promise<void>;
|
|
514
|
+
/** Stops the current process with `signal` (SIGKILL after the timeout) and refuses new starts. */
|
|
515
|
+
stop(signal?: NodeJS.Signals): Promise<void>;
|
|
516
|
+
/** Immediately SIGKILLs every process (a second Ctrl+C). */
|
|
517
|
+
kill(): void;
|
|
518
|
+
}
|
|
519
|
+
/** Choices of `znight new`. */
|
|
520
|
+
/** Package managers supported by `znight new`. */
|
|
521
|
+
type PackageManager = "bun" | "npm" | "pnpm" | "yarn";
|
|
522
|
+
/** HTTP adapters of `@znight/http`. */
|
|
523
|
+
type HttpAdapterName = "node" | "fastify" | "express" | "hono";
|
|
524
|
+
/** Optional features of a new project. */
|
|
525
|
+
type Feature = "config" | "observability" | "messaging" | "schedule" | "openapi";
|
|
526
|
+
/** Every package manager, in display order. */
|
|
527
|
+
export declare const PACKAGE_MANAGERS: readonly PackageManager[];
|
|
528
|
+
/** Every HTTP adapter, in display order. */
|
|
529
|
+
export declare const HTTP_ADAPTERS: readonly HttpAdapterName[];
|
|
530
|
+
/** Every feature, in display (and canonical) order. */
|
|
531
|
+
export declare const FEATURES: readonly Feature[];
|
|
532
|
+
/** Features selected when none are given. */
|
|
533
|
+
export declare const DEFAULT_FEATURES: readonly Feature[];
|
|
534
|
+
/** Everything that determines the files of a new project. */
|
|
535
|
+
interface ProjectOptions {
|
|
536
|
+
/** npm package name. */
|
|
537
|
+
readonly name: string;
|
|
538
|
+
readonly packageManager: PackageManager;
|
|
539
|
+
readonly adapter: HttpAdapterName;
|
|
540
|
+
/** Selected features, in canonical order. */
|
|
541
|
+
readonly features: readonly Feature[];
|
|
542
|
+
/** Version range base of the `@znight/*` packages (the CLI version). */
|
|
543
|
+
readonly znightVersion: string;
|
|
544
|
+
}
|
|
545
|
+
/** A file of the new project. */
|
|
546
|
+
interface ProjectFile {
|
|
547
|
+
/** POSIX path relative to the project directory. */
|
|
548
|
+
readonly path: string;
|
|
549
|
+
readonly content: string;
|
|
550
|
+
}
|
|
551
|
+
/** Every file of a new project, sorted by path. */
|
|
552
|
+
export declare function renderProject(options: ProjectOptions): ProjectFile[];
|
|
553
|
+
/** Available schematics. */
|
|
554
|
+
type SchematicName = "service" | "controller" | "consumer" | "config" | "guard" | "interceptor" | "factory" | "job";
|
|
555
|
+
/** Names derived from the user input. */
|
|
556
|
+
interface SchematicNames {
|
|
557
|
+
/** `user-profile` */
|
|
558
|
+
readonly kebab: string;
|
|
559
|
+
/** `UserProfile` */
|
|
560
|
+
readonly pascal: string;
|
|
561
|
+
/** `userProfile` */
|
|
562
|
+
readonly camel: string;
|
|
563
|
+
/** `UserProfileService` */
|
|
564
|
+
readonly className: string;
|
|
565
|
+
/**
|
|
566
|
+
* Dotted name of the element in the application: the directories of its file relative to `src/`
|
|
567
|
+
* (or to the project root, for a `--path` outside `src/`) and its kebab name, without the directory
|
|
568
|
+
* named after it (`reports.digest` for `src/reports/digest.jobs.ts`, `digest` for
|
|
569
|
+
* `src/digest/digest.jobs.ts`). Unlike `kebab`, it tells apart elements of the same name in different
|
|
570
|
+
* directories: the default name of a job (job names are unique in the application).
|
|
571
|
+
*/
|
|
572
|
+
readonly qualified: string;
|
|
573
|
+
}
|
|
574
|
+
/** Project facts that change the generated code. */
|
|
575
|
+
interface SchematicContext {
|
|
576
|
+
/** The project depends on `zod`: consumers get a message schema. */
|
|
577
|
+
readonly zod: boolean;
|
|
578
|
+
/** `interceptor` only: a method interceptor (`@Intercept`, AOP) instead of an HTTP interceptor. */
|
|
579
|
+
readonly aop: boolean;
|
|
580
|
+
}
|
|
581
|
+
/** A schematic. */
|
|
582
|
+
interface Schematic {
|
|
583
|
+
readonly name: SchematicName;
|
|
584
|
+
readonly aliases: readonly string[];
|
|
585
|
+
readonly description: string;
|
|
586
|
+
/** File and class suffix (`service` → `user.service.ts`, `UserService`). */
|
|
587
|
+
readonly suffix: string;
|
|
588
|
+
render(names: SchematicNames, context: SchematicContext): string;
|
|
589
|
+
/** What to do next, printed after the file is created. */
|
|
590
|
+
hint?(names: SchematicNames, context: SchematicContext): string | undefined;
|
|
591
|
+
}
|
|
592
|
+
/** Every schematic, in display order. */
|
|
593
|
+
export declare const SCHEMATICS: readonly Schematic[];
|
|
594
|
+
/** Finds a schematic by name or alias. */
|
|
595
|
+
export declare function findSchematic(name: string): Schematic | undefined;
|
|
596
|
+
/** Where and what to generate. */
|
|
597
|
+
interface SchematicPlan {
|
|
598
|
+
readonly schematic: Schematic;
|
|
599
|
+
readonly names: SchematicNames;
|
|
600
|
+
/** Absolute path of the file. */
|
|
601
|
+
readonly file: string;
|
|
602
|
+
readonly content: string;
|
|
603
|
+
readonly hint: string | undefined;
|
|
604
|
+
}
|
|
605
|
+
/** Inputs of {@link planSchematic}. */
|
|
606
|
+
interface PlanSchematicOptions {
|
|
607
|
+
readonly schematic: Schematic;
|
|
608
|
+
readonly name: string;
|
|
609
|
+
/** Project root (contains `src/`). */
|
|
610
|
+
readonly root: string;
|
|
611
|
+
/** Directory of `--path` (absolute), replacing `<root>/src`. */
|
|
612
|
+
readonly path?: string | undefined;
|
|
613
|
+
/** Do not create a directory named after the element. */
|
|
614
|
+
readonly flat?: boolean;
|
|
615
|
+
readonly context: SchematicContext;
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Computes the file of a schematic:
|
|
619
|
+
*
|
|
620
|
+
* | Input | File |
|
|
621
|
+
* | ---------------------------- | ------------------------------------- |
|
|
622
|
+
* | `service user` | `src/user/user.service.ts` |
|
|
623
|
+
* | `service users/user` | `src/users/user.service.ts` |
|
|
624
|
+
* | `service user --flat` | `src/user.service.ts` |
|
|
625
|
+
* | `service user --path lib/x` | `lib/x/user.service.ts` |
|
|
626
|
+
*/
|
|
627
|
+
export declare function planSchematic(options: PlanSchematicOptions): SchematicPlan;
|
|
628
|
+
/**
|
|
629
|
+
* Errors thrown by commands. The dispatcher turns them into a message on stderr and an exit code;
|
|
630
|
+
* any other error is reported as an unexpected failure (exit code 1, stack trace with `--debug`).
|
|
631
|
+
*/
|
|
632
|
+
/** Exit codes of the `znight` binary. */
|
|
633
|
+
export declare const ExitCode: {
|
|
634
|
+
/** The command succeeded. */
|
|
635
|
+
readonly Ok: 0;
|
|
636
|
+
/** The command failed (compilation errors, failed build, stale generated file...). */
|
|
637
|
+
readonly Failure: 1;
|
|
638
|
+
/** Invalid usage: unknown command or option, missing or invalid argument. */
|
|
639
|
+
readonly Usage: 2;
|
|
640
|
+
/** The user cancelled an interactive prompt or interrupted the command. */
|
|
641
|
+
readonly Cancelled: 130;
|
|
642
|
+
};
|
|
643
|
+
/** Options of a {@link CliError}. */
|
|
644
|
+
interface CliErrorOptions {
|
|
645
|
+
/** Exit code of the process. Default {@link ExitCode.Failure}. */
|
|
646
|
+
readonly exitCode?: number;
|
|
647
|
+
/** Lines printed after the message (`= hint: ...`). */
|
|
648
|
+
readonly hints?: readonly string[];
|
|
649
|
+
/** Original error. */
|
|
650
|
+
readonly cause?: unknown;
|
|
651
|
+
}
|
|
652
|
+
/** An expected failure: printed without stack trace. */
|
|
653
|
+
export declare class CliError extends Error {
|
|
654
|
+
readonly exitCode: number;
|
|
655
|
+
readonly hints: readonly string[];
|
|
656
|
+
constructor(message: string, options?: CliErrorOptions);
|
|
657
|
+
}
|
|
658
|
+
/** Invalid command line usage (exit code 2). The usage of the command is printed after the message. */
|
|
659
|
+
export declare class UsageError extends CliError {
|
|
660
|
+
constructor(message: string, hints?: readonly string[]);
|
|
661
|
+
}
|
|
662
|
+
/** The user cancelled a prompt (exit code 130). */
|
|
663
|
+
export declare class CancelledError extends CliError {
|
|
664
|
+
constructor(message?: string);
|
|
665
|
+
}
|
|
666
|
+
/** Every command, in help order. */
|
|
667
|
+
export declare const COMMANDS: readonly Command[];
|
|
668
|
+
/**
|
|
669
|
+
* Runs the CLI with `argv` (without the executable and script, i.e. `process.argv.slice(2)`).
|
|
670
|
+
* Resolves with the exit code; never throws.
|
|
671
|
+
*/
|
|
672
|
+
export declare function main(argv: readonly string[], options?: CliContextOptions): Promise<number>;
|
|
673
|
+
/**
|
|
674
|
+
* Version of `@znight/cli`, read from its `package.json` (one level above both `src/` and `dist/`).
|
|
675
|
+
* Projects created by `znight new` depend on `@znight/*` packages at `^<version>`.
|
|
676
|
+
*/
|
|
677
|
+
export declare function cliVersion(): string;
|
|
678
|
+
export type { AppSupervisorOptions, CheckResultLike, ChildHandle, CliContext, CliContextOptions, CliServices, Command, CommandDefinition, CommandMeta, CommandRunContext, CompileResultLike, CompilerApi, CompilerChanges, CompilerModule, Diagnostic, DiagnosticLocation, ExecveFunction, ExitStatus, Feature, FileWatcher, FormatDiagnosticsOptions, GenerateResultLike, HostRuntime, HttpAdapterName, IncrementalCompiler, OpenApiEmitApi, OpenApiEmitOptionsLike, OpenApiEmitResultLike, OpenApiViteApi, OpenApiVitePluginOptionsLike, OpenApiWarningLike, OutputStream, PackageManager, PlanSchematicOptions, ProcessService, ProjectFile, ProjectOptions, PromptChoice, Prompts, Reporter, RunOptions, RunResult, RuntimeName, RuntimeOption, Schematic, SchematicContext, SchematicName, SchematicNames, SchematicPlan, SignalSource, SpawnOptions, SupervisorEvents, WatchFactory, WatchTarget, ZnightConfigLike, ZnightOptions };
|
|
679
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { d as AppSupervisor, t as COMMANDS, _ as CancelledError, v as CliError, s as DEFAULT_FEATURES, y as ExitCode, c as FEATURES, l as HTTP_ADAPTERS, u as PACKAGE_MANAGERS, r as SCHEMATICS, b as UsageError, m as adaptCompilerModule, p as cliVersion, f as createContext, g as defineCommand, i as findSchematic, h as loadCompiler, n as main, a as planSchematic, o as renderProject } from "./main-BWsiUsxN.mjs";
|