yargs-file-commands 1.1.1 → 1.2.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.
Files changed (39) hide show
  1. package/README.md +23 -0
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/fileCommands.d.ts +2 -0
  6. package/dist/lib/fileCommands.js +9 -1
  7. package/dist/lib/fileCommands.js.map +1 -1
  8. package/dist/lib/validatePositionals.d.ts +26 -0
  9. package/dist/lib/validatePositionals.js +104 -0
  10. package/dist/lib/validatePositionals.js.map +1 -0
  11. package/dist/tsconfig.tsbuildinfo +1 -1
  12. package/package.json +1 -9
  13. package/dist/lib/buildSegmentTree.test.d.ts +0 -1
  14. package/dist/lib/buildSegmentTree.test.js +0 -323
  15. package/dist/lib/buildSegmentTree.test.js.map +0 -1
  16. package/dist/lib/fileCommands.test.d.ts +0 -1
  17. package/dist/lib/fileCommands.test.js +0 -113
  18. package/dist/lib/fileCommands.test.js.map +0 -1
  19. package/dist/lib/fixtures/commands/$default.d.ts +0 -2
  20. package/dist/lib/fixtures/commands/$default.js +0 -5
  21. package/dist/lib/fixtures/commands/$default.js.map +0 -1
  22. package/dist/lib/fixtures/commands/create.d.ts +0 -3
  23. package/dist/lib/fixtures/commands/create.js +0 -6
  24. package/dist/lib/fixtures/commands/create.js.map +0 -1
  25. package/dist/lib/fixtures/commands/db/health.d.ts +0 -4
  26. package/dist/lib/fixtures/commands/db/health.js +0 -6
  27. package/dist/lib/fixtures/commands/db/health.js.map +0 -1
  28. package/dist/lib/fixtures/commands/db/migration/command.d.ts +0 -10
  29. package/dist/lib/fixtures/commands/db/migration/command.js +0 -9
  30. package/dist/lib/fixtures/commands/db/migration/command.js.map +0 -1
  31. package/dist/lib/importCommand.test.d.ts +0 -1
  32. package/dist/lib/importCommand.test.js +0 -165
  33. package/dist/lib/importCommand.test.js.map +0 -1
  34. package/dist/lib/scanDirectory.test.d.ts +0 -1
  35. package/dist/lib/scanDirectory.test.js +0 -169
  36. package/dist/lib/scanDirectory.test.js.map +0 -1
  37. package/dist/lib/segmentPath.test.d.ts +0 -1
  38. package/dist/lib/segmentPath.test.js +0 -33
  39. package/dist/lib/segmentPath.test.js.map +0 -1
package/README.md CHANGED
@@ -216,6 +216,29 @@ The `fileCommands` method takes the following options:
216
216
  - The verbosity level for the plugin, either `debug` or `info`
217
217
  - Default: `"info"`
218
218
 
219
+ **validation**
220
+
221
+ - Whether to validate that positional arguments registered in the builder function match those declared in the command string
222
+ - When enabled, throws an error if positional arguments are registered via `.positional()` but not declared in the command string (e.g., `command: 'create'` should be `command: 'create <arg1> <arg2>'` if positionals are used)
223
+ - This helps catch a common mistake where positional arguments are defined in the builder but missing from the command string, which causes them to be `undefined` at runtime
224
+ - Default: `true`
225
+
226
+ **Example:**
227
+
228
+ ```ts
229
+ // ❌ This will fail validation if validation: true
230
+ export const command = defineCommand({
231
+ command: 'create', // Missing positional arguments!
232
+ builder: (yargs) => yargs.positional('name', { ... }),
233
+ });
234
+
235
+ // ✅ This passes validation
236
+ export const command = defineCommand({
237
+ command: 'create <name>', // Positional arguments declared
238
+ builder: (yargs) => yargs.positional('name', { ... }),
239
+ });
240
+ ```
241
+
219
242
  ## Plugin Development (for Contributors only)
220
243
 
