human-ids 1.0.14 → 2.0.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.
@@ -0,0 +1,18 @@
1
+ import type { Dictionary } from '../index';
2
+ /**
3
+ * Built-in dictionaries indexed by language code.
4
+ * Currently supports 'en' (English) and 'es' (Spanish).
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { dictionaries } from 'human-ids';
9
+ *
10
+ * // Access English adjectives
11
+ * const englishAdjectives = dictionaries.en.adjectives;
12
+ *
13
+ * // Check available languages
14
+ * const languages = Object.keys(dictionaries); // ['en', 'es']
15
+ * ```
16
+ */
17
+ declare const dictionaries: Record<string, Dictionary>;
18
+ export { dictionaries };
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dictionaries = void 0;
4
+ const en_1 = require("./en");
5
+ const es_1 = require("./es");
6
+ /**
7
+ * Built-in dictionaries indexed by language code.
8
+ * Currently supports 'en' (English) and 'es' (Spanish).
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { dictionaries } from 'human-ids';
13
+ *
14
+ * // Access English adjectives
15
+ * const englishAdjectives = dictionaries.en.adjectives;
16
+ *
17
+ * // Check available languages
18
+ * const languages = Object.keys(dictionaries); // ['en', 'es']
19
+ * ```
20
+ */
21
+ const dictionaries = {
22
+ en: en_1.en,
23
+ es: es_1.es,
24
+ };
25
+ exports.dictionaries = dictionaries;
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Human IDs - A library to generate human-readable identifiers
3
+ * @packageDocumentation
4
+ * @module human-ids
5
+ */
6
+ import { dictionaries } from './dictionaries';
7
+ /**
8
+ * Dictionary containing word lists for ID generation.
9
+ * Each property maps word keys to their display values.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const customDictionary: Dictionary = {
14
+ * adjectives: { happy: 'happy', bright: 'bright' },
15
+ * colors: { red: 'red', blue: 'blue' },
16
+ * nouns: { cat: 'cat', dog: 'dog' }
17
+ * };
18
+ * ```
19
+ */
20
+ export interface Dictionary {
21
+ /** List of adjective words */
22
+ adjectives: string[];
23
+ /** List of color words */
24
+ colors: string[];
25
+ /** List of noun words */
26
+ nouns: string[];
27
+ }
28
+ /**
29
+ * Object containing the individual parts of a generated ID.
30
+ * Returned when `asObject: true` is set in the settings.
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const parts: IdParts = {
35
+ * adjective: 'happy',
36
+ * color: 'blue',
37
+ * noun: 'cat',
38
+ * number1: '1234'
39
+ * };
40
+ * ```
41
+ */
42
+ export interface IdParts {
43
+ /** The adjective component (if enabled) */
44
+ adjective?: string;
45
+ /** The color component (if enabled) */
46
+ color?: string;
47
+ /** The noun component (if enabled) */
48
+ noun?: string;
49
+ /** Additional properties for number components (number1, number2, etc.) */
50
+ [key: string]: string | undefined;
51
+ }
52
+ /**
53
+ * Configuration options for the number component(s) of generated IDs.
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * // Generate IDs with numbers between 1000-9999, zero-padded
58
+ * const numberSettings: NumberSettings = {
59
+ * min: 1000,
60
+ * max: 9999,
61
+ * sets: 1,
62
+ * completeWithZeros: true
63
+ * };
64
+ * ```
65
+ */
66
+ export interface NumberSettings {
67
+ /**
68
+ * Minimum value for random numbers (inclusive)
69
+ * @default 0
70
+ */
71
+ min?: number;
72
+ /**
73
+ * Maximum value for random numbers (inclusive)
74
+ * @default 9999
75
+ */
76
+ max?: number;
77
+ /**
78
+ * Number of separate number components to include
79
+ * @default 1
80
+ * @example
81
+ * // With sets: 2, generates: "happy-blue-cat-1234-5678"
82
+ */
83
+ sets?: number;
84
+ /**
85
+ * Whether to pad numbers with leading zeros to match max length
86
+ * @default false
87
+ * @example
88
+ * // With max: 9999 and completeWithZeros: true
89
+ * // Number 42 becomes "0042"
90
+ */
91
+ completeWithZeros?: boolean;
92
+ }
93
+ /**
94
+ * Maps language codes to their component ordering.
95
+ * Defines the order in which ID parts appear for each language.
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const semantics: SemanticsMap = {
100
+ * en: ['adjective', 'color', 'noun', 'number'], // happy-blue-cat-123
101
+ * es: ['noun', 'color', 'adjective', 'number'] // gato-azul-feliz-123
102
+ * };
103
+ * ```
104
+ */
105
+ export interface SemanticsMap {
106
+ [lang: string]: Array<'noun' | 'adjective' | 'color' | 'number'>;
107
+ }
108
+ /**
109
+ * Configuration options for the ID generator.
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * // Basic usage with Spanish
114
+ * const settings: IdGeneratorSettings = {
115
+ * lang: 'es',
116
+ * separator: '_'
117
+ * };
118
+ *
119
+ * // Advanced usage with custom dictionary
120
+ * const advancedSettings: IdGeneratorSettings = {
121
+ * lang: 'en',
122
+ * adjective: true,
123
+ * color: false, // Exclude colors
124
+ * noun: true,
125
+ * number: { min: 100, max: 999 },
126
+ * dictionary: {
127
+ * adjectives: { cool: 'cool', awesome: 'awesome' }
128
+ * }
129
+ * };
130
+ * ```
131
+ */
132
+ export interface IdGeneratorSettings {
133
+ /**
134
+ * Language code for built-in dictionaries ('en' or 'es').
135
+ * Also accepts locale codes like 'en-US' (falls back to base language).
136
+ * @default 'en'
137
+ */
138
+ lang?: string;
139
+ /**
140
+ * Whether to include an adjective in the ID
141
+ * @default true
142
+ */
143
+ adjective?: boolean;
144
+ /**
145
+ * Whether to include a color in the ID
146
+ * @default true
147
+ */
148
+ color?: boolean;
149
+ /**
150
+ * Whether to include a noun in the ID
151
+ * @default true
152
+ */
153
+ noun?: boolean;
154
+ /**
155
+ * Whether to randomize the order of components
156
+ * @default false
157
+ */
158
+ randomOrder?: boolean;
159
+ /**
160
+ * Character(s) used to separate ID components
161
+ * @default '-'
162
+ */
163
+ separator?: string;
164
+ /**
165
+ * Return an object with individual parts instead of a string
166
+ * @default false
167
+ */
168
+ asObject?: boolean;
169
+ /**
170
+ * Custom component ordering per language.
171
+ * @default { en: ['adjective', 'color', 'noun', 'number'], es: ['noun', 'color', 'adjective', 'number'] }
172
+ */
173
+ semantics?: SemanticsMap;
174
+ /**
175
+ * Configuration for the number component(s)
176
+ * @default { min: 0, max: 9999, sets: 1, completeWithZeros: false }
177
+ */
178
+ number?: NumberSettings;
179
+ /**
180
+ * Custom dictionary to use (can partially override built-in words)
181
+ */
182
+ dictionary?: Partial<Dictionary>;
183
+ }
184
+ /**
185
+ * Generates a human-readable ID by combining adjectives, colors, nouns, and numbers.
186
+ *
187
+ * @param settings - Configuration options (with asObject: true)
188
+ * @returns Object containing individual ID components
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * // Get ID as object
193
+ * const parts = generateId({ asObject: true });
194
+ * // { adjective: 'happy', color: 'blue', noun: 'cat', number1: '1234' }
195
+ * ```
196
+ */
197
+ declare function generateId(settings?: IdGeneratorSettings & {
198
+ asObject: true;
199
+ }): IdParts;
200
+ /**
201
+ * Generates a human-readable ID by combining adjectives, colors, nouns, and numbers.
202
+ *
203
+ * @param settings - Configuration options
204
+ * @returns Human-readable ID string
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // Basic usage - returns string like "happy-blue-cat-1234"
209
+ * const id = generateId();
210
+ *
211
+ * // Spanish language
212
+ * const spanishId = generateId({ lang: 'es' });
213
+ * // "gato-azul-feliz-5678"
214
+ *
215
+ * // Custom separator
216
+ * const underscoreId = generateId({ separator: '_' });
217
+ * // "happy_blue_cat_9012"
218
+ *
219
+ * // Without colors
220
+ * const noColorId = generateId({ color: false });
221
+ * // "happy-cat-3456"
222
+ *
223
+ * // Custom number range
224
+ * const customNumberId = generateId({
225
+ * number: { min: 100, max: 999, completeWithZeros: true }
226
+ * });
227
+ * // "happy-blue-cat-042"
228
+ *
229
+ * // Multiple number sets
230
+ * const multiNumberId = generateId({ number: { sets: 2 } });
231
+ * // "happy-blue-cat-1234-5678"
232
+ *
233
+ * // Random component order
234
+ * const randomOrderId = generateId({ randomOrder: true });
235
+ * // "1234-cat-happy-blue" (random order each time)
236
+ *
237
+ * // Custom dictionary (partial override)
238
+ * const customId = generateId({
239
+ * dictionary: {
240
+ * adjectives: { cool: 'cool', awesome: 'awesome' }
241
+ * }
242
+ * });
243
+ * ```
244
+ */
245
+ declare function generateId(settings?: IdGeneratorSettings): string;
246
+ export { generateId, dictionaries };
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * Human IDs - A library to generate human-readable identifiers
4
+ * @packageDocumentation
5
+ * @module human-ids
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.dictionaries = void 0;
9
+ exports.generateId = generateId;
10
+ const dictionaries_1 = require("./dictionaries");
11
+ Object.defineProperty(exports, "dictionaries", { enumerable: true, get: function () { return dictionaries_1.dictionaries; } });
12
+ /**
13
+ * Default settings applied when options are not specified.
14
+ * @internal
15
+ */
16
+ const defaultSettings = {
17
+ lang: 'en',
18
+ adjective: true,
19
+ color: true,
20
+ noun: true,
21
+ randomOrder: false,
22
+ separator: '-',
23
+ asObject: false,
24
+ semantics: {
25
+ es: ['noun', 'color', 'adjective', 'number'],
26
+ en: ['adjective', 'color', 'noun', 'number'],
27
+ },
28
+ number: {
29
+ min: 0,
30
+ max: 9999,
31
+ sets: 1,
32
+ completeWithZeros: false,
33
+ },
34
+ };
35
+ /**
36
+ * Generates a random integer between min and max (inclusive).
37
+ * @param min - Minimum value (inclusive)
38
+ * @param max - Maximum value (inclusive)
39
+ * @returns Random integer in the range [min, max]
40
+ * @internal
41
+ */
42
+ function getRandomNumber(min, max) {
43
+ return Math.floor(Math.random() * (max - min + 1)) + min;
44
+ }
45
+ /**
46
+ * Picks a random element from an array.
47
+ * @param arr - Array to pick from
48
+ * @returns Random element from the array
49
+ * @internal
50
+ */
51
+ function pickRandom(arr) {
52
+ return arr[Math.floor(Math.random() * arr.length)];
53
+ }
54
+ /**
55
+ * Resolves a language code to a supported language.
56
+ * Supports full locale codes (e.g., 'en-US' resolves to 'en').
57
+ * Falls back to 'en' if language is not supported.
58
+ * @param lang - Language code to resolve
59
+ * @returns Resolved language code ('en' or 'es')
60
+ * @internal
61
+ */
62
+ function resolveLang(lang) {
63
+ if (dictionaries_1.dictionaries[lang])
64
+ return lang;
65
+ const base = lang.split('-')[0];
66
+ if (dictionaries_1.dictionaries[base])
67
+ return base;
68
+ return 'en';
69
+ }
70
+ function generateId(userSettings = {}) {
71
+ const settings = { ...defaultSettings, ...userSettings };
72
+ const lang = resolveLang(settings.lang);
73
+ const numberMin = settings.number && settings.number.min !== undefined ? settings.number.min : 0;
74
+ const numberMax = settings.number && settings.number.max !== undefined ? settings.number.max : 999;
75
+ const numberSets = (settings.number && settings.number.sets) || 1;
76
+ const completeWithZeros = (settings.number && settings.number.completeWithZeros) || false;
77
+ const customDict = settings.dictionary;
78
+ const builtinDict = dictionaries_1.dictionaries[lang];
79
+ const resolved = customDict
80
+ ? {
81
+ adjectives: customDict.adjectives ? [...new Set(customDict.adjectives)] : builtinDict.adjectives,
82
+ colors: customDict.colors ? [...new Set(customDict.colors)] : builtinDict.colors,
83
+ nouns: customDict.nouns ? [...new Set(customDict.nouns)] : builtinDict.nouns,
84
+ }
85
+ : builtinDict;
86
+ const parts = {};
87
+ if (settings.adjective) {
88
+ parts.adjective = pickRandom(resolved.adjectives);
89
+ }
90
+ if (settings.color) {
91
+ parts.color = pickRandom(resolved.colors);
92
+ }
93
+ if (settings.noun) {
94
+ parts.noun = pickRandom(resolved.nouns);
95
+ }
96
+ const maxNumberLength = completeWithZeros ? numberMax.toString().length : 0;
97
+ for (let i = 0; i < numberSets; i++) {
98
+ const num = getRandomNumber(numberMin, numberMax);
99
+ parts[`number${i + 1}`] = completeWithZeros
100
+ ? num.toString().padStart(maxNumberLength, '0')
101
+ : num.toString();
102
+ }
103
+ if (settings.randomOrder) {
104
+ const keys = Object.keys(parts);
105
+ const shuffledKeys = keys.sort(() => Math.random() - 0.5);
106
+ const shuffledParts = [];
107
+ for (const key of shuffledKeys) {
108
+ shuffledParts.push(parts[key]);
109
+ }
110
+ return shuffledParts.join(settings.separator);
111
+ }
112
+ if (settings.asObject) {
113
+ return parts;
114
+ }
115
+ const semantics = (settings.semantics && settings.semantics[lang]) || settings.semantics.en;
116
+ const result = semantics.map((key) => {
117
+ if (key !== 'number')
118
+ return parts[key];
119
+ // Collect all number parts directly instead of filtering with isNaN
120
+ const numberParts = [];
121
+ for (let i = 1; i <= numberSets; i++) {
122
+ numberParts.push(parts[`number${i}`]);
123
+ }
124
+ return numberParts.join('-');
125
+ });
126
+ return result.join(settings.separator);
127
+ }
@@ -0,0 +1,6 @@
1
+ declare const words: {
2
+ adjectives: string[];
3
+ colors: string[];
4
+ nouns: string[];
5
+ };
6
+ export { words as en };