@jondotsoy/flags
Version:
A Javascript arguments processor
141 lines • 11.2 kB
JavaScript
import { UnexpectedArgumentError } from "./errors/UnexpectedArgumentError.js";
import { helpMessage } from "./utils/help-message.js";
// NewFlagsParser implementation
export class FlagsParser {
schema;
metadata;
constructor(schema, metadata = {
program: "cli",
}) {
this.schema = schema;
this.metadata = metadata;
}
program(name) {
return new FlagsParser(this.schema, {
...this.metadata,
program: name,
});
}
describe(description) {
return new FlagsParser(this.schema, {
...this.metadata,
description,
});
}
version(version) {
return new FlagsParser(this.schema, {
...this.metadata,
version,
});
}
combineShortFlags() {
return new FlagsParser(this.schema, {
...this.metadata,
combineShortFlags: true,
});
}
helpMessage = (options) => helpMessage(this, this.schema, options);
parse(args) {
// Expand combined short flags if option is enabled
const expandedArgs = this.metadata.combineShortFlags
? this.expandCombinedShortFlags(args)
: args;
const result = {};
const usedIndices = new Set();
// Initialize result with initial values from each builder's spec
for (const [key, builder] of Object.entries(this.schema)) {
result[key] = builder.spec.getInitial();
}
// Try to parse each flag in the schema
for (const [key, builder] of Object.entries(this.schema)) {
let parsedValue = null;
let currentValue = undefined;
// Try to parse at each index in expandedArgs
for (let i = 0; i < expandedArgs.length; i++) {
if (usedIndices.has(i))
continue;
const parseResult = builder.parse(i, expandedArgs, currentValue !== undefined ? { current: currentValue } : undefined);
if (parseResult !== null) {
// Mark consumed indices as used
const consumedCount = parseResult.args.length;
for (let j = 0; j < consumedCount; j++) {
usedIndices.add(i + j);
}
parsedValue = parseResult.value;
currentValue = parseResult.value;
// If there's an accumulate function, continue looking for more matches
if (!builder.spec.getAccumulate()) {
break;
}
}
}
// Set the result: use parsed value if found
if (parsedValue !== null) {
result[key] = parsedValue;
}
}
// Check for unrecognized arguments
for (let i = 0; i < expandedArgs.length; i++) {
if (!usedIndices.has(i)) {
throw new UnexpectedArgumentError(expandedArgs[i]);
}
}
return result;
}
formatError(error) {
const message = error instanceof Error ? error.message : String(error);
return `${message}\n\nRun '${this.metadata.program} --help' for more information\n`;
}
safeParse(args) {
try {
const output = this.parse(args);
return [true, undefined, output];
}
catch (error) {
return [false, error, undefined];
}
}
expandCombinedShortFlags(args) {
const expanded = [];
// Collect all short flag aliases from the schema
const shortFlags = new Set();
for (const builder of Object.values(this.schema)) {
if (builder.spec.hasMetadata("matches")) {
const matches = builder.spec.getMetadata("matches");
for (const match of matches) {
// Short flags are single dash followed by single character
if (match.startsWith("-") &&
!match.startsWith("--") &&
match.length === 2) {
shortFlags.add(match[1]); // Store just the character
}
}
}
}
for (const arg of args) {
// Check if this looks like combined short flags: starts with single dash,
// not followed by another dash, and has multiple characters
if (arg.startsWith("-") &&
!arg.startsWith("--") &&
arg.length > 2 &&
!arg.includes("=")) {
// Check if all characters after the dash are valid short flags
const chars = arg.slice(1);
const allAreShortFlags = chars
.split("")
.every((c) => shortFlags.has(c));
if (allAreShortFlags) {
// Expand into individual flags
for (const char of chars) {
expanded.push(`-${char}`);
}
continue;
}
}
// Not a combined short flag, keep as is
expanded.push(arg);
}
return expanded;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxhZ3NQYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvRmxhZ3NQYXJzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDOUUsT0FBTyxFQUFFLFdBQVcsRUFBMkIsTUFBTSx5QkFBeUIsQ0FBQztBQVUvRSxnQ0FBZ0M7QUFFaEMsTUFBTSxPQUFPLFdBQVc7SUFFWjtJQUNDO0lBRlgsWUFDVSxNQUFTLEVBQ1IsV0FLTDtRQUNGLE9BQU8sRUFBRSxLQUFLO0tBQ2Y7UUFSTyxXQUFNLEdBQU4sTUFBTSxDQUFHO1FBQ1IsYUFBUSxHQUFSLFFBQVEsQ0FPaEI7SUFDQSxDQUFDO0lBRUosT0FBTyxDQUFDLElBQVk7UUFDbEIsT0FBTyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2xDLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDaEIsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUSxDQUFDLFdBQW1CO1FBQzFCLE9BQU8sSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNsQyxHQUFHLElBQUksQ0FBQyxRQUFRO1lBQ2hCLFdBQVc7U0FDWixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTyxDQUFDLE9BQWU7UUFDckIsT0FBTyxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2xDLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDaEIsT0FBTztTQUNSLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxpQkFBaUI7UUFDZixPQUFPLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDbEMsR0FBRyxJQUFJLENBQUMsUUFBUTtZQUNoQixpQkFBaUIsRUFBRSxJQUFJO1NBQ3hCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxXQUFXLEdBQUcs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