Skip to content

Latest commit

 

History

History
463 lines (361 loc) · 13.9 KB

README.md

File metadata and controls

463 lines (361 loc) · 13.9 KB

A collection of general purpose check functions for yargs and Black Flag


Black Lives Matter! Last commit timestamp Codecov Source license Uses Semantic Release!

NPM version Monthly Downloads


@black-flag/checks

A collection of general purpose check functions for yargs and Black Flag.



Install

To install:

npm install @black-flag/checks

Usage

BFC provides the below functions, each of which can be plugged into Black Flag's (or Yargs's) check builder property.

checkArrayNoConflicts

⪢ API reference: checkArrayNoConflicts

Warning

A non-array type option will always fail this check regardless of the argument value.

This check passes when at most only one element from each conflict tuple is present in the array.

import { withBuilderExtensions } from '@black-flag/extensions';
import { checkArrayNoConflicts } from '@black-flag/checks';

export const name = 'my-command';

export const [builder, withHandlerExtensions] = withBuilderExtensions({
  x: {
    string: true,
    array: true,
    check: checkArrayNoConflicts('x', [
      ['1', '2'], // <-- one "conflict tuple"
      ['3', '4', '5'] // <-- another "conflict tuple"
    ])
  }
});

export const handler = withHandlerExtensions(async (argv) => {
  // ...
});
$ my-command            ✅
$ my-command -x         ✅
$ my-command -x 1       ✅
$ my-command -x 2       ✅
$ my-command -x 1 3 6   ✅

$ my-command -x 2 1     ❌
Array option "x" allows only one of the following values: 1, 2
$ my-command -x 2 4 0 5 ❌
Array option "x" allows only one of the following values: 3, 4, 5

checkArrayNotEmpty

⪢ API reference: checkArrayNotEmpty

Warning

A non-array type option will always fail this check regardless of the argument value.

This check passes when each member of an array-type argument is a non-empty non-nullish value and the array itself is non-empty.

import { withBuilderExtensions } from '@black-flag/extensions';
import { checkArrayNoConflicts } from '@black-flag/checks';

export const name = 'my-command';

export const [builder, withHandlerExtensions] = withBuilderExtensions({
  x: {
    string: true,
    array: true,
    check: checkArrayNotEmpty('x')
  }
});

export const handler = withHandlerExtensions(async (argv) => {
  // ...
});
$ my-command            ✅
$ my-command -x 1       ✅
$ my-command -x 2       ✅
$ my-command -x 1 3 6   ✅

$ my-command -x         ❌
Array option "x" requires at least one non-empty value
$ my-command -x ''      ❌
Array option "x" requires at least one non-empty value

checkArrayUnique

⪢ API reference: checkArrayUnique

Warning

A non-array type option will always fail this check regardless of the argument value.

This check passes when each element in the array is unique.

import { withBuilderExtensions } from '@black-flag/extensions';
import { checkArrayNoConflicts } from '@black-flag/checks';

export const name = 'my-command';

export const [builder, withHandlerExtensions] = withBuilderExtensions({
  x: {
    string: true,
    array: true,
    check: checkArrayUnique('x')
  }
});

export const handler = withHandlerExtensions(async (argv) => {
  // ...
});
$ my-command              ✅
$ my-command -x           ✅
$ my-command -x 1         ✅
$ my-command -x 2         ✅
$ my-command -x 1 3 6     ✅

$ my-command -x 1 1       ❌
Array option "x" must contain only unique values
$ my-command -x true true ❌
Array option "x" must contain only unique values

checkIsNotNegative

⪢ API reference: checkIsNotNegative

This check passes when an argument value is a non-negative number.

import { withBuilderExtensions } from '@black-flag/extensions';
import { checkArrayNoConflicts } from '@black-flag/checks';

export const name = 'my-command';

export const [builder, withHandlerExtensions] = withBuilderExtensions({
  x: {
    number: true,
    check: checkIsNotNegative('x')
  }
});

export const handler = withHandlerExtensions(async (argv) => {
  // ...
});
$ my-command              ✅
$ my-command -x           ✅
$ my-command -x 1         ✅
$ my-command -x 2         ✅
$ my-command -x 0         ✅

$ my-command -x -1        ❌
Array option "x" must have a non-negative value
$ my-command -x -5        ❌
Array option "x" must have a non-negative value

checkIsNotNil

⪢ API reference: checkIsNotNil

This check passes when an argument value is not falsy.

import { withBuilderExtensions } from '@black-flag/extensions';
import { checkArrayNoConflicts } from '@black-flag/checks';

export const name = 'my-command';

export const [builder, withHandlerExtensions] = withBuilderExtensions({
  x: {
    string: true,
    check: checkIsNotNil('x'),
    coerce(arg: string) {
      switch (arg) {
        case '0': {
          return 0;
        }

        case 'false': {
          return false;
        }

        case 'null': {
          return null;
        }

        case 'undefined': {
          return undefined;
        }
      }

      return arg;
    }
  }
});

export const handler = withHandlerExtensions(async (argv) => {
  // ...
});
$ my-command              ✅
$ my-command -x 1         ✅
$ my-command -x -1        ✅
$ my-command -x zero      ✅
$ my-command -x '!true'   ✅

$ my-command -x           ❌
Array option "x" must have a non-empty (non-falsy) value
$ my-command -x ''        ❌
Array option "x" must have a non-empty (non-falsy) value
$ my-command -x 0         ❌
Array option "x" must have a non-empty (non-falsy) value
$ my-command -x false     ❌
Array option "x" must have a non-empty (non-falsy) value
$ my-command -x null      ❌
Array option "x" must have a non-empty (non-falsy) value
$ my-command -x undefined ❌
Array option "x" must have a non-empty (non-falsy) value

Appendix

Further documentation can be found under docs/.

Published Package Details

This is a CJS2 package with statically-analyzable exports built by Babel for use in Node.js versions that are not end-of-life. For TypeScript users, this package supports both "Node10" and "Node16" module resolution strategies.

Expand details

That means both CJS2 (via require(...)) and ESM (via import { ... } from ... or await import(...)) source will load this package from the same entry points when using Node. This has several benefits, the foremost being: less code shipped/smaller package size, avoiding dual package hazard entirely, distributables are not packed/bundled/uglified, a drastically less complex build process, and CJS consumers aren't shafted.

Each entry point (i.e. ENTRY) in package.json's exports[ENTRY] object includes one or more export conditions. These entries may or may not include: an exports[ENTRY].types condition pointing to a type declaration file for TypeScript and IDEs, a exports[ENTRY].module condition pointing to (usually ESM) source for Webpack/Rollup, a exports[ENTRY].node and/or exports[ENTRY].default condition pointing to (usually CJS2) source for Node.js require/import and for browsers and other environments, and other conditions not enumerated here. Check the package.json file to see which export conditions are supported.

Note that, regardless of the { "type": "..." } specified in package.json, any JavaScript files written in ESM syntax (including distributables) will always have the .mjs extension. Note also that package.json may include the sideEffects key, which is almost always false for optimal tree shaking where appropriate.

License

See LICENSE.

Contributing and Support

New issues and pull requests are always welcome and greatly appreciated! 🤩 Just as well, you can star 🌟 this project to let me know you found it useful! ✊🏿 Or buy me a beer, I'd appreciate it. Thank you!

See CONTRIBUTING.md and SUPPORT.md for more information.

Contributors

See the table of contributors.