@optique/discover 1.1.0 → 1.2.0-dev.2169

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyCommand, AnyStaticCommand, Command, CommandDefinition, CommandMetadata, CommandPath, StaticCommand, defineCommand, isCommand } from "./command-2HtR3-TV.cjs";
1
+ import { AnyCommand, AnyStaticCommand, Command, CommandDefinition, CommandMetadata, CommandPath, StaticCommand, defineCommand, isCommand } from "./command-DSHBTa5c.cjs";
2
2
  import { Mode, Parser } from "@optique/core/parser";
3
3
  import { Message } from "@optique/core/message";
4
4
  import { ProgramMetadata } from "@optique/core/program";
@@ -28,12 +28,31 @@ interface ProgramInvocation {
28
28
  */
29
29
  readonly handler: (value: unknown) => void | Promise<void>;
30
30
  }
31
+ /**
32
+ * A command paired with its command path.
33
+ *
34
+ * `createProgramParser()` accepts command entries directly, and
35
+ * `runProgram({ commands })` accepts them alongside commands that declare
36
+ * their own `path` field.
37
+ *
38
+ * @since 1.2.0
39
+ */
40
+ interface CommandEntry {
41
+ /**
42
+ * Command path used to place the command in the program tree.
43
+ */
44
+ readonly path: CommandPath;
45
+ /**
46
+ * The command definition.
47
+ */
48
+ readonly command: AnyCommand;
49
+ }
31
50
  /**
32
51
  * A command found on disk.
33
52
  *
34
53
  * @since 1.1.0
35
54
  */
