namefully 2.0.2 → 2.2.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.
@@ -1,7 +1,8 @@
1
1
  import { Config } from './config.js';
2
+ import { SerializedName } from './data.js';
2
3
  import { Name, JsonName } from './name.js';
3
- import { Flat, NameOrder, NameType, Namon, Nullable, Surname } from './types.js';
4
4
  import { NameIndex } from './utils.js';
5
+ import { Flat, NameOrder, NameType, Namon, Nullable, Surname, Separator, Title } from './types.js';
5
6
  import { Parser } from './parser.js';
6
7
  /**
7
8
  * A utility for organizing human names in a particular order, way, or shape.
@@ -31,8 +32,8 @@ import { Parser } from './parser.js';
31
32
  * this: `John Smith`, where `John` is the first name piece and `Smith`, the last
32
33
  * name piece.
33
34
  *
34
- * @see {@link https://www.fbiic.gov/public/2008/nov/Naming_practice_guide_UK_2006.pdf}
35
- * for more info on name standards.
35
+ * @see {@link https://www.fbiic.gov/public/2008/nov/Naming_practice_guide_UK_2006.pdf} for
36
+ * more info on name standards.
36
37
  *
37
38
  * **IMPORTANT**: Keep in mind that the order of appearance (or name order) matters
38
39
  * and may be altered through configurable parameters, which will be seen later.
@@ -59,7 +60,7 @@ export declare class Namefully {
59
60
  * name during its existence. All name parts must have at least one (1) character
60
61
  * to proceed. That is the only requirement/validation of namefully.
61
62
  */
62
- constructor(names: string | string[] | Name[] | JsonName | Parser, options?: Partial<Config>);
63
+ constructor(names: string | string[] | Name[] | JsonName | Parser, options?: NameOptions);
63
64
  /**
64
65
  * Constructs a `Namefully` instance from a text.
65
66
  *
@@ -85,6 +86,8 @@ export declare class Namefully {
85
86
  static parse(text: string, index?: NameIndex): Promise<Namefully>;
86
87
  /** The configuration dictating this name's behavior. */
87
88
  get config(): Config;
89
+ /** Whether the name is a single word name. */
90
+ get isMono(): boolean;
88
91
  /** The number of characters of the `birthName`, including spaces. */
89
92
  get length(): number;
90
93
  /** The prefix part of the name set. */
