168 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { customAlphabet } from 'nanoid';
 | 
						|
 | 
						|
// Word lists for generating memorable tokens
 | 
						|
const adjectives = [
 | 
						|
  'quick',
 | 
						|
  'lazy',
 | 
						|
  'happy',
 | 
						|
  'brave',
 | 
						|
  'bright',
 | 
						|
  'calm',
 | 
						|
  'clever',
 | 
						|
  'eager',
 | 
						|
  'gentle',
 | 
						|
  'kind',
 | 
						|
  'lively',
 | 
						|
  'proud',
 | 
						|
  'silly',
 | 
						|
  'witty',
 | 
						|
  'bold',
 | 
						|
  'cool',
 | 
						|
  'fair',
 | 
						|
  'fine',
 | 
						|
  'glad',
 | 
						|
  'good',
 | 
						|
  'neat',
 | 
						|
  'nice',
 | 
						|
  'rare',
 | 
						|
  'safe',
 | 
						|
  'warm',
 | 
						|
  'wise',
 | 
						|
  'fresh',
 | 
						|
  'clean',
 | 
						|
  'clear',
 | 
						|
  'crisp',
 | 
						|
  'sweet',
 | 
						|
  'smooth',
 | 
						|
];
 | 
						|
 | 
						|
const colors = [
 | 
						|
  'red',
 | 
						|
  'blue',
 | 
						|
  'green',
 | 
						|
  'yellow',
 | 
						|
  'purple',
 | 
						|
  'orange',
 | 
						|
  'pink',
 | 
						|
  'black',
 | 
						|
  'white',
 | 
						|
  'gray',
 | 
						|
  'brown',
 | 
						|
  'cyan',
 | 
						|
  'lime',
 | 
						|
  'navy',
 | 
						|
  'teal',
 | 
						|
  'gold',
 | 
						|
  'silver',
 | 
						|
  'coral',
 | 
						|
  'salmon',
 | 
						|
  'indigo',
 | 
						|
  'violet',
 | 
						|
  'crimson',
 | 
						|
  'azure',
 | 
						|
  'jade',
 | 
						|
];
 | 
						|
 | 
						|
const animals = [
 | 
						|
  'cat',
 | 
						|
  'dog',
 | 
						|
  'bird',
 | 
						|
  'fish',
 | 
						|
  'bear',
 | 
						|
  'lion',
 | 
						|
  'wolf',
 | 
						|
  'fox',
 | 
						|
  'deer',
 | 
						|
  'owl',
 | 
						|
  'hawk',
 | 
						|
  'duck',
 | 
						|
  'goat',
 | 
						|
  'seal',
 | 
						|
  'crab',
 | 
						|
  'moth',
 | 
						|
  'bee',
 | 
						|
  'ant',
 | 
						|
  'bat',
 | 
						|
  'cow',
 | 
						|
  'pig',
 | 
						|
  'hen',
 | 
						|
  'ram',
 | 
						|
  'rat',
 | 
						|
  'eel',
 | 
						|
  'cod',
 | 
						|
  'jay',
 | 
						|
  'yak',
 | 
						|
  'ox',
 | 
						|
  'pug',
 | 
						|
  'doe',
 | 
						|
  'hog',
 | 
						|
];
 | 
						|
 | 
						|
const nouns = [
 | 
						|
  'moon',
 | 
						|
  'star',
 | 
						|
  'cloud',
 | 
						|
  'river',
 | 
						|
  'mountain',
 | 
						|
  'ocean',
 | 
						|
  'forest',
 | 
						|
  'desert',
 | 
						|
  'island',
 | 
						|
  'valley',
 | 
						|
  'meadow',
 | 
						|
  'garden',
 | 
						|
  'bridge',
 | 
						|
  'castle',
 | 
						|
  'tower',
 | 
						|
  'light',
 | 
						|
  'shadow',
 | 
						|
  'dream',
 | 
						|
  'hope',
 | 
						|
  'wish',
 | 
						|
  'song',
 | 
						|
  'dance',
 | 
						|
  'smile',
 | 
						|
  'laugh',
 | 
						|
  'gift',
 | 
						|
  'pearl',
 | 
						|
  'jewel',
 | 
						|
  'crown',
 | 
						|
  'shield',
 | 
						|
  'sword',
 | 
						|
  'arrow',
 | 
						|
  'bow',
 | 
						|
];
 | 
						|
 | 
						|
// Generate a 4-digit number suffix for uniqueness
 | 
						|
const generateNumber = customAlphabet('0123456789', 4);
 | 
						|
 | 
						|
function getRandomElement<T>(array: T[]): T {
 | 
						|
  return array[Math.floor(Math.random() * array.length)];
 | 
						|
}
 | 
						|
 | 
						|
export function generateMemorableToken(): string {
 | 
						|
  const parts = [
 | 
						|
    getRandomElement(adjectives),
 | 
						|
    getRandomElement(colors),
 | 
						|
    getRandomElement(animals),
 | 
						|
    generateNumber(),
 | 
						|
  ];
 | 
						|
 | 
						|
  return parts.join('-');
 | 
						|
}
 | 
						|
 | 
						|
export function generateShortToken(): string {
 | 
						|
  const parts = [getRandomElement(colors), getRandomElement(nouns), generateNumber()];
 | 
						|
 | 
						|
  return parts.join('-');
 | 
						|
}
 | 
						|
 | 
						|
// Validate token format
 | 
						|
export function isValidToken(token: string): boolean {
 | 
						|
  // Check if token matches our format (word-word-word-4digits or word-word-4digits)
 | 
						|
  const longFormat = /^[a-z]+-[a-z]+-[a-z]+-\d{4}$/;
 | 
						|
  const shortFormat = /^[a-z]+-[a-z]+-\d{4}$/;
 | 
						|
 | 
						|
  return longFormat.test(token) || shortFormat.test(token);
 | 
						|
}
 |