Easy to use argument parser
Go to file
ever f5f5d6fe55 v0.2.1 2023-09-17 21:32:46 +02:00
src Simplified undefined checks 2023-09-16 12:56:52 +02:00
.gitignore Initial commit 2023-07-17 18:41:50 +02:00
.markdownlint.json Added readme 2023-07-17 18:56:24 +02:00
LICENSE Relicensed to BSD 3-Clause 2023-09-16 12:17:36 +02:00
README.md Corrected where positionals are specified in readme 2023-09-16 12:28:57 +02:00
package.json v0.2.1 2023-09-17 21:32:46 +02:00
pnpm-lock.yaml Initial commit 2023-07-17 18:41:50 +02:00
tsconfig.json Added browser compatibility 2023-07-19 15:57:27 +02:00

README.md

getargs - Easy to use argument parser

Features

  • Positional Argument Parsing
  • Simple Interface
  • Works in browsers and Node.js
  • TypeScript support (parsed arguments are also typed)
  • ECMAScript module imports

Installation

Node.js

npm install @brokenms/getargs
pnpm add @brokenms/getargs
yarn add @brokenms/getargs

Importing the package

In Node.js

import getargs from '@brokenms/getargs';

In the browser

With bundler

import getargs from '@brokenms/getargs/browser';

Without bundler

import getargs from '<package_root>/bin/browser.js';

Usage

Arguments are parsed by calling getargs().

Names of short options will be prefixed with an underscore "_" in the returned object and names of positionals will be prefixed with a dollar sign "$".

Hyphens will be replaced by underscores in all names.

For example:

// object returned by getargs()
{
	'_s':       /* ... */, // short option "-s"
	'long_opt': /* ... */, // long option "--long-opt" or "--long_opt"
	'$pos':     /* ... */, // positional "pos"
}

The first argument of getargs() is the array of arguments to be parsed (string array).

For Node.js:

process.argv.slice(2)

For Electron:

process.argv.slice(1)

The second argument of getargs() is the parser configuration, where - among other things - options and positionals are defined. It looks like this:

interface {
	options                ?: {/* ... */},
	positionals            ?: [/* ... */],
	required_positional_num?: number,
	use_exceptions         ?: boolean, // Whether to throw exceptions on errors when parsing. If undefined or false, exit on error. [Node.js only; exceptions are the only supported method in the browser]
}

Options/Flags

import getargs from '@brokenms/getargs';

const args = getargs(process.argv.slice(2), {
	options: {
		'-f': {
			type: 'boolean', // flag (doesn't take an argument; true when "-f" is passed to the program)
		},
		'--long-opt': {
			type: 'string', // takes an argument as it's value
		},
		'-l': '--long-opt', // alias; passing "-l" to the program is the same as passing "--long-opt"
	},
});

console.log(args);

Syntax

The syntax for the command will look like this:

node program.js [-f] [-l/--long-opt string]

Results

When executing without arguments, args will look like this:

{ _f: false }

When passing "-f --long-opt foobar", it will look like this:

{ _f: true, long_opt: 'foobar' }

Positionals

Positionals are (like options) also specified in the parser configuration:

import getargs from '@brokenms/getargs';

const args = getargs(process.argv.slice(2), {
	positionals: [
		{
			name: 'pos',
			type: 'number',
			// repeat is implicitly false
		},
		{
			name: 'repeated',
			type: 'string',
			repeat: true, // This means that the value of "repeated" will be an array of all arguments after the "pos" argument. Note that this only works for the last argument.
		},
	],
	required_positional_num: 2, // This specifies how many positional arguments are required. Setting this number to 1 would mean that the "pos" argument is required, but the "repeated" argument is optional. Setting it to 0 or omitting it will make all positional arguments optional.
});

console.log(args);

Syntax

node program.js pos repeated...

Results

node program.js 123 foo bar
{ '$repeated': [ 'foo', 'bar' ], '$pos': 123 }

Calling without arguments will fail.

Example

import * as fs from 'fs';
import * as process from 'process';

import getargs from '@brokenms/getargs';

const args = getargs(process.argv.slice(2), {
	options: {
		'--dry-run': {
			type: 'boolean',
		},
		'-n': '--dry-run',
	},
	positionals: [
		{
			name: 'action',
			type: 'string',
		},
		{
			name: 'files',
			type: 'string',
			repeat: true,
		},
	],
	required_positional_num: 2,
});

console.log(args);

switch (args.$action) {
case 'hide':
	for (const file of args.$files) {
		if (args.dry_run) {
			console.log('hide:', file);
		} else {
			fs.renameSync(file, '.' + file);
		}
	}
	console.log(`${args.$files.length} file(s) hidden!`);
	break;
default:
	console.error(`Error: Unknown action "${args.$action}"!`);
	process.exit(1);
}

With the below command, the program is instructed to simulate it's behavior, which would normally be to hide the files named foo and bar.

node program.js -n hide foo bar

This is the content of the args variable:

{ dry_run: true, '$files': [ 'foo', 'bar' ], '$action': 'hide' }

The program will print this text:

hide: foo
hide: bar
2 file(s) hidden!

Reference

Argument Types

The following values are available for the type field on options, flags and positionals:

Value Description
'float' Same as 'number' but parse via Number.parseFloat().
'number' The argument is parsed as a number via Number.parseInt() and triggers an error if it is not a valid number.
'string' The argument is not modified.

Additionally, options can be of type 'boolean', which makes them flags.

License

© Broken Mouse Studios 2023
https://brokenmouse.studio

This software and it's accompanying files are licensed under the BSD 3-Clause License.

For the license's contents, see LICENSE.

By submitting patches or merge/pull requests, you grant Broken Mouse Studios the permission to use, copy, modify, distribute, publish and/or relicense the contributions you have made to the project.