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 🙏

© 2026 – Pkg Stats / Ryan Hefner

custom-permutation

v1.2.0

Published

Permutation generator with custom options.

Readme

Custom Permutation Generator

1. Usage

1.1. require

const CustomPermutation = require('custom-permutation').default;

1.2. import

import CustomPermutation from 'custom-permutation';

2. Constructor

new CustomPermutation(elList: T[], options?: {
  only?: { [index: number]: T[] },   // alias: oneOf
  never?: { [index: number]: T[] },  // alias: noneOf
  elementsOrderAbsolute?: number[],
  passFn?: (items: T[]) => boolean,
})

| Option | Meaning | | -------- | ----------------------------------------------------------- | | only | Position may only hold one of the given elements | | never | Position may never hold any of the given elements | | passFn | Extra filter; a permutation is kept only if it returns true |

2.1. Supported elements

  • Elements must be strings or numbers.
  • They are compared by their string form, so 1 and "1" count as the same element.

2.2. Errors

The constructor throws instead of generating anything when:

  • a rule targets a position outside the list (RangeError)
  • an element is not a string or number (TypeError)
  • the only / never rules of a position exclude every element
  • the rules can't all hold at once, e.g. { only: { 0: ['a'], 1: ['a'] } } with a single "a"

2.3. Deprecated

These still work, but use the new names instead:

| Deprecated | Use instead | | ------------------------------------------ | ----------------------------------- | | Positional (elList, choices, nonChoices) | Options (elList, { only, never }) | | choices option | only | | nonChoices option | never | | customPermGen field | engine |

3. Usage explained

Example:

new CustomPermutation(['a', 'b', 'c'], {
  only: { 1: ['a', 'b'] },
  never: { 0: ['a'] },
});

Permute the 3 items "a", "b" and "c" with the rules below.

only rule:

{ "1": ["a", "b"] }

At index=1 there can only be the item "a" or "b"

never rule:

{ "0": ["a"] }

At index=0 there can NOT be the item "a"

Note: indexes are 0 based: index=0, index=1, etc.

| index | all options | after customization | | :---: | :-----------------: | :-----------------: | | 0 | "a", "b", "c" | "b", "c" | | 1 | "a", "b", "c" | "a", "b" | | 2 | "a", "b", "c" | "a", "b", "c" |

4. Result set explanation

Let's check all permutations, and see which ones are and are not valid.

| Permutation | Violates | Description | | :---------------: | :------: | :------------------------------------: | | ["a", "b", "c"] | never | first can't be "a" | | ["a", "c", "b"] | never | first can't be "a" | | ["b", "a", "c"] | - | - | | ["b", "c", "a"] | only | second is asked to be "a" or "b" | | ["c", "a", "b"] | - | - | | ["c", "b", "a"] | - | - |

So only 3 results can be generated with these parameters.

5. Complete example

5.1. Create object from CustomPermutation class

let customPerm = new CustomPermutation(['a', 'b', 'c'], {
  only: { 1: ['a', 'b'] },
  never: { 0: ['a'] },
});

5.2. Get next value

5.2.1. With next

let next = customPerm.next();

while (next) {
  console.log(next);
  next = customPerm.next();
}

5.2.2. With generator

let generator = customPerm.generator();
let next = generator.next();

while (!next.done) {
  console.log(next.value);
  next = generator.next();
}

Output:

["b", "a", "c"]
["c", "a", "b"]
["c", "b", "a"]

6. Command line

The package also ships a custom-permutation command, so you can use it without writing code:

npx custom-permutation a b c --only 1=a,b --never 0=a
b a c
c a b
c b a

| Option | Alias | Description | | ------------------------- | ----------- | -------------------------------------------------- | | -o, --only <pos>=<a,b> | --one-of | Position pos may only hold the given elements | | -n, --never <pos>=<a,b> | --none-of | Position pos may never hold the given elements | | --limit <n> | | Stop after n permutations (the count grows fast) | | --format <fmt> | | lines (default), json (one array) or csv | | -h, --help | | Show usage | | --not <pos>=<a,b> | | Deprecated, use --never (prints a warning) |

Notes:

  • --only and --never are repeatable; rules for the same position are merged.
  • Elements are treated as strings on the command line.
  • The passFn filter is only available from code.
  • Impossible rules print the reason and exit with code 1.

Python version of the tool

This is the python version of custom-permutation on PyPi.

Changelog

2.0.0 (20.10.2026)

Breaking

  • Elements must be strings or numbers, compared by string value.
  • Impossible rules now throw instead of silently generating permutations.

Added

  • Options object constructor: new CustomPermutation(list, { only, never, elementsOrderAbsolute, passFn })
  • oneOf / noneOf as aliases of only / never.
  • CLI: -o, --only and -n, --never, with --one-of / --none-of aliases.

Fixed

  • never was ignored when only targeted the same position.
  • Numeric rule values were mistaken for positions.
  • Rule objects passed in were mutated.
  • Distinct permutations could be merged by JSON-based de-duplication.
  • CLI rejects a non-integer --limit and empty rule elements.
  • The require example in this README.

Renamed public fields (old names still work as deprecated aliases)

| Old | New | | --------------------------------- | ---------------------------------- | | customPermGen | engine | | engine.set | engine.uniqueElements | | engine.permutationGenOfSet | engine.indexPermutationGenerator | | engine.nextIndexList | engine.currentIndexes | | engine.finalChoicesByIndexInSet | engine.allowedIndexesByPosition | | engine.historyHashes | engine.historyKeys |

Deprecated

  • The positional constructor and the choices / nonChoices options.
  • The --not CLI flag.

Earlier

  • 02.10.2026 - Added the custom-permutation command line tool.
  • 11.06.2026 - Better typing implemented and more test coverage added.
  • 23.09.2024 - Edge cases are handled and the codespace is simplified.
  • 25.09.2023 - unChoices did not reflect always, fixed now.