namejam 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # namejam
2
+
3
+ Generate funny, unique usernames.
4
+
5
+ ```
6
+ spooky-gremlin
7
+ caffeinated-axolotl
8
+ lurking-zephon
9
+ flummoxed-mothman
10
+ ```
11
+
12
+ ## Install
13
+
14
+ ```sh
15
+ npm install namejam
16
+ # or
17
+ yarn add namejam
18
+ ```
19
+
20
+ Requires Node.js ≥ 22.6.0.
21
+
22
+ ## Library
23
+
24
+ ```ts
25
+ import { generateName } from "namejam";
26
+
27
+ generateName();
28
+ // "chaotic-raccoon"
29
+
30
+ generateName({ style: "adj-adj-noun", casing: "pascal" });
31
+ // "UnhingedCursedGoblin"
32
+
33
+ generateName({ style: "adj-tech", casing: "camel", suffix: 4 });
34
+ // "bewilderedNexon8312"
35
+
36
+ generateName({ style: "verb-noun", separator: "_", casing: "uppercase" });
37
+ // "LURKING_WENDIGO"
38
+ ```
39
+
40
+ ### `generateName(options?)`
41
+
42
+ Returns a `string`.
43
+
44
+ | Option | Type | Default | Description |
45
+ |--------|------|---------|-------------|
46
+ | `style` | `Style` | `"adj-noun"` | Word pattern |
47
+ | `separator` | `string` | `"-"` | String placed between words |
48
+ | `casing` | `Casing` | `"lowercase"` | Casing applied to the result |
49
+ | `suffix` | `number` | — | Append N random digits |
50
+
51
+ ### Styles
52
+
53
+ | Style | Example |
54
+ |-------|---------|
55
+ | `adj-noun` | `spooky-gremlin` |
56
+ | `adj-adj-noun` | `cursed-feral-raccoon` |
57
+ | `verb-noun` | `haunting-wombat` |
58
+ | `noun-noun` | `pickle-warlock` |
59
+ | `adj-tech` | `chaotic-nexon` |
60
+ | `tech` | `zephon` |
61
+
62
+ ### Casings
63
+
64
+ | Casing | Example |
65
+ |--------|---------|
66
+ | `lowercase` | `spooky-gremlin` |
67
+ | `uppercase` | `SPOOKY-GREMLIN` |
68
+ | `title` | `Spooky-Gremlin` |
69
+ | `pascal` | `SpookyGremlin` |
70
+ | `camel` | `spookyGremlin` |
71
+
72
+ > For `pascal` and `camel`, `separator` is ignored — words are concatenated directly.
73
+
74
+ ## CLI
75
+
76
+ ```sh
77
+ npx namejam
78
+ npx namejam --style adj-adj-noun --casing pascal --count 5
79
+ npx namejam --style verb-noun --separator _ --suffix 4
80
+ npx namejam --style tech --count 10
81
+ ```
82
+
83
+ ```
84
+ Usage: namejam [options]
85
+
86
+ --style <style> adj-noun | adj-adj-noun | verb-noun | noun-noun | adj-tech | tech
87
+ --separator <sep> Word separator string (default: -)
88
+ --casing <casing> lowercase | uppercase | camel | pascal | title (default: lowercase)
89
+ --suffix <digits> Append N random digits
90
+ --count <n> Print N names, one per line (default: 1)
91
+ -h, --help Show help
92
+ -v, --version Show version
93
+ ```
94
+
95
+ ## License
96
+
97
+ MIT
package/dist/cli.js ADDED
@@ -0,0 +1,419 @@
1
+ #!/usr/bin/env -S node --strip-types
2
+ //#region src/words/adjectives.ts
3
+ const adjectives = [
4
+ "Accursed",
5
+ "Arcane",
6
+ "Befuddled",
7
+ "Bewildered",
8
+ "Blursed",
9
+ "Bogus",
10
+ "Caffeinated",
11
+ "Chaotic",
12
+ "Chunky",
13
+ "Cracked",
14
+ "Crunchy",
15
+ "Cryptic",
16
+ "Cursed",
17
+ "Damp",
18
+ "Deranged",
19
+ "Disheveled",
20
+ "Doomed",
21
+ "Elusive",
22
+ "Ethereal",
23
+ "Feral",
24
+ "Flummoxed",
25
+ "Flustered",
26
+ "Forbidden",
27
+ "Frantic",
28
+ "Furious",
29
+ "Glitchy",
30
+ "Gobsmacked",
31
+ "Goofy",
32
+ "Grumpy",
33
+ "Hapless",
34
+ "Haunted",
35
+ "Hollering",
36
+ "Invisible",
37
+ "Irate",
38
+ "Janky",
39
+ "Jittery",
40
+ "Klutzy",
41
+ "Lanky",
42
+ "Listless",
43
+ "Luminous",
44
+ "Lurking",
45
+ "Majestic",
46
+ "Maniacal",
47
+ "Manic",
48
+ "Mystical",
49
+ "Nefarious",
50
+ "Nervy",
51
+ "Notorious",
52
+ "Oblivious",
53
+ "Ominous",
54
+ "Ornery",
55
+ "Panicked",
56
+ "Peculiar",
57
+ "Phantom",
58
+ "Plucky",
59
+ "Prickly",
60
+ "Querulous",
61
+ "Rabid",
62
+ "Rambling",
63
+ "Reckless",
64
+ "Restless",
65
+ "Rogue",
66
+ "Scruffy",
67
+ "Smol",
68
+ "Sneaky",
69
+ "Snarky",
70
+ "Soggy",
71
+ "Spicy",
72
+ "Spooky",
73
+ "Suspicious",
74
+ "Tangled",
75
+ "Thunderous",
76
+ "Turbulent",
77
+ "Uncanny",
78
+ "Unhinged",
79
+ "Vexed",
80
+ "Volatile",
81
+ "Wacky",
82
+ "Wobbly",
83
+ "Zealous"
84
+ ];
85
+ //#endregion
86
+ //#region src/words/nouns.ts
87
+ const nouns = [
88
+ "Armadillo",
89
+ "Axolotl",
90
+ "Banshee",
91
+ "Basilisk",
92
+ "Blobfish",
93
+ "Boggart",
94
+ "Capybara",
95
+ "Chimera",
96
+ "Coyote",
97
+ "Cryptid",
98
+ "Ferret",
99
+ "Fetch",
100
+ "Flamingo",
101
+ "Gargoyle",
102
+ "Gecko",
103
+ "Goblin",
104
+ "Gremlin",
105
+ "Hedgehog",
106
+ "Imp",
107
+ "Jackalope",
108
+ "Kelpie",
109
+ "Kraken",
110
+ "Lemur",
111
+ "Mantis",
112
+ "Mongoose",
113
+ "Mothman",
114
+ "Narwhal",
115
+ "Okapi",
116
+ "Opossum",
117
+ "Pangolin",
118
+ "Penguin",
119
+ "Platypus",
120
+ "Poltergeist",
121
+ "Porcupine",
122
+ "Quokka",
123
+ "Raccoon",
124
+ "Revenant",
125
+ "Salamander",
126
+ "Specter",
127
+ "Tapir",
128
+ "Tardigrade",
129
+ "Thunderbird",
130
+ "Toad",
131
+ "Vulture",
132
+ "Walrus",
133
+ "Wendigo",
134
+ "Wombat",
135
+ "Wraith",
136
+ "Wyrm",
137
+ "Yak",
138
+ "Anomaly",
139
+ "Artifact",
140
+ "Bandit",
141
+ "Bauble",
142
+ "Biscuit",
143
+ "Blender",
144
+ "Burrito",
145
+ "Carbuncle",
146
+ "Cassette",
147
+ "Cauldron",
148
+ "Chalice",
149
+ "Cipher",
150
+ "Cloak",
151
+ "Contraption",
152
+ "Doohickey",
153
+ "Dumpling",
154
+ "Enigma",
155
+ "Fiasco",
156
+ "Gizmo",
157
+ "Grimoire",
158
+ "Harbinger",
159
+ "Lantern",
160
+ "Maverick",
161
+ "Menace",
162
+ "Monocle",
163
+ "Muffin",
164
+ "Noodle",
165
+ "Paradox",
166
+ "Parchment",
167
+ "Pickle",
168
+ "Pretzel",
169
+ "Relic",
170
+ "Rogue",
171
+ "Ruckus",
172
+ "Scroll",
173
+ "Sigil",
174
+ "Spatula",
175
+ "Talisman",
176
+ "Thingamajig",
177
+ "Toaster",
178
+ "Vagrant",
179
+ "Waffle",
180
+ "Warlock",
181
+ "Widget",
182
+ "Wizard"
183
+ ];
184
+ //#endregion
185
+ //#region src/words/tech.ts
186
+ const tech = [
187
+ "Axiom",
188
+ "Axton",
189
+ "Byton",
190
+ "Cipher",
191
+ "Cyron",
192
+ "Daxon",
193
+ "Dexon",
194
+ "Draxon",
195
+ "Exon",
196
+ "Hexar",
197
+ "Hexon",
198
+ "Helix",
199
+ "Ionex",
200
+ "Kryox",
201
+ "Kronos",
202
+ "Kronox",
203
+ "Lyron",
204
+ "Matrix",
205
+ "Naxon",
206
+ "Neoron",
207
+ "Nexar",
208
+ "Nexon",
209
+ "Nexus",
210
+ "Omicron",
211
+ "Phazon",
212
+ "Photex",
213
+ "Photon",
214
+ "Praxon",
215
+ "Proton",
216
+ "Pulsar",
217
+ "Quantum",
218
+ "Quasar",
219
+ "Synthex",
220
+ "Synthos",
221
+ "Tachyon",
222
+ "Vector",
223
+ "Vertex",
224
+ "Vexar",
225
+ "Vexon",
226
+ "Vorex",
227
+ "Vorton",
228
+ "Vortex",
229
+ "Xaeon",
230
+ "Xyron",
231
+ "Zenon",
232
+ "Zephon",
233
+ "Zeron",
234
+ "Zython"
235
+ ];
236
+ //#endregion
237
+ //#region src/words/verbs.ts
238
+ const verbs = [
239
+ "Banishing",
240
+ "Bumbling",
241
+ "Careening",
242
+ "Conjuring",
243
+ "Devouring",
244
+ "Enchanting",
245
+ "Fleeing",
246
+ "Fumbling",
247
+ "Glitching",
248
+ "Haunting",
249
+ "Howling",
250
+ "Jinxing",
251
+ "Lumbering",
252
+ "Lurking",
253
+ "Menacing",
254
+ "Napping",
255
+ "Obliterating",
256
+ "Pillaging",
257
+ "Questing",
258
+ "Rambling",
259
+ "Rampaging",
260
+ "Scheming",
261
+ "Shambling",
262
+ "Stampeding",
263
+ "Stumbling",
264
+ "Tinkering",
265
+ "Unleashing",
266
+ "Vanishing",
267
+ "Wobbling",
268
+ "Yelling"
269
+ ];
270
+ //#endregion
271
+ //#region src/format.ts
272
+ function titleCase(word) {
273
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
274
+ }
275
+ function applyFormat(words, casing, separator, suffix) {
276
+ let result;
277
+ switch (casing) {
278
+ case "lowercase":
279
+ result = words.map((w) => w.toLowerCase()).join(separator);
280
+ break;
281
+ case "uppercase":
282
+ result = words.map((w) => w.toUpperCase()).join(separator);
283
+ break;
284
+ case "title":
285
+ result = words.map(titleCase).join(separator);
286
+ break;
287
+ case "pascal":
288
+ result = words.map(titleCase).join("");
289
+ break;
290
+ case "camel": {
291
+ const [first, ...rest] = words.map(titleCase);
292
+ result = (first ?? "").toLowerCase() + rest.join("");
293
+ break;
294
+ }
295
+ }
296
+ return result + suffix;
297
+ }
298
+ //#endregion
299
+ //#region src/generate.ts
300
+ function pickUnique(arr, n) {
301
+ const copy = [...arr];
302
+ for (let i = 0; i < n; i++) {
303
+ const j = i + Math.floor(Math.random() * (copy.length - i));
304
+ [copy[i], copy[j]] = [copy[j], copy[i]];
305
+ }
306
+ return copy.slice(0, n);
307
+ }
308
+ function buildWords(style) {
309
+ switch (style) {
310
+ case "adj-noun": return [pickUnique(adjectives, 1)[0], pickUnique(nouns, 1)[0]];
311
+ case "adj-adj-noun": {
312
+ const [adj1, adj2] = pickUnique(adjectives, 2);
313
+ return [
314
+ adj1,
315
+ adj2,
316
+ pickUnique(nouns, 1)[0]
317
+ ];
318
+ }
319
+ case "verb-noun": return [pickUnique(verbs, 1)[0], pickUnique(nouns, 1)[0]];
320
+ case "noun-noun": return pickUnique(nouns, 2);
321
+ case "adj-tech": return [pickUnique(adjectives, 1)[0], pickUnique(tech, 1)[0]];
322
+ case "tech": return [pickUnique(tech, 1)[0]];
323
+ }
324
+ }
325
+ function buildSuffix(digits) {
326
+ if (!digits) return "";
327
+ let s = "";
328
+ for (let i = 0; i < digits; i++) s += Math.floor(Math.random() * 10).toString();
329
+ return s;
330
+ }
331
+ function generateName(options = {}) {
332
+ const { style = "adj-noun", separator = "-", casing = "lowercase", suffix } = options;
333
+ return applyFormat(buildWords(style), casing, separator, buildSuffix(suffix));
334
+ }
335
+ //#endregion
336
+ //#region src/cli/index.ts
337
+ const STYLES = [
338
+ "adj-noun",
339
+ "adj-adj-noun",
340
+ "verb-noun",
341
+ "noun-noun",
342
+ "adj-tech",
343
+ "tech"
344
+ ];
345
+ const CASINGS = [
346
+ "lowercase",
347
+ "uppercase",
348
+ "camel",
349
+ "pascal",
350
+ "title"
351
+ ];
352
+ const HELP = `
353
+ namejam — generate funny, unique usernames
354
+
355
+ Usage: namejam [options]
356
+
357
+ Options:
358
+ --style <style> Word pattern (default: adj-noun)
359
+ ${STYLES.join(" | ")}
360
+ --separator <sep> Word separator string (default: -)
361
+ --casing <casing> Casing style (default: lowercase)
362
+ ${CASINGS.join(" | ")}
363
+ --suffix <digits> Append N random digits
364
+ --count <n> Print N names, one per line (default: 1)
365
+ -h, --help Show this help
366
+ -v, --version Show version
367
+ `.trim();
368
+ function parseArgs(argv) {
369
+ const opts = {};
370
+ let count = 1;
371
+ let i = 0;
372
+ while (i < argv.length) {
373
+ const arg = argv[i];
374
+ if (arg === "-h" || arg === "--help") {
375
+ console.log(HELP);
376
+ process.exit(0);
377
+ }
378
+ if (arg === "-v" || arg === "--version") {
379
+ console.log("0.1.0");
380
+ process.exit(0);
381
+ }
382
+ const next = argv[i + 1];
383
+ if (arg === "--style") {
384
+ if (!next || !STYLES.includes(next)) die(`--style must be one of: ${STYLES.join(", ")}`);
385
+ opts.style = next;
386
+ i += 2;
387
+ } else if (arg === "--separator") {
388
+ if (next === void 0) die("--separator requires a value");
389
+ opts.separator = next;
390
+ i += 2;
391
+ } else if (arg === "--casing") {
392
+ if (!next || !CASINGS.includes(next)) die(`--casing must be one of: ${CASINGS.join(", ")}`);
393
+ opts.casing = next;
394
+ i += 2;
395
+ } else if (arg === "--suffix") {
396
+ const n = Number(next);
397
+ if (!next || !Number.isInteger(n) || n < 1) die("--suffix requires a positive integer");
398
+ opts.suffix = n;
399
+ i += 2;
400
+ } else if (arg === "--count") {
401
+ const n = Number(next);
402
+ if (!next || !Number.isInteger(n) || n < 1) die("--count requires a positive integer");
403
+ count = n;
404
+ i += 2;
405
+ } else die(`Unknown option: ${arg}`);
406
+ }
407
+ return {
408
+ opts,
409
+ count
410
+ };
411
+ }
412
+ function die(msg) {
413
+ console.error(`namejam: ${msg}\nRun 'namejam --help' for usage.`);
414
+ process.exit(1);
415
+ }
416
+ const { opts, count } = parseArgs(process.argv.slice(2));
417
+ for (let i = 0; i < count; i++) console.log(generateName(opts));
418
+ //#endregion
419
+ export {};