memorable-moniker

Name generator with some in-built dictionaries and presets.

Usage no npm install needed!

<script type="module">
  import memorableMoniker from 'https://cdn.skypack.dev/memorable-moniker';
</script>

README

memorable-moniker

Name generator with some in-built dictionaries and presets.

Node CI codecov npm version

Documentation

Installation

npm install memorable-moniker

or

yarn add memorable-moniker

Usage

The package exports some pre-defined name generators, which have a .modify(...) function for customisation. The pre-defined generators are nicknames, people, women and men. They are exposed as named exports, e.g.:

import {nicknames} from 'memorable-moniker'

// get a random nickname:
nicknames.next()

There are a few predefined name generators, which are exposed as named exports. Basic usage example, with sample outputs as comments:

import {nicknames, women, men, people} from 'memorable-moniker'

nicknames.next()  // dynamic-capybara
women.next()      // Dani Snowden
men.next()        // Stanley Coronado
people.next()     // Javion Farrar

nicknames

The easiest way to get a name-generator is to import the nicknames generator and customise it as necessary. The .modify(...) method returns a new instance of a generator which extends the original. It receives a partial dictionary of parameters, or a function which returns one - the function receives the parent's configuration as an input. Parameters that can be modified:

dictionaries -- A list of "dictionaries" that words should be chosen from. These can be one of the preset values ('animal', 'femaleName', 'maleName', 'lastName', 'positiveAdjective'), or an object with a property called words which should be an array of strings. It's also possible to pass a list of dictionaries, in the same format. Some examples:

Example
const animalGenerator = nicknames.modify({
  dictionaries: ['animal']
})
const formalAnimalGenerator = nicknames.modify({
  dictionaries: ['animal', 'lastName']
})
const veryFormalAnimalGenerator = nicknames.modify({
  dictionaries: [{words: ['Mr', 'Ms', 'Mrs']}, 'animal', 'lastName']
})

rng -- A random-number generator. A function that should return a value between 0 and 1. The lower bound should be inclusive and the upper bound exclusive. As a convenience, the default random-number generator has an rng.seed('...') function to allow getting a seeded rng based on the original. Usage:

Example
const myNameGenerator = nicknames.modify(params => ({ rng: params.rng.seed('my-seed-value') }))
console.log(myNameGenerator.next()) // always returns the same value

format -- A function which transforms dictionary words before returning them from the generator. For example, you could convert from kebab-case to snake_case with:

Example
const myGenerator = nicknames.modify({
  format: word => word.replace(/-/g, '_')
})

choose -- A function which receives a list of words, and a random-number generator function, and should return a single word. Typically this wouldn't need to be modified.

join -- A function which receives one word from each dictionary, and is responsible for joining them into a single value. Usually the return value is a string, but if another format is returned the type will be correctly inferred.

Example
const informalPeople = nicknames.modify({
  dictionaries: [['maleName', 'femaleName'], 'lastName']
  join: (firstName, lastName) => `${firstName} ${lastName}`,
})
const formalPeople = nicknames.modify({
  dictionaries: [['maleName', 'femaleName'], 'lastName']
  join: (firstName, lastName) => `${lastName}, ${firstName}`,
})
const structuredPeople = nicknames.modify({
  dictionaries: [['maleName', 'femaleName'], 'lastName']
  join: (firstName, lastName) => ({ name: { first: firstName, last: lastName } }),
})

Some usage examples of the .modify function tweaking generator behavior:

Nicknames/handles:

const generator = nicknames.modify(params => ({
  rng: params.rng.seed('nicknames'),
}))
const samples = range(0, 15).map(() => generator.next())
expect(samples).toMatchInlineSnapshot(`
  Array [
    "excited-goose",
    "emphatic-sardine",
    "energetic-mosquito",
    "delightful-dogfish",
    "merry-hawk",
    "praiseworthy-falcon",
    "amiable-curlew",
    "vigorous-pony",
    "fabulous-elk",
    "cheery-cockroach",
    "respectable-herring",
    "comfortable-tamarin",
    "sincere-rabbit",
    "kind-marmoset",
    "extraordinary-pony",
  ]
`)

Women's names:

const generator = women.modify(params => ({
  rng: params.rng.seed('women'),
}))
const samples = range(0, 15).map(generator.next).join('\n')
expect(samples).toMatchInlineSnapshot(`
  "Blair Brower
  Mae Carrasco
  Ellis Huntley
  Erika Thurston
  Jayleen Grantham
  Harleigh Dent
  Jazlyn Lawler
  Cecelia Lipscomb
  Noa Durant
  Claudia Orourke
  Kyleigh Shah
  Dorothy Baer
  Adrianna Hirsch
  Kaydence Reardon
  Paulina Hudgins"
`)

Men's names:

const generator = men.modify(params => ({
  rng: params.rng.seed('men'),
}))
const samples = range(0, 15).map(generator.next).join('\n')
expect(samples).toMatchInlineSnapshot(`
  "Willie Schuler
  Vihaan Trahan
  Koa Aiken
  Maddux Thurston
  Taylor Farnsworth
  Dax Pruett
  Alijah Lombardo
  Keagan Heck
  Kabir Burnham
  Judson Redding
  Koda Wakefield
  Keenan Pruett
  Kamden Burdick
  Jaxxon Mixon
  Orlando Smalls"
`)

Women's and men's names:

const generator = people.modify(params => ({
  rng: params.rng.seed('people'),
}))
const samples = range(0, 15).map(generator.next).join('\n')
expect(samples).toMatchInlineSnapshot(`
  "Legacy Couture
  Baylor Tinsley
  Opal Huston
  Ayaan Whatley
  Joe Montanez
  Haylee Satterfield
  Marcellus Fugate
  Nathalie Reagan
  Oaklyn Merchant
  Kaelyn Thrasher
  Raul Caruso
  Lee Trahan
  Ryann Murry
  Uriel Greco
  Lucian Barksdale"
`)