@@ -111,17 +114,40 @@ export declare class Namefully {
111
114
  get public(): string;
112
115
  /** The combination of prefix and last name. */
113
116
  get salutation(): string;
114
- /** Returns the full name as set. */
117
+ /**
118
+ * Returns an iterable of the name components in their natural form.
119
+ *
120
+ * Regardless of the order of appearance, this method will always return the
121
+ * existing `Name`s according to the name standards upon which this library
122
+ * is based.
123
+ *
124
+ * This is useful for iterating over the name parts in a consistent manner and
125
+ * this automatically enables operations such as mapping, filtering, etc.
126
+ */
127
+ get parts(): Iterable<Name>;
128
+ /** The number of name components. */
129
+ get size(): number;
130
+ /**
131
+ * Makes the name set iterable (i.e., for-of statements).
132
+ *
133
+ * This is similar to `parts` with the exception that all name components are
134
+ * returned as `Name` classes (instead of their natural form - e.g., `FirstName`)
135
+ * to maintain certain homogeneity and consistency across each name piece.
136
+ */
137
+ [Symbol.iterator](): Iterator<Name>;
138
+ /** Gets a string representation of the full name. */
115
139
  toString(): string;
116
140
  /** Fetches the raw form of a name piece. */
117
- get(namon: Namon): Nullable<Name | Name[]>;
141
+ get(key: Namon | string): Nullable<Name | Name[]>;
118
142
  /** Whether this name is equal to another one from a raw-string perspective. */
119
143
  equal(other: Namefully): boolean;
144
+ /** Whether this name is equal to another one from a component perspective. */
145
+ deepEqual(other: Namefully): boolean;
120
146
  /** Gets a JSON representation of the full name. */
121
147
  toJson(): JsonName;
122
148
  json: () => JsonName;
123
- /** Confirms that a name part has been set. */
124
- has(namon: Namon): boolean;
149
+ /** Confirms whether a name component exists. */
150
+ has(namon: Namon | string): boolean;
125
151
  /**
126
152
  * Gets the full name ordered as configured.
127
153
  *
@@ -129,21 +155,21 @@ export declare class Namefully {
129
155
  * name, overriding the preset configuration.
130
156
  *
131
157
  * `Namefully.format()` may also be used to alter manually the order of appearance
132
- * of full name. For example:
158
+ * of a full name. For example:
133
159
  * ```ts
134
160
  * const name = new Namefully('Jon Stark Snow');
135
161
  * console.log(name.fullName(NameOrder.LAST_NAME)); // "Snow Jon Stark"
136
162
  * console.log(name.format('l f m')); // "Snow Jon Stark"
137
163
  * ```
138
164
  */
139
- fullName(orderedBy?: NameOrder): string;
165
+ fullName(orderedBy?: NameOptions['orderedBy']): string;
140
166
  /**
141
167
  * Gets the birth name ordered as configured, no `prefix` or `suffix`.
142
168
  *
143
169
  * @param orderedBy forces to order by first or last name by overriding the
144
170
  * preset configuration.
145
171
  */
146
- birthName(orderedBy?: NameOrder): string;
172
+ birthName(orderedBy?: NameOptions['orderedBy']): string;
147
173
  /**
148
174
  * Gets the first name part of the `FullName`.
149
175
  * @param {boolean} withMore determines whether to include other pieces of the
@@ -157,7 +183,7 @@ export declare class Namefully {
157
183
  * @param {Surname} format overrides the how-to formatting of a surname output,
158
184
  * considering its sub-parts.
159
185
  */
160
- lastName(format?: Surname): string;
186
+ lastName(format?: NameOptions['surname']): string;
161
187
  /**
162
188
  * Gets the initials of the `FullName`.
163
189
  *
@@ -172,8 +198,8 @@ export declare class Namefully {
172
198
  * - `John Ben Smith` => `['J', 'B', 'S']`.
173
199
  */
174
200
  initials(options?: {
175
- orderedBy?: NameOrder;
176
- only?: NameType;
201
+ orderedBy?: NameOptions['orderedBy'];
202
+ only?: NameType | 'firstName' | 'lastName' | 'middleName' | 'birthName';
177
203
  asJson?: boolean;
178
204
  }): string[] | Record<string, string[]>;
179
205
  /**
@@ -193,7 +219,7 @@ export declare class Namefully {
193
219
  * For a given `FirstName FatherName MotherName`, shortening this name when
194
220
  * the surname is set as `mother` is equivalent to making it: `FirstName MotherName`.
195
221
  */
196
- shorten(orderedBy?: NameOrder): string;
222
+ shorten(orderedBy?: NameOptions['orderedBy']): string;
197
223
  /**
198
224
  * Flattens long names using the name types as variants.
199
225
  *
@@ -225,11 +251,11 @@ export declare class Namefully {
225
251
  */
226
252
  flatten(options: Partial<{
227
253
  limit: number;
228
- by: Flat;
254
+ by: Flat | 'firstName' | 'lastName' | 'middleName' | 'birthName' | 'firstMid' | 'midLast' | 'all' | '*';
229
255
  withPeriod: boolean;
230
256
  recursive: boolean;
231
257
  withMore: boolean;
232
- surname: Surname;
258
+ surname: NameOptions['surname'];
233
259
  }>): string;
234
260
  /**
235
261
  * Zips or compacts a name using different forms of variants.
@@ -263,14 +289,6 @@ export declare class Namefully {
263
289
  * - 'P': capitalized prefix
264
290
  * - 's': suffix
265
291
  * - 'S': capitalized suffix
266
- *
267
- * punctuations
268
- * ------------
269
- * - '.': period
270
- * - ',': comma
271
- * - ' ': space
272
- * - '-': hyphen
273
- * - '_': underscore
274
292
  * - '$': an escape character to select only the initial of the next char.
275
293
  *
276
294
  * Given the name `Joe Jim Smith`, use `format` with the `pattern` string.
@@ -312,11 +330,31 @@ export declare class Namefully {
312
330
  toDotCase(): string;
313
331
  /** Transforms a birth name into ToGgLeCaSe. */
314
332
  toToggleCase(): string;
333
+ /**
334
+ * Serializes this Namefully instance to a JSON object.
335
+ *
336
+ * This includes both the name data (with full hierarchy for FirstName and LastName)
337
+ * and the configuration, allowing for complete reconstruction of the Namefully instance.
338
+ *
339
+ * @returns a JSON-serializable object containing name data and config.
340
+ */
341
+ serialize(): SerializedName;
315
342
  }