221
244
  If you want to contribute, just check out [this git project](https://github.com/bhouston/yargs-file-commands) and run the following commands to get going:
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from './lib/fileCommands.js';
2
1
  export * from './lib/defineCommand.js';
2
+ export * from './lib/fileCommands.js';
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from './lib/fileCommands.js';
2
1
  export * from './lib/defineCommand.js';
2
+ export * from './lib/fileCommands.js';
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC"}
@@ -7,6 +7,8 @@ import { type ScanDirectoryOptions } from './scanDirectory.js';
7
7
  export type FileCommandsOptions = ScanDirectoryOptions & {
8
8
  /** Array of directory paths to scan for command files */
9
9
  commandDirs: string[];
10
+ /** Whether to validate that positional arguments in builder match command string */
11
+ validation?: boolean;
10
12
  };
11
13
  /**
12
14
  * Default configuration options for file-based commands
@@ -3,6 +3,7 @@ import { buildSegmentTree, createCommand, logCommandTree } from './buildSegmentT
3
3
  import { importCommandFromFile } from './importCommand.js';
4
4
  import { scanDirectory } from './scanDirectory.js';
5
5
  import { segmentPath } from './segmentPath.js';
6
+ import { validatePositionals } from './validatePositionals.js';
6
7
  /**
7
8
  * Default configuration options for file-based commands
8
9
  * @constant
@@ -26,6 +27,8 @@ export const DefaultFileCommandsOptions = {
26
27
  logLevel: 'info',
27
28
  /** Default log prefix */
28
29
  logPrefix: ' ',
30
+ /** Default validation setting - enabled by default */
31
+ validation: true,
29
32
  };