Custom combination of built-in dictionaries:

const doubleBarreledNames = people.modify(params => ({
  rng: params.rng.seed('double-barreled'),
  dictionaries: [['femaleName', 'maleName'], 'lastName', 'lastName'],
  join: parts => `${parts[0]} ${parts[1]}-${parts[2]}`,
}))
const samples = range(0, 15).map(doubleBarreledNames.next).join('\n')
expect(samples).toMatchInlineSnapshot(`
  "Tiana Denson-Dozier
  Leighton Escobedo-Ulrich
  Colson Saucedo-Shockley
  Monica Holton-Rooney
  Tristian Lyle-Huang
  Saint Monahan-Naylor
  Justus Boles-Gatlin
  Tristen Whatley-Schaeffer
  Royal Zepeda-Alonzo
  Kyleigh Satterfield-Jansen
  Dorothy Schwab-Ponder
  Addisyn Wilburn-Patten
  Yehuda Jacques-Joy
  Emory Beebe-Squires
  Esteban Mize-Barney"
`)

Use a custom dictionary:

const generator = nicknames.modify(params => ({
  rng: params.rng.seed('coin'),
  dictionaries: [{words: ['heads', 'tails']}],
}))
const samples = range(0, 15).map(generator.next).join('\n')
expect(samples).toMatchInlineSnapshot(`
  "heads
  tails
  heads
  heads
  heads
  heads
  heads
  heads
  heads
  tails
  tails
  heads
  tails
  tails
  heads"
`)

Use a custom random number generator:

const generator = nicknames.modify(() => ({
  rng: () => 0,
  dictionaries: [{words: ['heads', 'tails']}],
}))
const samples = range(0, 15).map(generator.next)
expect(samples).toEqual(range(0, 15).map(() => 'heads'))

Use a custom formatter to complex outputs:

const generator = nicknames.modify(params => ({
  rng: params.rng.seed('animals'),
  format: word => params.format(word).replace(/-/g, '_'),
  join: parts => ({joined: parts.join('.'), parts}),
}))
const result = generator.next()
expectTypeOf(result).toEqualTypeOf<{joined: string; parts: string[]}>()
expect(result).toMatchInlineSnapshot(`
  Object {
    "joined": "superb.caracal",
    "parts": Array [
      "superb",
      "caracal",
    ],
  }
`)

full families:

const generator = people.modify(params => {
  const rng = params.rng.seed('families')
  return {
    rng,
    dictionaries: ['lastName', 'lastName'],
    join: ([primaryLastName, secondaryLastName]) => {
      const size = 1 + Math.floor(rng() * 6)
      const firstNameGenerator = people.modify(params => ({
        rng: params.rng.seed(primaryLastName + secondaryLastName),
        dictionaries: [['femaleName', 'maleName']],
      }))
      expectTypeOf(firstNameGenerator.next).returns.not.toBeUnknown()
      expectTypeOf(firstNameGenerator.next).returns.toBeString()
      const primary = `${firstNameGenerator.next()} ${primaryLastName}`
      const secondary = `${firstNameGenerator.next()} ${rng() < 0.5 ? primaryLastName : secondaryLastName}`
      const kidNames = range(0, size).map(() => `${firstNameGenerator.next()} ${primaryLastName}`)
      return [primary, secondary, ...kidNames].slice(0, size)
    },
  }
})
const samples = range(0, 15).map(generator.next)
expect(samples).toMatchInlineSnapshot(`
  Array [
    Array [
      "Jenna Nesbitt",
      "Khalid Trimble",
      "Uriah Nesbitt",
      "Bianca Nesbitt",
      "Sutton Nesbitt",
    ],
    Array [
      "Kyleigh Corey",
      "Camilo Corey",
      "Braelynn Corey",
      "Adele Corey",
      "Monica Corey",
    ],
    Array [
      "Zaid Chester",
      "Kendall Layton",
      "Carmelo Chester",
      "Carl Chester",
    ],
    Array [
      "Kiana Etheridge",
      "Jaxtyn Beavers",
      "Amayah Etheridge",
      "Johanna Etheridge",
      "Harvey Etheridge",
    ],
    Array [
      "Yehuda Schuster",
      "Kyla Bowser",
      "Oakley Schuster",
    ],
    Array [
      "Miller Spain",
      "Ailani Boyles",
      "Rayna Spain",
    ],
    Array [
      "Kallie Monk",
      "Ignacio Adamson",
      "Kadence Monk",
    ],
    Array [
      "Karsyn Paris",
      "Zakai Paris",
    ],
    Array [
      "Conrad Levin",
      "Emmie Levin",
      "Kataleya Levin",
      "Kashton Levin",
      "Hugh Levin",
      "Alaric Levin",
    ],
    Array [
      "Rosalee Regan",
      "Zev Okeefe",
      "Esme Regan",
      "Zainab Regan",
    ],
    Array [
      "Milan Unger",
      "Raven Unger",
      "Miracle Unger",
      "Nataly Unger",
    ],
    Array [
      "Esmeralda Alonso",
    ],
    Array [
      "Michaela Wing",
      "Anne Wing",
    ],
    Array [
      "Aliza Radford",
      "Harleigh Fagan",
      "Lian Radford",
    ],
    Array [
      "Van Gannon",
      "Zaylee Ryder",
      "Leona Gannon",
      "Adrien Gannon",
      "Davion Gannon",
    ],
  ]
`)