316
343
  /**
317
344
  * A default export for the `namefully` utility.
318
345
  * @param names element to parse.
319
346
  * @param options additional settings.
320
347
  */
321
- declare const _default: (names: string | string[] | Name[] | JsonName | Parser, options?: Partial<Config>) => Namefully;
348
+ declare const _default: (names: string | string[] | Name[] | JsonName | Parser, options?: NameOptions) => Namefully;
322
349
  export default _default;
350
+ /** Optional namefully parameters (@see {@linkcode Config} for more details). */
351
+ export type NameOptions = Partial<{
352
+ name: string;
353
+ orderedBy: NameOrder | 'firstName' | 'lastName';
354
+ separator: Separator;
355
+ title: Title | 'UK' | 'US';
356
+ ending: boolean;
357
+ bypass: boolean;
358
+ surname: Surname | 'father' | 'mother' | 'hyphenated' | 'all';
359
+ mono: boolean | Namon;
360
+ }>;
@@ -1,8 +1,8 @@
1
1
  import { ALLOWED_FORMAT_TOKENS } from './constants.js';
2
- import { InputError, NotAllowedError } from './error.js';
3
2
  import { isNameArray } from './name.js';
4
- import { Flat, NameOrder, NameType, Namon } from './types.js';
3
+ import { InputError, NotAllowedError } from './error.js';
5
4
  import { capitalize, decapitalize, isStringArray, toggleCase } from './utils.js';
5
+ import { Flat, NameOrder, NameType, Namon } from './types.js';
6
6
  import { ArrayNameParser, ArrayStringParser, NamaParser, Parser, StringParser } from './parser.js';