30
33
  /**
31
34
  * Generates a command tree structure from files in specified directories
@@ -94,10 +97,15 @@ export const fileCommands = async (options) => {
94
97
  if (lastSegment === undefined) {
95
98
  throw new Error(`No segments found for file: ${filePath}`);
96
99
  }
100
+ const commandModule = await importCommandFromFile(filePath, lastSegment, fullOptions);
101
+ // Validate positional arguments if validation is enabled
102
+ if (fullOptions.validation) {
103
+ await validatePositionals(commandModule, filePath);
104
+ }
97
105
  return {
98
106
  fullPath: filePath,
99
107
  segments,
100
- commandModule: await importCommandFromFile(filePath, lastSegment, fullOptions),
108
+ commandModule,
101
109
  };
102
110
  })));
103
111
  commands.push(...fileResults);
@@ -1 +1 @@
1
- {"version":3,"file":"fileCommands.js","sourceRoot":"","sources":["../../src/lib/fileCommands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fileCommands.js","sourceRoot":"","sources":["../../src/lib/fileCommands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { CommandBuilder, CommandModule } from 'yargs';
2
+ /**
3
+ * Extracts positional argument names from a command string.
4
+ * Handles patterns like: "create <name>", "create <name> [optional]", etc.
5
+ *
6
+ * @param commandString - The command string (e.g., "create <serviceAccount> <token>")
7
+ * @returns Array of positional argument names found in the command string
8
+ */
9
+ export declare function extractPositionalsFromCommandString(commandString: string | readonly string[] | undefined): string[];
10
+ /**
11
+ * Extracts positional argument names from a builder function by executing it
12
+ * with a mock yargs instance and tracking what positionals are registered.
13
+ *
14
+ * @param builder - The command builder function
15
+ * @returns Array of positional argument names registered in the builder
16
+ */
17
+ export declare function extractPositionalsFromBuilder(builder: CommandBuilder | undefined): Promise<string[]>;
18
+ /**
19
+ * Validates that positional arguments registered in the builder match
20
+ * those declared in the command string.
21
+ *
22
+ * @param commandModule - The command module to validate
23
+ * @param filePath - Path to the command file (for error messages)
24
+ * @throws Error if validation fails and positionals don't match
25
+ */
26
+ export declare function validatePositionals(commandModule: CommandModule, filePath: string): Promise<void>;
@@ -0,0 +1,104 @@
1
+ import yargs from 'yargs';
2
+ /**
3
+ * Extracts positional argument names from a command string.
4
+ * Handles patterns like: "create <name>", "create <name> [optional]", etc.
5
+ *
6
+ * @param commandString - The command string (e.g., "create <serviceAccount> <token>")
7
+ * @returns Array of positional argument names found in the command string
8
+ */
9
+ export function extractPositionalsFromCommandString(commandString) {
10
+ if (!commandString) {
11
+ return [];
12
+ }
13
+ // Handle array of command strings (take the first one)
14
+ const cmd = Array.isArray(commandString) ? commandString[0] : commandString;
15
+ if (!cmd || typeof cmd !== 'string') {
16
+ return [];
17
+ }
18
+ // Match patterns like <name> or [name] in the command string
19
+ // Examples:
20
+ // - "create <serviceAccount> <token>" -> ["serviceAccount", "token"]
21
+ // - "create <name> [optional]" -> ["name", "optional"]
22
+ // - "create" -> []
23
+ const positionalPattern = /[<[]([^>\]]+)[>\]]/g;
24
+ const positionals = [];
25
+ let match = positionalPattern.exec(cmd);
26
+ while (match !== null) {
27
+ if (match[1]) {
28
+ positionals.push(match[1]);
29
+ }
30
+ match = positionalPattern.exec(cmd);
31
+ }
32
+ return positionals;
33
+ }
34
+ /**
35
+ * Extracts positional argument names from a builder function by executing it
36
+ * with a mock yargs instance and tracking what positionals are registered.
37
+ *
38
+ * @param builder - The command builder function
39
+ * @returns Array of positional argument names registered in the builder
40
+ */
41
+ export async function extractPositionalsFromBuilder(builder) {
42
+ if (!builder) {
43
+ return [];
44
+ }
45
+ // CommandBuilder can be a function or an object - we only validate function builders
46
+ if (typeof builder !== 'function') {
47
+ // Object builders don't use .positional() calls, so no positionals to extract
48
+ return [];
49
+ }
50
+ // Track positional arguments by creating a wrapper around yargs
51
+ const positionals = [];
52
+ const mockYargs = yargs([]);
53
+ // Wrap the positional method to track calls
54
+ const originalPositional = mockYargs.positional.bind(mockYargs);
55
+ // biome-ignore lint/suspicious/noExplicitAny: Need to override yargs positional method to track calls
56
+ mockYargs.positional = (name, config) => {
57
+ positionals.push(name);
58
+ return originalPositional(name, config);
59
+ };
60
+ // Execute the builder function
61
+ try {
62
+ const result = builder(mockYargs);
63
+ // Handle both sync and async builders
64
+ await (result instanceof Promise ? result : Promise.resolve(result));
65
+ }
66
+ catch {
67
+ // If builder throws, we can't validate - this is okay, yargs will catch it later
68
+ // We'll just return what we've collected so far
69
+ }
70
+ return positionals;
71
+ }
72
+ /**
73
+ * Validates that positional arguments registered in the builder match
74
+ * those declared in the command string.
75
+ *
76
+ * @param commandModule - The command module to validate
77
+ * @param filePath - Path to the command file (for error messages)
78
+ * @throws Error if validation fails and positionals don't match
79
+ */
80
+ export async function validatePositionals(commandModule, filePath) {
81
+ const commandString = commandModule.command;
82
+ const builder = commandModule.builder;
83
+ // Extract positionals from command string
84
+ const commandStringPositionals = extractPositionalsFromCommandString(commandString);
85
+ // Extract positionals from builder
86
+ const builderPositionals = await extractPositionalsFromBuilder(builder);
87
+ // If builder has positionals but command string doesn't, that's an error
88
+ if (builderPositionals.length > 0 && commandStringPositionals.length === 0) {
89
+ throw new Error(`Command in ${filePath} has ${builderPositionals.length} positional argument(s) registered in builder ` +
90
+ `(${builderPositionals.join(', ')}) but none declared in command string "${commandString}". ` +
91
+ `Positional arguments must be declared in the command string (e.g., "create <arg1> <arg2>").`);
92
+ }
93
+ // Check if all builder positionals are in command string
94
+ const missingInCommandString = builderPositionals.filter((pos) => !commandStringPositionals.includes(pos));
95
+ if (missingInCommandString.length > 0) {
96
+ throw new Error(`Command in ${filePath} has positional argument(s) registered in builder ` +
97
+ `(${missingInCommandString.join(', ')}) that are not declared in command string "${commandString}". ` +
98
+ `All positional arguments must be declared in the command string (e.g., "create <arg1> <arg2>").`);
99
+ }
100
+ // Check if command string has positionals not in builder (warning case, but not an error)
101
+ // This is allowed - you can declare positionals in command string without registering them
102
+ // But we'll still validate the reverse (builder positionals must be in command string)
103
+ }
104
+ //# sourceMappingURL=validatePositionals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validatePositionals.js","sourceRoot":"","sources":["../../src/lib/validatePositionals.ts"],"names":[],"mappings":"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"}