36
- interface DiscoveredCommand {
55
+ interface DiscoveredCommand extends CommandEntry {
37
56
  /**
38
57
  * Command path derived from the module's relative path.
39
58
  */
@@ -47,6 +66,26 @@ interface DiscoveredCommand {
47
66
  */
48
67
  readonly command: AnyCommand;
49
68
  }
69
+ /**
70
+ * A command loaded from a static module map.
71
+ *
72
+ * @since 1.2.0
73
+ */
74
+ interface ModuleCommand extends CommandEntry {
75
+ /**
76
+ * Module map key used to derive the command path.
77
+ */
78
+ readonly modulePath: string;
79
+ }
80
+ /**
81
+ * Static module map accepted by {@link commandsFromModules}.
82
+ *
83
+ * This matches eager glob import APIs such as Vite's
84
+ * `import.meta.glob(..., { eager: true })`.
85
+ *
86
+ * @since 1.2.0
87
+ */
88
+ type ModuleMap = Readonly<Record<string, unknown>>;
50
89
  /**
51
90
  * Options for {@link discoverCommands}.
52
91
  *
@@ -64,6 +103,45 @@ interface DiscoverCommandsOptions {
64
103
  * @default Runtime-aware extension defaults from {@link getDefaultExtensions}
65
104
  */
66
105
  readonly extensions?: readonly string[];
106
+ /**
107
+ * File name that maps to the containing command path after extension
108
+ * stripping. For example, `stash/index.ts` maps to `stash`, and root
109
+ * `index.ts` maps to the root command. Pass `false` to treat matching files
110
+ * as ordinary command names.
111
+ *
112
+ * @default `"index"`
113
+ * @since 1.2.0
114
+ */
115
+ readonly entryFileName?: string | false;
116
+ }
117
+ /**
118
+ * Options for {@link commandsFromModules}.
119
+ *
120
+ * @since 1.2.0
121
+ */
122
+ interface CommandsFromModulesOptions {
123
+ /**
124
+ * Base module path to strip before deriving command paths.
125
+ *
126
+ * @default `"."`
127
+ */
128
+ readonly base?: string;
129
+ /**
130
+ * Module suffixes to include. Compound suffixes such as `.cmd.ts` are
131
+ * supported.
132
+ *
133
+ * @default Runtime-aware extension defaults from {@link getDefaultExtensions}
134
+ */
135
+ readonly extensions?: readonly string[];
136
+ /**
137
+ * File name that maps to the containing command path after extension
138
+ * stripping. For example, `stash/index.ts` maps to `stash`, and root
139
+ * `index.ts` maps to the root command. Pass `false` to treat matching files
140
+ * as ordinary command names.
141
+ *
142
+ * @default `"index"`
143
+ */
144
+ readonly entryFileName?: string | false;
67
145
  }
68
146
  /**
69
147
  * Runtime hint for {@link getDefaultExtensions}.
@@ -134,6 +212,14 @@ interface RunProgramDiscoveryOptions extends RunProgramBaseOptions {
134
212
  * File suffixes to include during discovery.
135
213
  */
136
214
  readonly extensions?: readonly string[];
215
+ /**
216
+ * File name that maps to the containing command path after extension
217
+ * stripping.
218
+ *
219
+ * @default `"index"`
220
+ * @since 1.2.0
221
+ */
222
+ readonly entryFileName?: string | false;
137
223
  /**
138
224
  * Static commands cannot be used together with `dir`.
139
225
  */
@@ -147,8 +233,11 @@ interface RunProgramDiscoveryOptions extends RunProgramBaseOptions {
147
233
  interface RunProgramStaticOptions extends RunProgramBaseOptions {
148
234
  /**
149
235
  * Commands to compose without file-system discovery.
236
+ *
237
+ * Pass commands that declare their own `path`, or command entries returned
238
+ * by {@link commandsFromModules}.
150
239
  */
151
- readonly commands: readonly AnyStaticCommand[];
240
+ readonly commands: readonly (AnyStaticCommand | CommandEntry)[];
152
241
  /**
153
242
  * File-system discovery cannot be used together with `commands`.
154
243
  */
@@ -157,6 +246,10 @@ interface RunProgramStaticOptions extends RunProgramBaseOptions {
157
246
  * File suffixes are only used with file-system discovery.
158
247
  */
159
248
  readonly extensions?: never;
249
+ /**
250
+ * Entry file names are only used with file-system discovery.
251
+ */
252
+ readonly entryFileName?: never;
160
253
  }
161
254
  /**
162
255
  * Options for {@link runProgram}.
@@ -178,21 +271,39 @@ declare function getDefaultExtensions(options?: RuntimeExtensionOptions): readon
178
271
  * @param options Discovery options.
179
272
  * @returns Discovered commands sorted by command path.
180
273
  * @throws {TypeError} If options are invalid, discovery finds no commands,
181
- * command paths conflict, or a module does not default-export a
182
- * command created with `defineCommand()`.
274
+ * command paths are duplicated, or a module does not default-export
275
+ * a command created with `defineCommand()`.
183
276
  * @since 1.1.0
184
277
  */
185
278
  declare function discoverCommands(options: DiscoverCommandsOptions): Promise<readonly DiscoveredCommand[]>;
279
+ /**
280
+ * Converts a static module map into command entries.
281
+ *
282
+ * This is useful for bundlers and single-file packagers that can statically
283
+ * see module maps, such as `import.meta.glob(..., { eager: true })`, while
284
+ * still deriving command paths from file-like module keys.
285
+ *
286
+ * @param modules Static module map keyed by module path.
287
+ * @param options Module path derivation options.
288
+ * @returns Command entries sorted by command path.
289
+ * @throws {TypeError} If options are invalid, no command modules are found,
290
+ * command paths are duplicated, a module does not default-export a
291
+ * command created with `defineCommand()`, or an explicit command
292
+ * `path` does not match the module-derived path.
293
+ * @since 1.2.0
294
+ */
295
+ declare function commandsFromModules(modules: ModuleMap, options?: CommandsFromModulesOptions): readonly ModuleCommand[];
186
296
  /**
187
297
  * Builds a parser that dispatches to discovered command handlers.
188
298
  *
189
299
  * @param commands Commands to compose.
190
300
  * @param metadata Optional root documentation metadata.
191
301
  * @returns A parser that resolves to an internal command invocation.
192
- * @throws {TypeError} If no commands are provided or command paths conflict.
302
+ * @throws {TypeError} If no commands are provided or command paths are
303
+ * duplicated.
193
304
  * @since 1.1.0
194
305
  */
195
- declare function createProgramParser(commands: readonly Pick<DiscoveredCommand, "path" | "command">[], metadata?: ProgramHelpMetadata): Parser<Mode, ProgramInvocation, unknown>;
306
+ declare function createProgramParser(commands: readonly CommandEntry[], metadata?: ProgramHelpMetadata): Parser<Mode, ProgramInvocation, unknown>;
196
307
  /**
197
308
  * Discovers and runs a command program.
198
309
  *
@@ -223,4 +334,4 @@ interface ProgramHelpMetadata {
223
334
  readonly footer?: Message;
224
335
  }
225
336
  //#endregion
226
- export { type AnyCommand, type AnyStaticCommand, type Command, type CommandDefinition, type CommandMetadata, type CommandPath, DiscoverCommandsOptions, DiscoveredCommand, ProgramHelpMetadata, ProgramInvocation, RunProgramDiscoveryOptions, RunProgramOptions, RunProgramStaticOptions, RuntimeExtensionOptions, type StaticCommand, createProgramParser, defineCommand, discoverCommands, getDefaultExtensions, isCommand, runProgram };
337
+ export { type AnyCommand, type AnyStaticCommand, type Command, type CommandDefinition, CommandEntry, type CommandMetadata, type CommandPath, CommandsFromModulesOptions, DiscoverCommandsOptions, DiscoveredCommand, ModuleCommand, ModuleMap, ProgramHelpMetadata, ProgramInvocation, RunProgramDiscoveryOptions, RunProgramOptions, RunProgramStaticOptions, RuntimeExtensionOptions, type StaticCommand, commandsFromModules, createProgramParser, defineCommand, discoverCommands, getDefaultExtensions, isCommand, runProgram };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AnyCommand, AnyStaticCommand, Command, CommandDefinition, CommandMetadata, CommandPath, StaticCommand, defineCommand, isCommand } from "./command-BAVhIzfI.js";
1
+ import { AnyCommand, AnyStaticCommand, Command, CommandDefinition, CommandMetadata, CommandPath, StaticCommand, defineCommand, isCommand } from "./command-DyiVIMUh.js";
2
2
  import { RunOptions } from "@optique/run";
3
3
  import { Mode, Parser } from "@optique/core/parser";
4
4
  import { Message } from "@optique/core/message";
@@ -28,12 +28,31 @@ interface ProgramInvocation {
28
28
  */
29
29
  readonly handler: (value: unknown) => void | Promise<void>;
30
30
  }
31
+ /**
32
+ * A command paired with its command path.
33
+ *
34
+ * `createProgramParser()` accepts command entries directly, and
35
+ * `runProgram({ commands })` accepts them alongside commands that declare
36
+ * their own `path` field.
37
+ *
38
+ * @since 1.2.0
39
+ */
40
+ interface CommandEntry {
41
+ /**
42
+ * Command path used to place the command in the program tree.
43
+ */
44
+ readonly path: CommandPath;
45
+ /**
46
+ * The command definition.
47
+ */
48
+ readonly command: AnyCommand;
49
+ }
31
50
  /**
32
51
  * A command found on disk.
33
52
  *
34
53
  * @since 1.1.0
35
54
  */
36
- interface DiscoveredCommand {
55
+ interface DiscoveredCommand extends CommandEntry {
37
56
  /**
38
57
  * Command path derived from the module's relative path.
39
58
  */
@@ -47,6 +66,26 @@ interface DiscoveredCommand {
47
66
  */
48
67
  readonly command: AnyCommand;
49
68
  }
69
+ /**
70
+ * A command loaded from a static module map.
71
+ *
72
+ * @since 1.2.0
73
+ */
74
+ interface ModuleCommand extends CommandEntry {
75
+ /**
76
+ * Module map key used to derive the command path.
77
+ */
78
+ readonly modulePath: string;
79
+ }
80
+ /**
81
+ * Static module map accepted by {@link commandsFromModules}.
82
+ *
83
+ * This matches eager glob import APIs such as Vite's
84
+ * `import.meta.glob(..., { eager: true })`.
85
+ *
86
+ * @since 1.2.0
87
+ */
88
+ type ModuleMap = Readonly<Record<string, unknown>>;
50
89
  /**
51
90
  * Options for {@link discoverCommands}.
52
91
  *
@@ -64,6 +103,45 @@ interface DiscoverCommandsOptions {
64
103
  * @default Runtime-aware extension defaults from {@link getDefaultExtensions}
65
104
  */
66
105
  readonly extensions?: readonly string[];
106
+ /**
107
+ * File name that maps to the containing command path after extension
108
+ * stripping. For example, `stash/index.ts` maps to `stash`, and root
109
+ * `index.ts` maps to the root command. Pass `false` to treat matching files
110
+ * as ordinary command names.
111
+ *
112
+ * @default `"index"`
113
+ * @since 1.2.0
114
+ */
115
+ readonly entryFileName?: string | false;
116
+ }
117
+ /**
118
+ * Options for {@link commandsFromModules}.
119
+ *
120
+ * @since 1.2.0
121
+ */
122
+ interface CommandsFromModulesOptions {
123
+ /**
124
+ * Base module path to strip before deriving command paths.
125
+ *
126
+ * @default `"."`
127
+ */
128
+ readonly base?: string;
129
+ /**
130
+ * Module suffixes to include. Compound suffixes such as `.cmd.ts` are
131
+ * supported.
132
+ *
133
+ * @default Runtime-aware extension defaults from {@link getDefaultExtensions}
134
+ */
135
+ readonly extensions?: readonly string[];
136
+ /**
137
+ * File name that maps to the containing command path after extension
138
+ * stripping. For example, `stash/index.ts` maps to `stash`, and root
139
+ * `index.ts` maps to the root command. Pass `false` to treat matching files
140
+ * as ordinary command names.
141
+ *
142
+ * @default `"index"`
143
+ */
144
+ readonly entryFileName?: string | false;
67
145
  }
68
146
  /**
69
147
  * Runtime hint for {@link getDefaultExtensions}.
@@ -134,6 +212,14 @@ interface RunProgramDiscoveryOptions extends RunProgramBaseOptions {
134
212
  * File suffixes to include during discovery.
135
213
  */
136
214
  readonly extensions?: readonly string[];
215
+ /**
216
+ * File name that maps to the containing command path after extension
217
+ * stripping.
218
+ *
219
+ * @default `"index"`
220
+ * @since 1.2.0
221
+ */
222
+ readonly entryFileName?: string | false;
137
223
  /**
138
224
  * Static commands cannot be used together with `dir`.
139
225
  */
@@ -147,8 +233,11 @@ interface RunProgramDiscoveryOptions extends RunProgramBaseOptions {
147
233
  interface RunProgramStaticOptions extends RunProgramBaseOptions {
148
234
  /**
149
235
  * Commands to compose without file-system discovery.
236
+ *
237
+ * Pass commands that declare their own `path`, or command entries returned
238
+ * by {@link commandsFromModules}.
150
239
  */
151
- readonly commands: readonly AnyStaticCommand[];
240
+ readonly commands: readonly (AnyStaticCommand | CommandEntry)[];
152
241
  /**
153
242
  * File-system discovery cannot be used together with `commands`.
154
243
  */
@@ -157,6 +246,10 @@ interface RunProgramStaticOptions extends RunProgramBaseOptions {
157
246
  * File suffixes are only used with file-system discovery.
158
247
  */
159
248
  readonly extensions?: never;
249
+ /**
250
+ * Entry file names are only used with file-system discovery.
251
+ */
252
+ readonly entryFileName?: never;
160
253
  }
161
254
  /**
162
255
  * Options for {@link runProgram}.
@@ -178,21 +271,39 @@ declare function getDefaultExtensions(options?: RuntimeExtensionOptions): readon
178
271
  * @param options Discovery options.
179
272
  * @returns Discovered commands sorted by command path.
180
273
  * @throws {TypeError} If options are invalid, discovery finds no commands,
181
- * command paths conflict, or a module does not default-export a
182
- * command created with `defineCommand()`.
274
+ * command paths are duplicated, or a module does not default-export
275
+ * a command created with `defineCommand()`.
183
276
  * @since 1.1.0
184
277
  */
185
278
  declare function discoverCommands(options: DiscoverCommandsOptions): Promise<readonly DiscoveredCommand[]>;
279
+ /**
280
+ * Converts a static module map into command entries.
281
+ *
282
+ * This is useful for bundlers and single-file packagers that can statically
283
+ * see module maps, such as `import.meta.glob(..., { eager: true })`, while
284
+ * still deriving command paths from file-like module keys.
285
+ *
286
+ * @param modules Static module map keyed by module path.
287
+ * @param options Module path derivation options.
288
+ * @returns Command entries sorted by command path.
289
+ * @throws {TypeError} If options are invalid, no command modules are found,
290
+ * command paths are duplicated, a module does not default-export a
291
+ * command created with `defineCommand()`, or an explicit command
292
+ * `path` does not match the module-derived path.
293
+ * @since 1.2.0
294
+ */
295
+ declare function commandsFromModules(modules: ModuleMap, options?: CommandsFromModulesOptions): readonly ModuleCommand[];
186
296
  /**
187
297
  * Builds a parser that dispatches to discovered command handlers.
188
298
  *
189
299
  * @param commands Commands to compose.
190
300
  * @param metadata Optional root documentation metadata.
191
301
  * @returns A parser that resolves to an internal command invocation.
192
- * @throws {TypeError} If no commands are provided or command paths conflict.
302
+ * @throws {TypeError} If no commands are provided or command paths are
303
+ * duplicated.
193
304
  * @since 1.1.0
194
305
  */
195
- declare function createProgramParser(commands: readonly Pick<DiscoveredCommand, "path" | "command">[], metadata?: ProgramHelpMetadata): Parser<Mode, ProgramInvocation, unknown>;
306
+ declare function createProgramParser(commands: readonly CommandEntry[], metadata?: ProgramHelpMetadata): Parser<Mode, ProgramInvocation, unknown>;
196
307
  /**
197
308
  * Discovers and runs a command program.
198
309
  *
@@ -223,4 +334,4 @@ interface ProgramHelpMetadata {
223
334
  readonly footer?: Message;
224
335
  }
225
336
  //#endregion
226
- export { type AnyCommand, type AnyStaticCommand, type Command, type CommandDefinition, type CommandMetadata, type CommandPath, DiscoverCommandsOptions, DiscoveredCommand, ProgramHelpMetadata, ProgramInvocation, RunProgramDiscoveryOptions, RunProgramOptions, RunProgramStaticOptions, RuntimeExtensionOptions, type StaticCommand, createProgramParser, defineCommand, discoverCommands, getDefaultExtensions, isCommand, runProgram };
337
+ export { type AnyCommand, type AnyStaticCommand, type Command, type CommandDefinition, CommandEntry, type CommandMetadata, type CommandPath, CommandsFromModulesOptions, DiscoverCommandsOptions, DiscoveredCommand, ModuleCommand, ModuleMap, ProgramHelpMetadata, ProgramInvocation, RunProgramDiscoveryOptions, RunProgramOptions, RunProgramStaticOptions, RuntimeExtensionOptions, type StaticCommand, commandsFromModules, createProgramParser, defineCommand, discoverCommands, getDefaultExtensions, isCommand, runProgram };