7
7
  export class Namefully {
8
8
  #fullName;
@@ -23,7 +23,12 @@ export class Namefully {
23
23
  get config() {
24
24
  return this.#fullName.config;
25
25
  }
26
+ get isMono() {
27
+ return this.#fullName.isMono;
28
+ }
26
29
  get length() {
30
+ if (this.isMono)
31
+ return this.#fullName.toString().length;
27
32
  return this.birth.length;
28
33
  }
29
34
  get prefix() {
@@ -62,25 +67,43 @@ export class Namefully {
62
67
  get salutation() {
63
68
  return this.format('p l');
64
69
  }
70
+ get parts() {
71
+ return this.#fullName.toIterable();
72
+ }
73
+ get size() {
74
+ return Array.from(this.parts).length;
75
+ }
76
+ *[Symbol.iterator]() {
77
+ yield* this.#fullName.toIterable(true);
78
+ }
65
79
  toString() {
66
80
  return this.full;
67
81
  }
68
- get(namon) {
69
- if (namon.equal(Namon.PREFIX))
82
+ get(key) {
83
+ const namon = typeof key === 'string' ? Namon.cast(key) : key;
84
+ if (namon?.equal(Namon.PREFIX))
70
85
  return this.#fullName.prefix;
71
- if (namon.equal(Namon.FIRST_NAME))
86
+ if (namon?.equal(Namon.FIRST_NAME))
72
87
  return this.#fullName.firstName;
73
- if (namon.equal(Namon.MIDDLE_NAME))
88
+ if (namon?.equal(Namon.MIDDLE_NAME))
74
89
  return this.#fullName.middleName;
75
- if (namon.equal(Namon.LAST_NAME))
90
+ if (namon?.equal(Namon.LAST_NAME))
76
91
  return this.#fullName.lastName;
77
- if (namon.equal(Namon.SUFFIX))
92
+ if (namon?.equal(Namon.SUFFIX))
78
93
  return this.#fullName.suffix;
79
94
  return undefined;
80
95
  }
81
96
  equal(other) {
82
97
  return this.toString() === other.toString();
83
98
  }
99
+ deepEqual(other) {
100
+ const others = Array.from(other.parts);
101
+ for (const part of this.parts) {
102
+ if (!others.some((name) => name.equal(part)))
103
+ return false;
104
+ }
105
+ return true;
106
+ }
84
107
  toJson() {
85
108
  return {
86
109
  prefix: this.prefix,
@@ -95,6 +118,8 @@ export class Namefully {
95
118
  return this.#fullName.has(namon);
96
119
  }
97
120
  fullName(orderedBy) {
121
+ if (this.isMono)
122
+ return this.#fullName.toString();
98
123
  const sep = this.config.ending ? ',' : '';
99
124
  const names = [];
100
125
  if (this.prefix)
@@ -103,13 +128,21 @@ export class Namefully {
103
128
  names.push(this.first, ...this.middleName(), this.last + sep);
104
129
  }
105
130
  else {
106
- names.push(this.last, this.first, this.middleName().join(' ') + sep);
131
+ names.push(this.last);
132
+ if (this.hasMiddle) {
133
+ names.push(this.first, this.middleName().join(' ') + sep);
134
+ }
135
+ else {
136
+ names.push(this.first + sep);
137
+ }
107
138
  }
108
139
  if (this.suffix)
109
140
  names.push(this.suffix);
110
141
  return names.join(' ').trim();
111
142
  }
112
143
  birthName(orderedBy) {
144
+ if (this.isMono)
145
+ return this.#fullName.toString();
113
146
  orderedBy ??= this.config.orderedBy;
114
147
  return orderedBy === NameOrder.FIRST_NAME
115
148
  ? [this.first, ...this.middleName(), this.last].join(' ')
@@ -125,6 +158,8 @@ export class Namefully {
125
158
  return this.#fullName.lastName.toString(format);
126
159
  }
127
160
  initials(options) {
161
+ if (this.isMono)
162
+ return [this.#fullName.toString()[0]];
128
163
  const { orderedBy = this.config.orderedBy, only = NameType.BIRTH_NAME, asJson } = options ?? {};
129
164
  const firstInits = this.#fullName.firstName.initials();
130
165
  const midInits = this.#fullName.middleName.map((n) => n.value[0]);
@@ -142,6 +177,8 @@ export class Namefully {
142
177
  }
143
178
  }
144
179
  shorten(orderedBy) {
180
+ if (this.isMono)
181
+ return this.#fullName.toString();
145
182
  orderedBy ??= this.config.orderedBy;
146
183
  const { firstName, lastName } = this.#fullName;
147
184
  return orderedBy === NameOrder.FIRST_NAME
@@ -152,6 +189,8 @@ export class Namefully {
152
189
  const { by = Flat.MIDDLE_NAME, limit = 20, recursive = false, withMore = false, withPeriod = true, surname, } = options;
153
190
  if (this.length <= limit)
154
191
  return this.full;
192
+ if (this.isMono)
193
+ return `${this.initials()}${withPeriod ? '.' : ''}`;
155
194
  const { firstName, lastName, middleName } = this.#fullName;
156
195
  const sep = withPeriod ? '.' : '';
157
196
  const hasMid = this.hasMiddle;
@@ -179,7 +218,7 @@ export class Namefully {
179
218
  case Flat.MID_LAST:
180
219
  name = hasMid ? [fn, m, l] : [fn, l];
181
220
  break;
182
- case Flat.ALL:
221
+ default:
183
222
  name = hasMid ? [f, m, l] : [f, l];
184
223
  break;
185
224
  }
@@ -201,7 +240,7 @@ export class Namefully {
201
240
  case Flat.MID_LAST:
202
241
  name = hasMid ? [l, fn, m] : [l, fn];
203
242
  break;
204
- case Flat.ALL:
243
+ default:
205
244
  name = hasMid ? [l, f, m] : [l, f];
206
245
  break;
207
246
  }
@@ -242,7 +281,7 @@ export class Namefully {
242
281
  let group = '';
243
282
  const formatted = [];
244
283
  for (const char of pattern) {
245
- if (ALLOWED_FORMAT_TOKENS.indexOf(char) === -1) {
284
+ if (!ALLOWED_FORMAT_TOKENS.includes(char)) {
246
285
  throw new NotAllowedError({
247
286
  source: this.full,
248
287
  operation: 'format',
@@ -299,6 +338,28 @@ export class Namefully {
299
338
  toToggleCase() {
300
339
  return toggleCase(this.birth);
301
340
  }
341
+ serialize() {
342
+ const { config, firstName: fn, lastName: ln } = this.#fullName;
343
+ return {
344
+ names: {
345
+ prefix: this.prefix,
346
+ firstName: fn.hasMore ? { value: fn.value, more: fn.more } : fn.value,
347
+ middleName: this.hasMiddle ? this.middleName() : undefined,
348
+ lastName: ln.hasMother ? { father: ln.father, mother: ln.mother } : ln.value,
349
+ suffix: this.suffix,
350
+ },
351
+ config: {
352
+ name: config.name,
353
+ orderedBy: config.orderedBy,
354
+ separator: config.separator.token,
355
+ title: config.title,
356
+ ending: config.ending,
357
+ bypass: config.bypass,
358
+ surname: config.surname,
359
+ mono: config.mono instanceof Namon ? config.mono.key : config.mono,
360
+ },
361
+ };
362
+ }
302
363
  #toParser(raw) {
303
364
  if (raw instanceof Parser)
304
365
  return raw;
@@ -314,12 +375,6 @@ export class Namefully {
314
375
  }
315
376
  #map(char) {
316
377
  switch (char) {
317
- case '.':
318
- case ',':
319
- case ' ':
320
- case '-':
321
- case '_':
322
- return char;
323
378
  case 'b':
324
379
  return this.birth;
325
380
  case 'B':
@@ -361,16 +416,19 @@ export class Namefully {
361
416
  case 'S':
362
417
  return this.suffix?.toUpperCase();
363
418
  case '$f':
364
- case '$F':
365
419
  return this.#fullName.firstName.value[0];
420
+ case '$F':
421
+ return this.#fullName.firstName.initials(true).join('');
366
422
  case '$l':
367
- case '$L':
368
423
  return this.#fullName.lastName.value[0];
424
+ case '$L':
425
+ return this.#fullName.lastName.initials().join('');
369
426
  case '$m':
370
- case '$M':
371
427
  return this.hasMiddle ? this.middle[0] : undefined;
428
+ case '$M':
429
+ return this.hasMiddle ? this.#fullName.middleName.map((n) => n.value[0]).join('') : undefined;
372
430
  default:
373
- return undefined;
431
+ return ALLOWED_FORMAT_TOKENS.includes(char) ? char : undefined;
374
432
  }
375
433
  }
376
434
  }
@@ -1,6 +1,6 @@
1
1
  import { Config } from './config.js';
2
2
  import { NameIndex } from './utils.js';
3
- import { FullName } from './fullname.js';
3
+ import { FullName, Mononym } from './fullname.js';
4
4
  import { Name, JsonName } from './name.js';
5
5
  /**
6
6
  * A parser signature that helps to organize the names accordingly.
@@ -12,6 +12,11 @@ export declare abstract class Parser<T = unknown> {
12
12
  * @param raw data to be parsed
13
13
  */
14
14
  constructor(raw: T);
15
+ /**
16
+ * Parses raw data into a `FullName` while applying some options.
17
+ * @param options for additional configuration to apply.
18
+ */
19
+ abstract parse(options?: Partial<Config>): FullName;
15
20
  /**
16
21
  * Builds a dynamic `Parser` on the fly and throws a `NameError` when unable
17
22
  * to do so. The built parser only knows how to operate birth names.
@@ -19,11 +24,6 @@ export declare abstract class Parser<T = unknown> {
19
24
  static build(text: string, index?: NameIndex): Parser;
20
25
  /** Builds asynchronously a dynamic `Parser`. */
21
26
  static buildAsync(text: string, index?: NameIndex): Promise<Parser>;
22
- /**
23
- * Parses the raw data into a `FullName` while considering some options.
24
- * @param options for additional configuration to apply.
25
- */
26
- abstract parse(options?: Partial<Config>): FullName;
27
27
  }
28
28
  export declare class StringParser extends Parser<string> {
29
29
  parse(options: Partial<Config>): FullName;
@@ -37,3 +37,6 @@ export declare class NamaParser extends Parser<JsonName> {
37
37
  export declare class ArrayNameParser extends Parser<Name[]> {
38
38
  parse(options: Partial<Config>): FullName;
39
39
  }
40
+ export declare class MonoParser extends Parser<string | Name> {
41
+ parse(options: Partial<Config>): Mononym;
42
+ }
@@ -1,10 +1,10 @@
1
1
  import { Config } from './config.js';
2
2
  import { NameIndex } from './utils.js';
3
3
  import { InputError } from './error.js';
4
- import { FullName } from './fullname.js';
4
+ import { FullName, Mononym } from './fullname.js';
5
5
  import { Namon, Separator } from './types.js';
6
6
  import { FirstName, LastName, Name } from './name.js';
7
- import { ArrayStringValidator, ArrayNameValidator, NamaValidator } from './validator.js';
7
+ import { ArrayStringValidator, ArrayNameValidator, Validators } from './validator.js';
8
8
  export class Parser {
9
9
  raw;
10
10
  constructor(raw) {
@@ -20,10 +20,7 @@ export class Parser {
20
20
  return new ArrayNameParser(names);
21
21
  }
22
22
  if (length < 2) {
23
- throw new InputError({
24
- source: text,
25
- message: 'cannot build from invalid input',
26
- });
23
+ throw new InputError({ source: text, message: 'expecting at least 2 name parts' });
27
24
  }
28
25
  else if (length === 2 || length === 3) {
29
26
  return new StringParser(text);
@@ -47,13 +44,15 @@ export class StringParser extends Parser {
47
44
  parse(options) {
48
45
  const config = Config.merge(options);
49
46
  const names = this.raw.split(config.separator.token);
50
- return new ArrayStringParser(names).parse(options);
47
+ return new ArrayStringParser(names).parse(config);
51
48
  }
52
49
  }
53
50
  export class ArrayStringParser extends Parser {
54
51
  parse(options) {
55
52
  const config = Config.merge(options);
56
- const fullName = new FullName(config);
53
+ if (this.raw.length === 1 && config.mono) {
54
+ return new MonoParser(this.raw[0]).parse(config);
55
+ }
57
56
  const raw = this.raw.map((n) => n.trim());
58
57
  const index = NameIndex.when(config.orderedBy, raw.length);
59
58
  const validator = new ArrayStringValidator(index);
@@ -64,8 +63,9 @@ export class ArrayStringParser extends Parser {
64
63
  validator.validate(raw);
65
64
  }
66
65
  const { firstName, lastName, middleName, prefix, suffix } = index;
67
- fullName.setFirstName(new FirstName(raw[firstName]));
68
- fullName.setLastName(new LastName(raw[lastName]));
66
+ const fullName = new FullName(config)
67
+ .setFirstName(new FirstName(raw[firstName]))
68
+ .setLastName(new LastName(raw[lastName]));
69
69
  if (raw.length >= 3)
70
70
  fullName.setMiddleName(raw[middleName].split(config.separator.token));
71
71
  if (raw.length >= 4)
@@ -89,10 +89,10 @@ export class NamaParser extends Parser {
89
89
  return [namon, value];
90
90
  }));
91
91
  if (config.bypass) {
92
- NamaValidator.create().validateKeys(names);
92
+ Validators.nama.validateKeys(names);
93
93
  }
94
94
  else {
95
- NamaValidator.create().validate(names);
95
+ Validators.nama.validate(names);
96
96
  }
97
97
  return FullName.parse(this.raw, config);
98
98
  }
@@ -100,8 +100,13 @@ export class NamaParser extends Parser {
100
100
  export class ArrayNameParser extends Parser {
101
101
  parse(options) {
102
102
  const config = Config.merge(options);
103
+ if (this.raw.length === 1 && config.mono) {
104
+ return new MonoParser(this.raw[0]).parse(options);
105
+ }
106
+ else {
107
+ ArrayNameValidator.create().validate(this.raw);
108
+ }
103
109
  const fullName = new FullName(config);
104
- ArrayNameValidator.create().validate(this.raw);
105
110
  for (const name of this.raw) {
106
111
  if (name.isPrefix) {
107
112
  fullName.setPrefix(name);
@@ -116,10 +121,20 @@ export class ArrayNameParser extends Parser {
116
121
  fullName.middleName.push(name);
117
122
  }
118
123
  else if (name.isLastName) {
119
- const lastName = new LastName(name.value, name instanceof LastName ? name.mother : undefined, config.surname);
120
- fullName.setLastName(lastName);
124
+ const mother = name instanceof LastName ? name.mother : undefined;
125
+ fullName.setLastName(new LastName(name.value, mother, config.surname));
121
126
  }
122
127
  }
123
128
  return fullName;
124
129
  }
125
130
  }
131
+ export class MonoParser extends Parser {
132
+ parse(options) {
133
+ const config = Config.merge(options);
134
+ if (config.bypass)
135
+ Validators.namon.validate(this.raw);
136
+ const type = config.mono instanceof Namon ? config.mono : Namon.FIRST_NAME;
137
+ const name = this.raw instanceof Name ? this.raw : new Name(this.raw.trim(), type);
138
+ return new Mononym(name, config);
139
+ }
140
+ }
@@ -61,6 +61,7 @@ export declare class Namon {
61
61
  static readonly values: Namon[];
62
62
  /** All the predefined name types. */
63
63
  static readonly all: Map<string, Namon>;
64
+ private static readonly aliases;
64
65
  private constructor();
65
66
  /** Whether this string key is part of the predefined keys. */
66
67
  static has(key: string): boolean;
@@ -90,6 +91,8 @@ export declare class Separator {
90
91
  /** All the available tokens. */
91
92
  static readonly tokens: string[];
92
93
  private constructor();
94
+ /** Makes a string key a separator type. */
95
+ static cast(key: string): Nullable<Separator>;
93
96
  /** String representation of this object. */
94
97
  toString(): string;
95
98
  }
package/dist/esm/types.js CHANGED
@@ -53,6 +53,13 @@ export class Namon {
53
53
  [Namon.LAST_NAME.key, Namon.LAST_NAME],
54
54
  [Namon.SUFFIX.key, Namon.SUFFIX],
55
55
  ]);
56
+ static aliases = {
57
+ [Namon.PREFIX.key]: ['prefix', 'px', 'p'],
58
+ [Namon.FIRST_NAME.key]: ['firstname', 'first', 'fn', 'f'],
59
+ [Namon.MIDDLE_NAME.key]: ['middlename', 'middle', 'mid', 'mn', 'm'],
60
+ [Namon.LAST_NAME.key]: ['lastname', 'last', 'ln', 'l'],
61
+ [Namon.SUFFIX.key]: ['suffix', 'sx', 's'],
62
+ };
56
63
  constructor(index, key) {
57
64
  this.index = index;
58
65
  this.key = key;
@@ -61,7 +68,9 @@ export class Namon {
61
68
  return Namon.all.has(key);
62
69
  }
63
70
  static cast(key) {
64
- return Namon.has(key) ? Namon.all.get(key) : undefined;
71
+ const searchValue = String(key).toLowerCase();
72
+ const namon = Object.entries(Namon.aliases).find(([, list]) => list.includes(searchValue))?.[0];
73
+ return Namon.has(namon ?? '') ? Namon.all.get(key) : undefined;
65
74
  }
66
75
  toString() {
67
76
  return `Namon.${this.key}`;
@@ -100,6 +109,14 @@ export class Separator {
100
109
  this.name = name;
101
110
  this.token = token;
102
111
  }
112
+ static cast(key) {
113
+ for (const [name, separator] of Separator.all) {
114
+ if (separator.token === key || name.toLowerCase() === key.toLowerCase()) {
115
+ return separator;
116
+ }
117
+ }
118
+ return undefined;
119
+ }
103
120
  toString() {
104
121
  return `Separator.${this.name}`;
105
122
  }