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

memorable-moniker

v0.5.1

Published

Name generator with some in-built dictionaries and presets.

Downloads

30

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",
    ],
  ]
`)