diff --git a/src/utils/command.ts b/src/utils/command.ts index 9470ce9..947cbe3 100644 --- a/src/utils/command.ts +++ b/src/utils/command.ts @@ -133,7 +133,9 @@ export function parseCommand(input: string): Command { function tokenize(input: string): string[] { const tokens: string[] = []; let current = ''; - let inQuote: string | null = null; // ' 或 " 或 null + let inQuote: string | null = null; + let inBracket = false; + let bracketDepth = 0; let escaped = false; let i = 0; @@ -141,38 +143,57 @@ function tokenize(input: string): string[] { const char = input[i]; if (escaped) { - // 转义字符:直接添加到当前 token current += char; escaped = false; } else if (char === '\\') { - // 开始转义 escaped = true; } else if (inQuote) { - // 在引号内 if (char === inQuote) { - // 结束引号 inQuote = null; } else { current += char; } } else if (char === '"' || char === "'") { - // 开始引号 inQuote = char; + } else if (char === '[') { + if (inBracket) { + bracketDepth++; + current += char; + } else { + if (current.length > 0) { + tokens.push(current); + current = ''; + } + inBracket = true; + bracketDepth = 1; + current = '['; + } + } else if (char === ']') { + if (inBracket) { + bracketDepth--; + current += char; + if (bracketDepth === 0) { + tokens.push(current); + current = ''; + inBracket = false; + } + } else { + current += char; + } } else if (/\s/.test(char)) { - // 空白字符 - if (current.length > 0) { + if (inBracket) { + current += char; + } else if (current.length > 0) { tokens.push(current); current = ''; } } else { - // 普通字符 current += char; } i++; } - // 处理未闭合的引号 if (current.length > 0) { tokens.push(current); } @@ -231,12 +252,19 @@ export function parseCommandSchema(schemaStr: string): CommandSchema { const inner = token.slice(1, -1).trim(); if (inner.startsWith('--')) { - // 可选长格式标志或选项 const parts = inner.split(/\s+/); const name = parts[0].slice(2); - // 检查是否有类型定义(如 --flag: boolean 或 --opt: string[]) - if (name.includes(':')) { + if (name.endsWith(':')) { + const optName = name.slice(0, -1).trim(); + const typeStr = parts[1] || ''; + const parsedSchema = defineSchema(typeStr); + schema.options.push({ + name: optName, + required: false, + schema: parsedSchema, + }); + } else if (name.includes(':')) { const [optName, typeStr] = name.split(':').map(s => s.trim()); const parsedSchema = defineSchema(typeStr); schema.options.push({ @@ -245,36 +273,28 @@ export function parseCommandSchema(schemaStr: string): CommandSchema { schema: parsedSchema, }); } else if (parts.length > 1) { - // 可选选项(旧语法:--opt ) - const valueToken = parts[1]; - let typeStr = valueToken; - // 如果是 格式,提取类型 - if (valueToken.startsWith('<') && valueToken.endsWith('>')) { - typeStr = valueToken.slice(1, -1); - } - // 尝试解析为 inline-schema 类型 - let parsedSchema: ParsedSchema | undefined; - try { - parsedSchema = defineSchema(typeStr); - } catch { - // 不是有效的 schema,使用默认字符串 - } schema.options.push({ name, required: false, - schema: parsedSchema, }); } else { - // 可选标志 schema.flags.push({ name }); } } else if (inner.startsWith('-') && inner.length > 1) { - // 可选短格式标志或选项 const parts = inner.split(/\s+/); const short = parts[0].slice(1); - // 检查是否有类型定义 - if (short.includes(':')) { + if (short.endsWith(':')) { + const optName = short.slice(0, -1).trim(); + const typeStr = parts[1] || ''; + const parsedSchema = defineSchema(typeStr); + schema.options.push({ + name: optName, + short: optName, + required: false, + schema: parsedSchema, + }); + } else if (short.includes(':')) { const [optName, typeStr] = short.split(':').map(s => s.trim()); const parsedSchema = defineSchema(typeStr); schema.options.push({ @@ -284,26 +304,12 @@ export function parseCommandSchema(schemaStr: string): CommandSchema { schema: parsedSchema, }); } else if (parts.length > 1) { - // 可选选项(旧语法) - const valueToken = parts[1]; - let typeStr = valueToken; - if (valueToken.startsWith('<') && valueToken.endsWith('>')) { - typeStr = valueToken.slice(1, -1); - } - let parsedSchema: ParsedSchema | undefined; - try { - parsedSchema = defineSchema(typeStr); - } catch { - // 不是有效的 schema,使用默认字符串 - } schema.options.push({ name: short, short, required: false, - schema: parsedSchema, }); } else { - // 可选标志 schema.flags.push({ name: short, short }); } } else { @@ -336,8 +342,18 @@ export function parseCommandSchema(schemaStr: string): CommandSchema { const name = token.slice(2); const nextToken = tokens[i + 1]; - // 检查是否有类型定义(如 --flag: boolean) - if (name.includes(':')) { + if (name.endsWith(':')) { + const optName = name.slice(0, -1).trim(); + const nextPart = tokens[i + 1]; + const typeStr = nextPart || ''; + const parsedSchema = defineSchema(typeStr); + schema.options.push({ + name: optName, + required: true, + schema: parsedSchema, + }); + i += 2; + } else if (name.includes(':')) { const [optName, typeStr] = name.split(':').map(s => s.trim()); const parsedSchema = defineSchema(typeStr); schema.options.push({ @@ -347,23 +363,12 @@ export function parseCommandSchema(schemaStr: string): CommandSchema { }); i++; } else if (nextToken && nextToken.startsWith('<') && nextToken.endsWith('>')) { - // 旧语法:--opt - const valueToken = nextToken; - const typeStr = valueToken.slice(1, -1); - let parsedSchema: ParsedSchema | undefined; - try { - parsedSchema = defineSchema(typeStr); - } catch { - // 不是有效的 schema - } schema.options.push({ name, required: true, - schema: parsedSchema, }); i += 2; } else { - // 否则是标志 schema.flags.push({ name }); i++; } @@ -372,8 +377,19 @@ export function parseCommandSchema(schemaStr: string): CommandSchema { const short = token.slice(1); const nextToken = tokens[i + 1]; - // 检查是否有类型定义 - if (short.includes(':')) { + if (short.endsWith(':')) { + const optName = short.slice(0, -1).trim(); + const nextPart = tokens[i + 1]; + const typeStr = nextPart || ''; + const parsedSchema = defineSchema(typeStr); + schema.options.push({ + name: optName, + short: optName, + required: true, + schema: parsedSchema, + }); + i += 2; + } else if (short.includes(':')) { const [optName, typeStr] = short.split(':').map(s => s.trim()); const parsedSchema = defineSchema(typeStr); schema.options.push({ @@ -384,24 +400,13 @@ export function parseCommandSchema(schemaStr: string): CommandSchema { }); i++; } else if (nextToken && nextToken.startsWith('<') && nextToken.endsWith('>')) { - // 旧语法 - const valueToken = nextToken; - const typeStr = valueToken.slice(1, -1); - let parsedSchema: ParsedSchema | undefined; - try { - parsedSchema = defineSchema(typeStr); - } catch { - // 不是有效的 schema - } schema.options.push({ name: short, short, required: true, - schema: parsedSchema, }); i += 2; } else { - // 否则是标志 schema.flags.push({ name: short, short }); i++; }