npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

aspargvs

v0.6.0

Published

Parse argv as json object

Downloads

5,846

Readme

aspargvs

lint status badge test status badge License: MIT npm

Parse argv as a json object.

Rather opinionated solution for when you need a CLI wrapper for a library package that accepts complex options object and you don't want to manually define and maintain CLI arguments mapping for all of that.


Goals / features

  • construct JSON of any complexity from CLI args

  • unambiguous (don't accept some ways to write args that may have different interpretations)

  • compact (provide ways to reduce redundancy for deeply nested structures)

Non-goals / out-of-scope

  • performance (it's CLI - it doesn't meant to be in the hot code path)

  • full JSON in arg values (what's the point? go full json then. putting keys inside values doesn't seem idiomatic for console args and it can be error-prone - would require too much attention to proper escaping - can't just copy and paste json from elsewhere)

  • explicit defaults (This intended to be a thin wrapper around a package with it's own defaults. Extra layer of defaults might be confusing. If you absolutely need it - you can merge the produced json with your default object in client code. There are also preset and file reading features for cases when multiple meaningful behaviors can be provided.)

Changelog

Available here: CHANGELOG.md

Install

> npm i aspargvs

Usage example

import { handleArgv } from 'aspargvs';

handleArgv({
  handlers: {
    json: businessLogic
  }
});

function businessLogic (optionsObject) {
  console.log('Business logic start.');
  console.log(JSON.stringify(optionsObject));
  console.log('Business logic end.');
}

Usage:

> node example.js --foo --bar.baz[] 3 4 5
Business logic start.
{"foo":true,"bar":{"baz":[3,4,5]}}
Business logic end.

Another example: example/example.mjs

Documentation

API

Command line arguments

> example [commands...] [keys and values...]

Built-in commands

Commands are only available when required conditions are met (this means specific handler is provided in most cases).

| Command | Alias | Argument | Description | --------- | ----- | -------------- | ----------- | json | -j | <file_name> | Merge given file contents with the parsed args object. | preset | -p | <preset_name> | Merge given preset into the parsed args object. | inspect | -i | | Pretty print the parsed args object. Useful as a dry run to check how arguments are parsed. | unparse | -u | | Print the parsed args object back as args string. Can be used to check what arguments produce the result equivalent to a given json file. Albeit it's pretty dumb at this point and can't use subkeys for example. | help | -h | | Print help message. | version | -v | | Print version number.

Note: short aliases cannot be merged.

Path syntax

| Syntax | Interpretation | ------------- | -------------- | foo | An object property key | foo.bar | Nested object property keys | [0] | Array index (Note: the root object is not an array, only subkeys can start from an index) | foo.[0] | 0-th item inside foo array | foo.[0].bar | bar property of an object that is a 0-th item inside foo array | foo[0] | The same as foo.[0] | foo.[_] | Next item in array, automatic index (value will be assigned to foo[foo.length])

Key syntax

| Syntax | Interpretation | ---------------------------- | -------------- | --<path> | Bare key, assigned a true value | --!<path> | Negation, assigned a false value | --<path>=<value> | Key with a value (see next table) | --<path>[] <value> <value> | Array key followed by bare values (see next table) | --<path>{} | Empty object (use subkeys or full paths to fill a non-empty object) | :<path> | Subkey (all above is the same except : prefix, but the path is nested in the last defined object or array that is not in a subkey. Subkeys recursion is not allowed.)

Value syntax

| Syntax | Interpretation | Notes | --------------- | -------------- | ----- | null | null | | true | true | | false | false | | 1.23e+4 | Number | | [<value>,...] | Array | Spaces are not allowed. If you quote the whole arg then any inner spaces will become part of values | {} | Empty object | Use separate args - full keys or subkeys to build a complex object | "null" | String | Beware - Node.js strips unescaped double quotes | 'true' | String | Beware - some shells may strip unescaped quotes | `false` | String | Beware - some shells may strip unescaped quotes | anything_else | String | Don't need quotes unless it is ambiguous

Some examples

| Syntax | Interpretation | | ----------------------------------- | -------------------------------------------- | | --foo.bar=1 --foo.baz=2 --foo.qux | { foo: { bar: 1, baz: 2, qux: true } } | | --foo{} :bar=1 :baz=2 :qux | { foo: { bar: 1, baz: 2, qux: true } } | | --foo.bar{} :baz.qux[_]=null | { foo: { bar: { baz: { qux: [null] } } } } | | --foo[0]=1 --foo[1]=2 --!foo[2] | { foo: [ 1, 2, false ] } | | --foo[] 1 2 false | { foo: [ 1, 2, false ] } | | --foo[] :[_]=1 :[_]=2 :![_] | { foo: [ 1, 2, false ] } | | --foo=[true] :![1] :[_][] :[_]{} | { foo: [ true, false, [], {} ] } | | --foo={} :bar{} :!baz | { foo: { bar: {}, baz: false } } | | --foo[] {} :bar {} :!baz | { foo: [ { bar: true }, { baz: false } ] } | | --foo[] [0] :[_]=1 [] :[_]=[2,3] | { foo: [ [0, 1], [[2, 3]] ] } |

Escape syntax

  • Escape syntax characters inside keys and inside arrays with "\";
  • Use quoted strings to escape syntax inside values;
  • Escape quote symbol inside quoted string with "\".

| Syntax | Interpretation | | ----------------- | -------------------- | | --foo\[0]=1 | { 'foo[0]': 1 } | | --foo\.bar=1 | { 'foo.bar': 1 } | | --foo\=1 | { 'foo=1': true } | | --\!foo | { '!foo': true } | | --foo=[a\]] | { foo: [ 'a]' ] } | | --foo=[a\,b] | { foo: [ 'a,b' ] } | | --foo=['a,b'] | { foo: [ 'a,b' ] } | | --foo='[a,b]' | { foo: '[a,b]' } | | --foo='true' | { foo: 'true' } |

Shell specifics

Node.js universal

Double quote (") characters are used to delimit arguments but removed before arguments get to the application. Therefore they can be placed anywhere to pass string values containing spaces.

But such bare double quotes can't help to escape something that can be taken as a grammar of this arg parser (such as "true" as a string). For that, string value has to be wrapped into escaped double quotes or different quotes.

PowerShell

PowerShell has special meaning for too many characters and also nontrivial escape rules.

  • All possible quotes are intercepted by PowerShell.

    I find the simplest way is to use a pair of backtick characters (``) to pass a single backtick.

    Escaped string would look like this: ``true``

    Backtick + single quote (`') would also work to pass a single quote, but it is just not as easy to type.

  • PowerShell has a special meaning for curly braces.

    Escape with backtick when defining an empty object: `{`}

Others

I'm not using anything else daily and can't provide any specific advice. Feel free to share your experience and findings by opening an issue.

Roadmap

Some things left for future updates:

  • Explore the possibility to support for output object type/schema - to return object of that type and generate detailed help;
  • unparse command - provide escaped strings ready for use in different shells;
  • unparse command - avoid string quotes when not needed;
  • Recursive subkeys with ::, :::, etc prefixes;
  • Explore the possibility to escape syntax inside values with \ to reduce the need for quoted strings;
  • ...

Somewhat related packages