/ utils / words.ts
words.ts
  1  /**
  2   * Random word slug generator for plan IDs
  3   * Inspired by https://github.com/nas5w/random-word-slugs
  4   * with Claude-flavored words
  5   */
  6  import { randomBytes } from 'crypto'
  7  
  8  // Adjectives for slug generation - whimsical and delightful
  9  const ADJECTIVES = [
 10    // Classic pleasant adjectives
 11    'abundant',
 12    'ancient',
 13    'bright',
 14    'calm',
 15    'cheerful',
 16    'clever',
 17    'cozy',
 18    'curious',
 19    'dapper',
 20    'dazzling',
 21    'deep',
 22    'delightful',
 23    'eager',
 24    'elegant',
 25    'enchanted',
 26    'fancy',
 27    'fluffy',
 28    'gentle',
 29    'gleaming',
 30    'golden',
 31    'graceful',
 32    'happy',
 33    'hidden',
 34    'humble',
 35    'jolly',
 36    'joyful',
 37    'keen',
 38    'kind',
 39    'lively',
 40    'lovely',
 41    'lucky',
 42    'luminous',
 43    'magical',
 44    'majestic',
 45    'mellow',
 46    'merry',
 47    'mighty',
 48    'misty',
 49    'noble',
 50    'peaceful',
 51    'playful',
 52    'polished',
 53    'precious',
 54    'proud',
 55    'quiet',
 56    'quirky',
 57    'radiant',
 58    'rosy',
 59    'serene',
 60    'shiny',
 61    'silly',
 62    'sleepy',
 63    'smooth',
 64    'snazzy',
 65    'snug',
 66    'snuggly',
 67    'soft',
 68    'sparkling',
 69    'spicy',
 70    'splendid',
 71    'sprightly',
 72    'starry',
 73    'steady',
 74    'sunny',
 75    'swift',
 76    'tender',
 77    'tidy',
 78    'toasty',
 79    'tranquil',
 80    'twinkly',
 81    'valiant',
 82    'vast',
 83    'velvet',
 84    'vivid',
 85    'warm',
 86    'whimsical',
 87    'wild',
 88    'wise',
 89    'witty',
 90    'wondrous',
 91    'zany',
 92    'zesty',
 93    'zippy',
 94    // Whimsical / magical
 95    'breezy',
 96    'bubbly',
 97    'buzzing',
 98    'cheeky',
 99    'cosmic',
100    'cozy',
101    'crispy',
102    'crystalline',
103    'cuddly',
104    'drifting',
105    'dreamy',
106    'effervescent',
107    'ethereal',
108    'fizzy',
109    'flickering',
110    'floating',
111    'floofy',
112    'fluttering',
113    'foamy',
114    'frolicking',
115    'fuzzy',
116    'giggly',
117    'glimmering',
118    'glistening',
119    'glittery',
120    'glowing',
121    'goofy',
122    'groovy',
123    'harmonic',
124    'hazy',
125    'humming',
126    'iridescent',
127    'jaunty',
128    'jazzy',
129    'jiggly',
130    'melodic',
131    'moonlit',
132    'mossy',
133    'nifty',
134    'peppy',
135    'prancy',
136    'purrfect',
137    'purring',
138    'quizzical',
139    'rippling',
140    'rustling',
141    'shimmering',
142    'shimmying',
143    'snappy',
144    'snoopy',
145    'squishy',
146    'swirling',
147    'ticklish',
148    'tingly',
149    'twinkling',
150    'velvety',
151    'wiggly',
152    'wobbly',
153    'woolly',
154    'zazzy',
155    // Programming concepts
156    'abstract',
157    'adaptive',
158    'agile',
159    'async',
160    'atomic',
161    'binary',
162    'cached',
163    'compiled',
164    'composed',
165    'compressed',
166    'concurrent',
167    'cryptic',
168    'curried',
169    'declarative',
170    'delegated',
171    'distributed',
172    'dynamic',
173    'eager',
174    'elegant',
175    'encapsulated',
176    'enumerated',
177    'eventual',
178    'expressive',
179    'federated',
180    'functional',
181    'generic',
182    'greedy',
183    'hashed',
184    'idempotent',
185    'immutable',
186    'imperative',
187    'indexed',
188    'inherited',
189    'iterative',
190    'lazy',
191    'lexical',
192    'linear',
193    'linked',
194    'logical',
195    'memoized',
196    'modular',
197    'mutable',
198    'nested',
199    'optimized',
200    'parallel',
201    'parsed',
202    'partitioned',
203    'piped',
204    'polymorphic',
205    'pure',
206    'reactive',
207    'recursive',
208    'refactored',
209    'reflective',
210    'replicated',
211    'resilient',
212    'robust',
213    'scalable',
214    'sequential',
215    'serialized',
216    'sharded',
217    'sorted',
218    'staged',
219    'stateful',
220    'stateless',
221    'streamed',
222    'structured',
223    'synchronous',
224    'synthetic',
225    'temporal',
226    'transient',
227    'typed',
228    'unified',
229    'validated',
230    'vectorized',
231    'virtual',
232  ] as const
233  
234  // Nouns for slug generation - whimsical creatures, nature, and fun objects
235  const NOUNS = [
236    // Nature & cosmic
237    'aurora',
238    'avalanche',
239    'blossom',
240    'breeze',
241    'brook',
242    'bubble',
243    'canyon',
244    'cascade',
245    'cloud',
246    'clover',
247    'comet',
248    'coral',
249    'cosmos',
250    'creek',
251    'crescent',
252    'crystal',
253    'dawn',
254    'dewdrop',
255    'dusk',
256    'eclipse',
257    'ember',
258    'feather',
259    'fern',
260    'firefly',
261    'flame',
262    'flurry',
263    'fog',
264    'forest',
265    'frost',
266    'galaxy',
267    'garden',
268    'glacier',
269    'glade',
270    'grove',
271    'harbor',
272    'horizon',
273    'island',
274    'lagoon',
275    'lake',
276    'leaf',
277    'lightning',
278    'meadow',
279    'meteor',
280    'mist',
281    'moon',
282    'moonbeam',
283    'mountain',
284    'nebula',
285    'nova',
286    'ocean',
287    'orbit',
288    'pebble',
289    'petal',
290    'pine',
291    'planet',
292    'pond',
293    'puddle',
294    'quasar',
295    'rain',
296    'rainbow',
297    'reef',
298    'ripple',
299    'river',
300    'shore',
301    'sky',
302    'snowflake',
303    'spark',
304    'spring',
305    'star',
306    'stardust',
307    'starlight',
308    'storm',
309    'stream',
310    'summit',
311    'sun',
312    'sunbeam',
313    'sunrise',
314    'sunset',
315    'thunder',
316    'tide',
317    'twilight',
318    'valley',
319    'volcano',
320    'waterfall',
321    'wave',
322    'willow',
323    'wind',
324    // Cute creatures
325    'alpaca',
326    'axolotl',
327    'badger',
328    'bear',
329    'beaver',
330    'bee',
331    'bird',
332    'bumblebee',
333    'bunny',
334    'cat',
335    'chipmunk',
336    'crab',
337    'crane',
338    'deer',
339    'dolphin',
340    'dove',
341    'dragon',
342    'dragonfly',
343    'duckling',
344    'eagle',
345    'elephant',
346    'falcon',
347    'finch',
348    'flamingo',
349    'fox',
350    'frog',
351    'giraffe',
352    'goose',
353    'hamster',
354    'hare',
355    'hedgehog',
356    'hippo',
357    'hummingbird',
358    'jellyfish',
359    'kitten',
360    'koala',
361    'ladybug',
362    'lark',
363    'lemur',
364    'llama',
365    'lobster',
366    'lynx',
367    'manatee',
368    'meerkat',
369    'moth',
370    'narwhal',
371    'newt',
372    'octopus',
373    'otter',
374    'owl',
375    'panda',
376    'parrot',
377    'peacock',
378    'pelican',
379    'penguin',
380    'phoenix',
381    'piglet',
382    'platypus',
383    'pony',
384    'porcupine',
385    'puffin',
386    'puppy',
387    'quail',
388    'quokka',
389    'rabbit',
390    'raccoon',
391    'raven',
392    'robin',
393    'salamander',
394    'seahorse',
395    'seal',
396    'sloth',
397    'snail',
398    'sparrow',
399    'sphinx',
400    'squid',
401    'squirrel',
402    'starfish',
403    'swan',
404    'tiger',
405    'toucan',
406    'turtle',
407    'unicorn',
408    'walrus',
409    'whale',
410    'wolf',
411    'wombat',
412    'wren',
413    'yeti',
414    'zebra',
415    // Fun objects & concepts
416    'acorn',
417    'anchor',
418    'balloon',
419    'beacon',
420    'biscuit',
421    'blanket',
422    'bonbon',
423    'book',
424    'boot',
425    'cake',
426    'candle',
427    'candy',
428    'castle',
429    'charm',
430    'clock',
431    'cocoa',
432    'cookie',
433    'crayon',
434    'crown',
435    'cupcake',
436    'donut',
437    'dream',
438    'fairy',
439    'fiddle',
440    'flask',
441    'flute',
442    'fountain',
443    'gadget',
444    'gem',
445    'gizmo',
446    'globe',
447    'goblet',
448    'hammock',
449    'harp',
450    'haven',
451    'hearth',
452    'honey',
453    'journal',
454    'kazoo',
455    'kettle',
456    'key',
457    'kite',
458    'lantern',
459    'lemon',
460    'lighthouse',
461    'locket',
462    'lollipop',
463    'mango',
464    'map',
465    'marble',
466    'marshmallow',
467    'melody',
468    'mitten',
469    'mochi',
470    'muffin',
471    'music',
472    'nest',
473    'noodle',
474    'oasis',
475    'origami',
476    'pancake',
477    'parasol',
478    'peach',
479    'pearl',
480    'pebble',
481    'pie',
482    'pillow',
483    'pinwheel',
484    'pixel',
485    'pizza',
486    'plum',
487    'popcorn',
488    'pretzel',
489    'prism',
490    'pudding',
491    'pumpkin',
492    'puzzle',
493    'quiche',
494    'quill',
495    'quilt',
496    'riddle',
497    'rocket',
498    'rose',
499    'scone',
500    'scroll',
501    'shell',
502    'sketch',
503    'snowglobe',
504    'sonnet',
505    'sparkle',
506    'spindle',
507    'sprout',
508    'sundae',
509    'swing',
510    'taco',
511    'teacup',
512    'teapot',
513    'thimble',
514    'toast',
515    'token',
516    'tome',
517    'tower',
518    'treasure',
519    'treehouse',
520    'trinket',
521    'truffle',
522    'tulip',
523    'umbrella',
524    'waffle',
525    'wand',
526    'whisper',
527    'whistle',
528    'widget',
529    'wreath',
530    'zephyr',
531    // Computer scientists
532    'abelson',
533    'adleman',
534    'aho',
535    'allen',
536    'babbage',
537    'bachman',
538    'backus',
539    'barto',
540    'bengio',
541    'bentley',
542    'blum',
543    'boole',
544    'brooks',
545    'catmull',
546    'cerf',
547    'cherny',
548    'church',
549    'clarke',
550    'cocke',
551    'codd',
552    'conway',
553    'cook',
554    'corbato',
555    'cray',
556    'curry',
557    'dahl',
558    'diffie',
559    'dijkstra',
560    'dongarra',
561    'eich',
562    'emerson',
563    'engelbart',
564    'feigenbaum',
565    'floyd',
566    'gosling',
567    'graham',
568    'gray',
569    'hamming',
570    'hanrahan',
571    'hartmanis',
572    'hejlsberg',
573    'hellman',
574    'hennessy',
575    'hickey',
576    'hinton',
577    'hoare',
578    'hollerith',
579    'hopcroft',
580    'hopper',
581    'iverson',
582    'kahan',
583    'kahn',
584    'karp',
585    'kay',
586    'kernighan',
587    'knuth',
588    'kurzweil',
589    'lamport',
590    'lampson',
591    'lecun',
592    'lerdorf',
593    'liskov',
594    'lovelace',
595    'matsumoto',
596    'mccarthy',
597    'metcalfe',
598    'micali',
599    'milner',
600    'minsky',
601    'moler',
602    'moore',
603    'naur',
604    'neumann',
605    'newell',
606    'nygaard',
607    'papert',
608    'parnas',
609    'pascal',
610    'patterson',
611    'pearl',
612    'perlis',
613    'pike',
614    'pnueli',
615    'rabin',
616    'reddy',
617    'ritchie',
618    'rivest',
619    'rossum',
620    'russell',
621    'scott',
622    'sedgewick',
623    'shamir',
624    'shannon',
625    'sifakis',
626    'simon',
627    'stallman',
628    'stearns',
629    'steele',
630    'stonebraker',
631    'stroustrup',
632    'sutherland',
633    'sutton',
634    'tarjan',
635    'thacker',
636    'thompson',
637    'torvalds',
638    'turing',
639    'ullman',
640    'valiant',
641    'wadler',
642    'wall',
643    'wigderson',
644    'wilkes',
645    'wilkinson',
646    'wirth',
647    'wozniak',
648    'yao',
649  ] as const
650  
651  // Verbs for the middle word - whimsical action words
652  const VERBS = [
653    'baking',
654    'beaming',
655    'booping',
656    'bouncing',
657    'brewing',
658    'bubbling',
659    'chasing',
660    'churning',
661    'coalescing',
662    'conjuring',
663    'cooking',
664    'crafting',
665    'crunching',
666    'cuddling',
667    'dancing',
668    'dazzling',
669    'discovering',
670    'doodling',
671    'dreaming',
672    'drifting',
673    'enchanting',
674    'exploring',
675    'finding',
676    'floating',
677    'fluttering',
678    'foraging',
679    'forging',
680    'frolicking',
681    'gathering',
682    'giggling',
683    'gliding',
684    'greeting',
685    'growing',
686    'hatching',
687    'herding',
688    'honking',
689    'hopping',
690    'hugging',
691    'humming',
692    'imagining',
693    'inventing',
694    'jingling',
695    'juggling',
696    'jumping',
697    'kindling',
698    'knitting',
699    'launching',
700    'leaping',
701    'mapping',
702    'marinating',
703    'meandering',
704    'mixing',
705    'moseying',
706    'munching',
707    'napping',
708    'nibbling',
709    'noodling',
710    'orbiting',
711    'painting',
712    'percolating',
713    'petting',
714    'plotting',
715    'pondering',
716    'popping',
717    'prancing',
718    'purring',
719    'puzzling',
720    'questing',
721    'riding',
722    'roaming',
723    'rolling',
724    'sauteeing',
725    'scribbling',
726    'seeking',
727    'shimmying',
728    'singing',
729    'skipping',
730    'sleeping',
731    'snacking',
732    'sniffing',
733    'snuggling',
734    'soaring',
735    'sparking',
736    'spinning',
737    'splashing',
738    'sprouting',
739    'squishing',
740    'stargazing',
741    'stirring',
742    'strolling',
743    'swimming',
744    'swinging',
745    'tickling',
746    'tinkering',
747    'toasting',
748    'tumbling',
749    'twirling',
750    'waddling',
751    'wandering',
752    'watching',
753    'weaving',
754    'whistling',
755    'wibbling',
756    'wiggling',
757    'wishing',
758    'wobbling',
759    'wondering',
760    'yawning',
761    'zooming',
762  ] as const
763  
764  /**
765   * Generate a cryptographically random integer in the range [0, max)
766   */
767  function randomInt(max: number): number {
768    // Use crypto.randomBytes for better randomness than Math.random
769    const bytes = randomBytes(4)
770    const value = bytes.readUInt32BE(0)
771    return value % max
772  }
773  
774  /**
775   * Pick a random element from an array
776   */
777  function pickRandom<T>(array: readonly T[]): T {
778    return array[randomInt(array.length)]!
779  }
780  
781  /**
782   * Generate a random word slug in the format "adjective-verb-noun"
783   * Example: "gleaming-brewing-phoenix", "cosmic-pondering-lighthouse"
784   */
785  export function generateWordSlug(): string {
786    const adjective = pickRandom(ADJECTIVES)
787    const verb = pickRandom(VERBS)
788    const noun = pickRandom(NOUNS)
789    return `${adjective}-${verb}-${noun}`
790  }
791  
792  /**
793   * Generate a shorter random word slug in the format "adjective-noun"
794   * Example: "graceful-unicorn", "cosmic-lighthouse"
795   */
796  export function generateShortWordSlug(): string {
797    const adjective = pickRandom(ADJECTIVES)
798    const noun = pickRandom(NOUNS)
799    return `${adjective}-${noun}`
800  }