diff --git a/package.json b/package.json index e90d6c5..6db6af9 100644 --- a/package.json +++ b/package.json @@ -42,5 +42,8 @@ "unbuild": "^1.1.2", "vitest": "^0.29.7" }, - "packageManager": "pnpm@7.30.5" + "packageManager": "pnpm@7.30.5", + "dependencies": { + "scule": "^1.0.0" + } } diff --git a/playground/commands/build.ts b/playground/commands/build.ts index a4043c4..0ce9543 100644 --- a/playground/commands/build.ts +++ b/playground/commands/build.ts @@ -21,7 +21,7 @@ export default defineCommand({ description: "disable hot module replacement", default: true, }, - dir: { + workDir: { type: "string", description: "working directory", required: true, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc1dd55..ed7cef3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,10 +9,14 @@ specifiers: eslint-config-unjs: ^0.1.0 jiti: ^1.18.2 prettier: ^2.8.7 + scule: ^1.0.0 typescript: ^4.9.5 unbuild: ^1.1.2 vitest: ^0.29.7 +dependencies: + scule: 1.0.0 + devDependencies: '@types/node': 18.15.10 '@vitest/coverage-c8': 0.29.7_vitest@0.29.7 @@ -3336,7 +3340,6 @@ packages: /scule/1.0.0: resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==} - dev: true /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} diff --git a/src/args.ts b/src/args.ts index 95542e7..ca9f4ec 100644 --- a/src/args.ts +++ b/src/args.ts @@ -1,3 +1,4 @@ +import { kebabCase, camelCase } from "scule"; import { parseRawArgs } from "./_parser"; import type { Arg, ArgsDef, ParsedArgs } from "./types"; import { CLIError, toArray } from "./_utils"; @@ -28,25 +29,31 @@ export function parseArgs(rawArgs: string[], argsDef: ArgsDef): ParsedArgs { const parsed = parseRawArgs(rawArgs, parseOptions); const [, ...positionalArguments] = parsed._; + const parsedArgsProxy = new Proxy(parsed, { + get(target: ParsedArgs, prop: string) { + return target[prop] ?? target[camelCase(prop)] ?? target[kebabCase(prop)]; + }, + }); + for (const [, arg] of args.entries()) { if (arg.type === "positional") { const nextPositionalArgument = positionalArguments.shift(); if (nextPositionalArgument !== undefined) { - parsed[arg.name] = nextPositionalArgument; + parsedArgsProxy[arg.name] = nextPositionalArgument; } else if (arg.default !== undefined) { - parsed[arg.name] = arg.default; + parsedArgsProxy[arg.name] = arg.default; } else { throw new CLIError( `Missing required positional argument: ${arg.name.toUpperCase()}`, "EARG" ); } - } else if (arg.required && parsed[arg.name] === undefined) { + } else if (arg.required && parsedArgsProxy[arg.name] === undefined) { throw new CLIError(`Missing required argument: --${arg.name}`, "EARG"); } } - return parsed; + return parsedArgsProxy; } export function resolveArgs(argsDef: ArgsDef): Arg[] {