Преглед изворни кода

refactor(cli): Nest subcommands in command definitions

HouseinIsProgramming пре 7 месеци
родитељ
комит
7c4b37e192

+ 4 - 0
packages/cli/src/commands/add/add-operations.ts

@@ -52,6 +52,10 @@ export async function performAddOperation(options: AddOperationOptions): Promise
         // Figure out which flag was set. They are mutually exclusive: the first
         // truthy option determines the sub-command we run.
         if (options.plugin) {
+            // Validate that a plugin name was provided
+            if (typeof options.plugin !== 'string' || !options.plugin.trim()) {
+                throw new Error('Plugin name is required. Usage: vendure add -p <plugin-name>');
+            }
             await createNewPluginCommand.run({ name: options.plugin, config: options.config });
             return {
                 success: true,

+ 6 - 1
packages/cli/src/commands/add/plugin/create-new-plugin.ts

@@ -31,6 +31,11 @@ const cancelledMessage = 'Plugin setup cancelled.';
 export async function createNewPlugin(
     options: Partial<GeneratePluginOptions> = {},
 ): Promise<CliCommandReturnVal> {
+    // Validate that if a name is provided, it's actually a string
+    if (options.name !== undefined && (typeof options.name !== 'string' || !options.name.trim())) {
+        throw new Error('Plugin name is required. Usage: vendure add -p <plugin-name>');
+    }
+
     const isNonInteractive = !!options.name;
     if (!isNonInteractive) {
         intro('Adding a new Vendure plugin!');
@@ -55,7 +60,7 @@ export async function createNewPlugin(
         }
     }
     const existingPluginDir = findExistingPluginsDir(project);
-    const pluginDir = getPluginDirName(options.name , existingPluginDir);
+    const pluginDir = getPluginDirName(options.name, existingPluginDir);
 
     if (isNonInteractive) {
         options.pluginDir = pluginDir;

+ 24 - 20
packages/cli/src/commands/command-declarations.ts

@@ -33,16 +33,18 @@ export const cliCommands: CliCommandDefinition[] = [
                 long: '--job-queue [plugin]',
                 description: 'Add job-queue support to the specified plugin',
                 required: false,
-            },
-            {
-                long: '--name <n>',
-                description: 'Name for the job queue (required with -j)',
-                required: false,
-            },
-            {
-                long: '--selected-service <n>',
-                description: 'Name of the service to add the job queue to (required with -j)',
-                required: false,
+                subOptions: [
+                    {
+                        long: '--name <n>',
+                        description: 'Name for the job queue (required with -j)',
+                        required: false,
+                    },
+                    {
+                        long: '--selected-service <n>',
+                        description: 'Name of the service to add the job queue to (required with -j)',
+                        required: false,
+                    },
+                ],
             },
             {
                 short: '-c',
@@ -55,16 +57,18 @@ export const cliCommands: CliCommandDefinition[] = [
                 long: '--api-extension [plugin]',
                 description: 'Add an API extension scaffold to the specified plugin',
                 required: false,
-            },
-            {
-                long: '--queryName <n>',
-                description: 'Name for the query (used with -a)',
-                required: false,
-            },
-            {
-                long: '--mutationName <n>',
-                description: 'Name for the mutation (used with -a)',
-                required: false,
+                subOptions: [
+                    {
+                        long: '--queryName <n>',
+                        description: 'Name for the query (used with -a)',
+                        required: false,
+                    },
+                    {
+                        long: '--mutationName <n>',
+                        description: 'Name for the mutation (used with -a)',
+                        required: false,
+                    },
+                ],
             },
             {
                 short: '-u',

+ 1 - 0
packages/cli/src/shared/cli-command-definition.ts

@@ -4,6 +4,7 @@ export interface CliCommandOption {
     description: string;
     required?: boolean;
     defaultValue?: any;
+    subOptions?: CliCommandOption[]; // Options that are only valid when this option is used
 }
 
 export interface CliCommandDefinition {

+ 29 - 13
packages/cli/src/shared/command-registry.ts

@@ -1,6 +1,6 @@
 import { Command } from 'commander';
 
-import { CliCommandDefinition } from './cli-command-definition';
+import { CliCommandDefinition, CliCommandOption } from './cli-command-definition';
 
 export function registerCommands(program: Command, commands: CliCommandDefinition[]): void {
     commands.forEach(commandDef => {
@@ -14,21 +14,37 @@ export function registerCommands(program: Command, commands: CliCommandDefinitio
         // Add options if they exist
         if (commandDef.options) {
             commandDef.options.forEach(option => {
-                const parts: string[] = [];
-                if (option.short) {
-                    parts.push(option.short);
-                }
-                parts.push(option.long);
-
-                let optionString = parts.join(', ');
+                addOption(command, option);
 
-                // Handle optional options which expect a value by converting <value> to [value]
-                if (!option.required) {
-                    optionString = optionString.replace(/<([^>]+)>/g, '[$1]');
+                // Add sub-options if they exist
+                if (option.subOptions) {
+                    option.subOptions.forEach(subOption => {
+                        // Create a version of the sub-option with indented description
+                        const indentedSubOption = {
+                            ...subOption,
+                            description: `  └─ ${subOption.description}`,
+                        };
+                        addOption(command, indentedSubOption);
+                    });
                 }
-
-                command.option(optionString, option.description, option.defaultValue);
             });
         }
     });
 }
+
+function addOption(command: Command, option: CliCommandOption): void {
+    const parts: string[] = [];
+    if (option.short) {
+        parts.push(option.short);
+    }
+    parts.push(option.long);
+
+    let optionString = parts.join(', ');
+
+    // Handle optional options which expect a value by converting <value> to [value]
+    if (!option.required) {
+        optionString = optionString.replace(/<([^>]+)>/g, '[$1]');
+    }
+
+    command.option(optionString, option.description, option.defaultValue);
+}