namefully 2.0.0 → 2.0.2
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/dist/cjs/config.js +14 -5
- package/dist/cjs/constants.js +3 -3
- package/dist/cjs/error.js +4 -7
- package/dist/cjs/fullname.js +10 -11
- package/dist/cjs/name.js +18 -22
- package/dist/cjs/namefully.js +32 -40
- package/dist/cjs/parser.js +13 -15
- package/dist/cjs/utils.js +18 -25
- package/dist/cjs/validator.js +24 -39
- package/dist/esm/builder.d.ts +4 -2
- package/dist/esm/config.d.ts +6 -1
- package/dist/esm/config.js +14 -5
- package/dist/esm/constants.d.ts +2 -2
- package/dist/esm/constants.js +2 -2
- package/dist/esm/error.d.ts +10 -14
- package/dist/esm/error.js +4 -7
- package/dist/esm/fullname.d.ts +10 -12
- package/dist/esm/fullname.js +10 -11
- package/dist/esm/name.d.ts +12 -20
- package/dist/esm/name.js +18 -22
- package/dist/esm/namefully.d.ts +64 -65
- package/dist/esm/namefully.js +33 -41
- package/dist/esm/parser.d.ts +3 -6
- package/dist/esm/parser.js +13 -15
- package/dist/esm/types.d.ts +16 -48
- package/dist/esm/utils.d.ts +4 -5
- package/dist/esm/utils.js +18 -25
- package/dist/esm/validator.d.ts +1 -1
- package/dist/esm/validator.js +29 -44
- package/dist/namefully.js +124 -155
- package/dist/namefully.min.js +1 -1
- package/package.json +7 -7
- package/readme.md +16 -17
package/dist/esm/name.js
CHANGED
|
@@ -40,19 +40,19 @@ export class Name {
|
|
|
40
40
|
return this.type === Namon.SUFFIX;
|
|
41
41
|
}
|
|
42
42
|
static prefix(value) {
|
|
43
|
-
return new
|
|
43
|
+
return new Name(value, Namon.PREFIX);
|
|
44
44
|
}
|
|
45
45
|
static first(value) {
|
|
46
|
-
return new
|
|
46
|
+
return new Name(value, Namon.FIRST_NAME);
|
|
47
47
|
}
|
|
48
48
|
static middle(value) {
|
|
49
|
-
return new
|
|
49
|
+
return new Name(value, Namon.MIDDLE_NAME);
|
|
50
50
|
}
|
|
51
51
|
static last(value) {
|
|
52
|
-
return new
|
|
52
|
+
return new Name(value, Namon.LAST_NAME);
|
|
53
53
|
}
|
|
54
54
|
static suffix(value) {
|
|
55
|
-
return new
|
|
55
|
+
return new Name(value, Namon.SUFFIX);
|
|
56
56
|
}
|
|
57
57
|
initials() {
|
|
58
58
|
return [this.initial];
|
|
@@ -72,8 +72,8 @@ export class Name {
|
|
|
72
72
|
return this;
|
|
73
73
|
}
|
|
74
74
|
validate(name) {
|
|
75
|
-
if (name && name
|
|
76
|
-
throw new InputError({ source: name, message: 'must be
|
|
75
|
+
if (typeof name === 'string' && name.trim().length < 1) {
|
|
76
|
+
throw new InputError({ source: name, message: 'must be 1+ characters' });
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
@@ -81,7 +81,7 @@ export class FirstName extends Name {
|
|
|
81
81
|
#more;
|
|
82
82
|
constructor(value, ...more) {
|
|
83
83
|
super(value, Namon.FIRST_NAME);
|
|
84
|
-
more.forEach(
|
|
84
|
+
more.forEach(this.validate);
|
|
85
85
|
this.#more = more;
|
|
86
86
|
}
|
|
87
87
|
get hasMore() {
|
|
@@ -92,9 +92,8 @@ export class FirstName extends Name {
|
|
|
92
92
|
}
|
|
93
93
|
get asNames() {
|
|
94
94
|
const names = [Name.first(this.value)];
|
|
95
|
-
if (this.hasMore)
|
|
96
|
-
names.push(...this.#more.map(
|
|
97
|
-
}
|
|
95
|
+
if (this.hasMore)
|
|
96
|
+
names.push(...this.#more.map(Name.first));
|
|
98
97
|
return names;
|
|
99
98
|
}
|
|
100
99
|
get more() {
|
|
@@ -105,9 +104,8 @@ export class FirstName extends Name {
|
|
|
105
104
|
}
|
|
106
105
|
initials(withMore = false) {
|
|
107
106
|
const inits = [this.initial];
|
|
108
|
-
if (withMore && this.hasMore)
|
|
107
|
+
if (withMore && this.hasMore)
|
|
109
108
|
inits.push(...this.#more.map((n) => n[0]));
|
|
110
|
-
}
|
|
111
109
|
return inits;
|
|
112
110
|
}
|
|
113
111
|
caps(range) {
|
|
@@ -169,34 +167,32 @@ export class LastName extends Name {
|
|
|
169
167
|
}
|
|
170
168
|
}
|
|
171
169
|
initials(format) {
|
|
172
|
-
format = format || this.format;
|
|
173
170
|
const inits = [];
|
|
174
|
-
switch (format) {
|
|
175
|
-
case Surname.MOTHER:
|
|
176
|
-
if (this.#mother)
|
|
177
|
-
inits.push(this.#mother[0]);
|
|
178
|
-
break;
|
|
171
|
+
switch (format ?? this.format) {
|
|
179
172
|
case Surname.HYPHENATED:
|
|
180
173
|
case Surname.ALL:
|
|
181
174
|
inits.push(this.initial);
|
|
182
175
|
if (this.#mother)
|
|
183
176
|
inits.push(this.#mother[0]);
|
|
184
177
|
break;
|
|
185
|
-
case Surname.
|
|
178
|
+
case Surname.MOTHER:
|
|
179
|
+
if (this.#mother)
|
|
180
|
+
inits.push(this.#mother[0]);
|
|
181
|
+
break;
|
|
186
182
|
default:
|
|
187
183
|
inits.push(this.initial);
|
|
188
184
|
}
|
|
189
185
|
return inits;
|
|
190
186
|
}
|
|
191
187
|
caps(range) {
|
|
192
|
-
range
|
|
188
|
+
range ??= this.capsRange;
|
|
193
189
|
this.value = capitalize(this.value, range);
|
|
194
190
|
if (this.hasMother)
|
|
195
191
|
this.#mother = capitalize(this.#mother, range);
|
|
196
192
|
return this;
|
|
197
193
|
}
|
|
198
194
|
decaps(range) {
|
|
199
|
-
range
|
|
195
|
+
range ??= this.capsRange;
|
|
200
196
|
this.value = decapitalize(this.value, range);
|
|
201
197
|
if (this.hasMother)
|
|
202
198
|
this.#mother = decapitalize(this.#mother, range);
|
package/dist/esm/namefully.d.ts
CHANGED
|
@@ -1,74 +1,76 @@
|
|
|
1
1
|
import { Config } from './config.js';
|
|
2
2
|
import { Name, JsonName } from './name.js';
|
|
3
|
-
import { Parser } from './parser.js';
|
|
4
3
|
import { Flat, NameOrder, NameType, Namon, Nullable, Surname } from './types.js';
|
|
5
4
|
import { NameIndex } from './utils.js';
|
|
5
|
+
import { Parser } from './parser.js';
|
|
6
6
|
/**
|
|
7
|
-
* A
|
|
7
|
+
* A utility for organizing human names in a particular order, way, or shape.
|
|
8
8
|
*
|
|
9
|
-
* Though `namefully` is easy to use, it does not magically guess
|
|
10
|
-
* the name is what (prefix, suffix, first, last, or middle names).
|
|
11
|
-
* actually on how the name parts are indicated (i.e., their roles)
|
|
12
|
-
* it can perform internally certain operations and saves us some extra
|
|
13
|
-
* calculations/processing.
|
|
14
|
-
* distinct raw data shapes. This is intended to give some flexibility to
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
9
|
+
* Though `namefully` is designed to be easy to use, it does not magically guess
|
|
10
|
+
* which part of the name is what (prefix, suffix, first, last, or middle names).
|
|
11
|
+
* It relies actually on how the name parts are indicated (i.e., their roles)
|
|
12
|
+
* so that it can perform internally certain operations and saves us some extra
|
|
13
|
+
* calculations/processing. Additionally, `Namefully` objects may be created using
|
|
14
|
+
* distinct raw data shapes. This is intended to give some flexibility to you
|
|
15
|
+
* so that you are not bound to a particular data format (e.g., string).
|
|
16
|
+
* Follow the API reference to know how to harness its usability as this utility
|
|
17
|
+
* aims to save time in formatting names.
|
|
18
18
|
*
|
|
19
|
-
* `namefully` also works like a trapdoor. Once
|
|
20
|
-
* validated,
|
|
21
|
-
*
|
|
22
|
-
* instance of `Namefully` must be created. In
|
|
23
|
-
* Remember, this utility's primary objective is to help manipulate
|
|
19
|
+
* `namefully` also works like a trapdoor. Once some name data is provided and
|
|
20
|
+
* validated, you may only *access* it but not update any part of it. This
|
|
21
|
+
* means that *no editing* is possible. If the name is mistaken, a new
|
|
22
|
+
* instance of `Namefully` must be created. In simple terms, it's immutable.
|
|
23
|
+
* Remember, this utility's primary objective is to help manipulate human names,
|
|
24
|
+
* not the opposite.
|
|
24
25
|
*
|
|
25
|
-
* Note that the name standards used for the current version of this
|
|
26
|
-
*
|
|
26
|
+
* Note that the name standards used for the current version of this utility are
|
|
27
|
+
* as follows:
|
|
27
28
|
* `[prefix] firstName [middleName] lastName [suffix]`
|
|
28
|
-
*
|
|
29
|
+
* where the opening `[` and closing `]` brackets mean that these parts are optional.
|
|
29
30
|
* In other words, the most basic and typical case is a name that looks like
|
|
30
31
|
* this: `John Smith`, where `John` is the first name piece and `Smith`, the last
|
|
31
32
|
* name piece.
|
|
32
33
|
*
|
|
33
|
-
* @see https://www.fbiic.gov/public/2008/nov/Naming_practice_guide_UK_2006.pdf
|
|
34
|
+
* @see {@link https://www.fbiic.gov/public/2008/nov/Naming_practice_guide_UK_2006.pdf}
|
|
34
35
|
* for more info on name standards.
|
|
35
36
|
*
|
|
36
37
|
* **IMPORTANT**: Keep in mind that the order of appearance (or name order) matters
|
|
37
|
-
* and may be altered through
|
|
38
|
+
* and may be altered through configurable parameters, which will be seen later.
|
|
38
39
|
* By default, the order of appearance is as shown above and will be used as a
|
|
39
40
|
* basis for future examples and use cases.
|
|
40
41
|
*
|
|
41
|
-
* Once imported, all that is required to do is to create
|
|
42
|
-
*
|
|
42
|
+
* Once imported, all that is required to do is to create instances of `Namefully`
|
|
43
|
+
* as you see fit and the rest will follow.
|
|
43
44
|
*
|
|
44
45
|
* Some terminologies used across the library are:
|
|
45
|
-
* - namon: 1 piece of name (e.g.,
|
|
46
|
-
* - nama: 2+ pieces of name (e.g., first name + last name)
|
|
46
|
+
* - namon: 1 piece of name (e.g., prefix)
|
|
47
|
+
* - nama: a combination of 2+ pieces of name (e.g., first name + last name)
|
|
47
48
|
*
|
|
48
49
|
* Happy name handling 😊!
|
|
49
50
|
*/
|
|
50
51
|
export declare class Namefully {
|
|
51
52
|
#private;
|
|
52
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Creates a name with distinguishable parts.
|
|
53
55
|
* @param names element to parse.
|
|
54
56
|
* @param options additional settings.
|
|
55
57
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
58
|
+
* Optional parameters may be provided with specifics on how to treat a full
|
|
59
|
+
* name during its existence. All name parts must have at least one (1) character
|
|
60
|
+
* to proceed. That is the only requirement/validation of namefully.
|
|
59
61
|
*/
|
|
60
62
|
constructor(names: string | string[] | Name[] | JsonName | Parser, options?: Partial<Config>);
|
|
61
63
|
/**
|
|
62
64
|
* Constructs a `Namefully` instance from a text.
|
|
63
65
|
*
|
|
64
|
-
* It works like `parse` except that this function returns `
|
|
65
|
-
* would throw a `NameError`.
|
|
66
|
+
* It works like `parse` except that this function returns `undefined` when
|
|
67
|
+
* `parse` would throw a `NameError`.
|
|
66
68
|
*/
|
|
67
69
|
static tryParse(text: string, index?: NameIndex): Namefully | undefined;
|
|
68
70
|
/**
|
|
69
71
|
* Constructs a `Namefully` instance from a text.
|
|
70
72
|
*
|
|
71
|
-
*
|
|
73
|
+
* @throws a `NameError` if the @param text cannot be parsed. Use `tryParse`
|
|
72
74
|
* instead if a `null` return is preferred over a throwable error.
|
|
73
75
|
*
|
|
74
76
|
* This operation is computed asynchronously, which gives more flexibility at
|
|
@@ -81,27 +83,27 @@ export declare class Namefully {
|
|
|
81
83
|
* process.
|
|
82
84
|
*/
|
|
83
85
|
static parse(text: string, index?: NameIndex): Promise<Namefully>;
|
|
84
|
-
/** The
|
|
86
|
+
/** The configuration dictating this name's behavior. */
|
|
85
87
|
get config(): Config;
|
|
86
88
|
/** The number of characters of the `birthName`, including spaces. */
|
|
87
89
|
get length(): number;
|
|
88
|
-
/** The prefix part. */
|
|
90
|
+
/** The prefix part of the name set. */
|
|
89
91
|
get prefix(): string | undefined;
|
|
90
|
-
/** The firt name part. */
|
|
92
|
+
/** The firt name part of the name set. */
|
|
91
93
|
get first(): string;
|
|
92
|
-
/** The first middle name part if any. */
|
|
94
|
+
/** The first middle name part of the name set if any. */
|
|
93
95
|
get middle(): string | undefined;
|
|
94
96
|
/** Returns true if any middle name has been set. */
|
|
95
97
|
get hasMiddle(): boolean;
|
|
96
|
-
/** The last name part. */
|
|
98
|
+
/** The last name part of the name set. */
|
|
97
99
|
get last(): string;
|
|
98
|
-
/** The suffix part. */
|
|
100
|
+
/** The suffix part of the name set. */
|
|
99
101
|
get suffix(): string | undefined;
|
|
100
|
-
/** The birth name part. */
|
|
102
|
+
/** The birth name part of the name set. */
|
|
101
103
|
get birth(): string;
|
|
102
|
-
/** The shortest version of a
|
|
104
|
+
/** The shortest version of a human name (first + last name). */
|
|
103
105
|
get short(): string;
|
|
104
|
-
/** The longest version of a
|
|
106
|
+
/** The longest version of a human name (a.k.a birth name). */
|
|
105
107
|
get long(): string;
|
|
106
108
|
/** The entire name set. */
|
|
107
109
|
get full(): string;
|
|
@@ -117,18 +119,17 @@ export declare class Namefully {
|
|
|
117
119
|
equal(other: Namefully): boolean;
|
|
118
120
|
/** Gets a JSON representation of the full name. */
|
|
119
121
|
toJson(): JsonName;
|
|
122
|
+
json: () => JsonName;
|
|
120
123
|
/** Confirms that a name part has been set. */
|
|
121
124
|
has(namon: Namon): boolean;
|
|
122
125
|
/**
|
|
123
126
|
* Gets the full name ordered as configured.
|
|
124
127
|
*
|
|
125
|
-
*
|
|
126
|
-
* overriding the preset configuration.
|
|
127
|
-
*
|
|
128
|
-
* `Namefully.format` may also be used to alter manually the order of appearance
|
|
129
|
-
* of full name.
|
|
128
|
+
* @param {NameOrder} orderedBy forces to arrange a name set by first or last
|
|
129
|
+
* name, overriding the preset configuration.
|
|
130
130
|
*
|
|
131
|
-
*
|
|
131
|
+
* `Namefully.format()` may also be used to alter manually the order of appearance
|
|
132
|
+
* of full name. For example:
|
|
132
133
|
* ```ts
|
|
133
134
|
* const name = new Namefully('Jon Stark Snow');
|
|
134
135
|
* console.log(name.fullName(NameOrder.LAST_NAME)); // "Snow Jon Stark"
|
|
@@ -145,26 +146,26 @@ export declare class Namefully {
|
|
|
145
146
|
birthName(orderedBy?: NameOrder): string;
|
|
146
147
|
/**
|
|
147
148
|
* Gets the first name part of the `FullName`.
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
* name.
|
|
149
|
+
* @param {boolean} withMore determines whether to include other pieces of the
|
|
150
|
+
* first name.
|
|
151
151
|
*/
|
|
152
152
|
firstName(withMore?: boolean): string;
|
|
153
153
|
/** Gets the middle name part of the `FullName`. */
|
|
154
154
|
middleName(): string[];
|
|
155
155
|
/**
|
|
156
156
|
* Gets the last name part of the `FullName`.
|
|
157
|
-
*
|
|
158
|
-
* @param format overrides the how-to formatting of a surname output,
|
|
157
|
+
* @param {Surname} format overrides the how-to formatting of a surname output,
|
|
159
158
|
* considering its sub-parts.
|
|
160
159
|
*/
|
|
161
160
|
lastName(format?: Surname): string;
|
|
162
161
|
/**
|
|
163
162
|
* Gets the initials of the `FullName`.
|
|
164
163
|
*
|
|
165
|
-
* @param {
|
|
164
|
+
* @param {object} options when getting the initials.
|
|
165
|
+
* @param {NameOrder} options.orderedBy forces to order by first or last name by
|
|
166
166
|
* overriding the preset configuration.
|
|
167
|
-
* @param
|
|
167
|
+
* @param {NameType} options.only selects initials of only certain name parts.
|
|
168
|
+
* @param {boolean} options.asJson whether to return initials as an array or JSON.
|
|
168
169
|
*
|
|
169
170
|
* For example, given the names:
|
|
170
171
|
* - `John Smith` => `['J', 'S']`
|
|
@@ -179,23 +180,22 @@ export declare class Namefully {
|
|
|
179
180
|
* Shortens a complex full name to a simple typical name, a combination of
|
|
180
181
|
* first and last name.
|
|
181
182
|
*
|
|
182
|
-
* @param orderedBy forces to order by first or last name
|
|
183
|
-
* preset configuration.
|
|
183
|
+
* @param {NameOrder} orderedBy forces to order by first or last name, overriding
|
|
184
|
+
* the preset configuration.
|
|
184
185
|
*
|
|
185
186
|
* For a given name such as `Mr Keanu Charles Reeves`, shortening this name
|
|
186
187
|
* is equivalent to making it `Keanu Reeves`.
|
|
187
188
|
*
|
|
188
189
|
* As a shortened name, the namon of the first name is favored over the other
|
|
189
|
-
* names forming part of the entire first names, if any. Meanwhile, for
|
|
190
|
-
*
|
|
190
|
+
* names forming part of the entire first names, if any. Meanwhile, for the
|
|
191
|
+
* last name, the configured `surname` is prioritized.
|
|
191
192
|
*
|
|
192
193
|
* For a given `FirstName FatherName MotherName`, shortening this name when
|
|
193
|
-
* the surname is set as `mother` is equivalent to making it:
|
|
194
|
-
* `FirstName MotherName`.
|
|
194
|
+
* the surname is set as `mother` is equivalent to making it: `FirstName MotherName`.
|
|
195
195
|
*/
|
|
196
196
|
shorten(orderedBy?: NameOrder): string;
|
|
197
197
|
/**
|
|
198
|
-
* Flattens
|
|
198
|
+
* Flattens long names using the name types as variants.
|
|
199
199
|
*
|
|
200
200
|
* While @param limit sets a threshold as a limited number of characters
|
|
201
201
|
* supported to flatten a `FullName`, @param by indicates which variant
|
|
@@ -233,13 +233,12 @@ export declare class Namefully {
|
|
|
233
233
|
}>): string;
|
|
234
234
|
/**
|
|
235
235
|
* Zips or compacts a name using different forms of variants.
|
|
236
|
-
*
|
|
237
236
|
* @see `flatten()` for more details.
|
|
238
237
|
*/
|
|
239
238
|
zip(by?: Flat, withPeriod?: boolean): string;
|
|
240
239
|
/**
|
|
241
240
|
* Formats the full name as desired.
|
|
242
|
-
* @param pattern character used to format it.
|
|
241
|
+
* @param {string} pattern character used to format it.
|
|
243
242
|
*
|
|
244
243
|
* string format
|
|
245
244
|
* -------------
|
|
@@ -285,7 +284,7 @@ export declare class Namefully {
|
|
|
285
284
|
* first, middle, and last names.
|
|
286
285
|
*/
|
|
287
286
|
format(pattern: string): string;
|
|
288
|
-
/** Flips
|
|
287
|
+
/** Flips or swaps the name order from the preset/current config. */
|
|
289
288
|
flip(): void;
|
|
290
289
|
/**
|
|
291
290
|
* Splits the name parts of a birth name.
|
|
@@ -294,7 +293,7 @@ export declare class Namefully {
|
|
|
294
293
|
split(separator?: string | RegExp): string[];
|
|
295
294
|
/**
|
|
296
295
|
* Joins the name parts of a birth name.
|
|
297
|
-
* @param separator token for the junction.
|
|
296
|
+
* @param {string} separator token for the junction.
|
|
298
297
|
*/
|
|
299
298
|
join(separator?: string): string;
|
|
300
299
|
/** Transforms a birth name into UPPERCASE. */
|
package/dist/esm/namefully.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ALLOWED_FORMAT_TOKENS } from './constants.js';
|
|
2
2
|
import { InputError, NotAllowedError } from './error.js';
|
|
3
3
|
import { isNameArray } from './name.js';
|
|
4
|
-
import { ArrayNameParser, ArrayStringParser, NamaParser, Parser, StringParser } from './parser.js';
|
|
5
4
|
import { Flat, NameOrder, NameType, Namon } from './types.js';
|
|
6
5
|
import { capitalize, decapitalize, isStringArray, toggleCase } from './utils.js';
|
|
6
|
+
import { ArrayNameParser, ArrayStringParser, NamaParser, Parser, StringParser } from './parser.js';
|
|
7
7
|
export class Namefully {
|
|
8
8
|
#fullName;
|
|
9
9
|
constructor(names, options) {
|
|
@@ -90,16 +90,16 @@ export class Namefully {
|
|
|
90
90
|
suffix: this.suffix,
|
|
91
91
|
};
|
|
92
92
|
}
|
|
93
|
+
json = this.toJson;
|
|
93
94
|
has(namon) {
|
|
94
95
|
return this.#fullName.has(namon);
|
|
95
96
|
}
|
|
96
97
|
fullName(orderedBy) {
|
|
97
98
|
const sep = this.config.ending ? ',' : '';
|
|
98
99
|
const names = [];
|
|
99
|
-
orderedBy = orderedBy || this.config.orderedBy;
|
|
100
100
|
if (this.prefix)
|
|
101
101
|
names.push(this.prefix);
|
|
102
|
-
if (orderedBy === NameOrder.FIRST_NAME) {
|
|
102
|
+
if ((orderedBy ?? this.config.orderedBy) === NameOrder.FIRST_NAME) {
|
|
103
103
|
names.push(this.first, ...this.middleName(), this.last + sep);
|
|
104
104
|
}
|
|
105
105
|
else {
|
|
@@ -110,7 +110,7 @@ export class Namefully {
|
|
|
110
110
|
return names.join(' ').trim();
|
|
111
111
|
}
|
|
112
112
|
birthName(orderedBy) {
|
|
113
|
-
orderedBy
|
|
113
|
+
orderedBy ??= this.config.orderedBy;
|
|
114
114
|
return orderedBy === NameOrder.FIRST_NAME
|
|
115
115
|
? [this.first, ...this.middleName(), this.last].join(' ')
|
|
116
116
|
: [this.last, this.first, ...this.middleName()].join(' ');
|
|
@@ -125,50 +125,42 @@ export class Namefully {
|
|
|
125
125
|
return this.#fullName.lastName.toString(format);
|
|
126
126
|
}
|
|
127
127
|
initials(options) {
|
|
128
|
+
const { orderedBy = this.config.orderedBy, only = NameType.BIRTH_NAME, asJson } = options ?? {};
|
|
128
129
|
const firstInits = this.#fullName.firstName.initials();
|
|
129
|
-
const midInits = this.#fullName.middleName.map((n) => n.
|
|
130
|
+
const midInits = this.#fullName.middleName.map((n) => n.value[0]);
|
|
130
131
|
const lastInits = this.#fullName.lastName.initials();
|
|
131
|
-
if (
|
|
132
|
+
if (asJson)
|
|
132
133
|
return { firstName: firstInits, middleName: midInits, lastName: lastInits };
|
|
133
|
-
const initials = [];
|
|
134
|
-
const { orderedBy = this.config.orderedBy, only = NameType.BIRTH_NAME } = options ?? {};
|
|
135
134
|
if (only !== NameType.BIRTH_NAME) {
|
|
136
|
-
|
|
137
|
-
initials.push(...firstInits);
|
|
138
|
-
}
|
|
139
|
-
else if (only === NameType.MIDDLE_NAME) {
|
|
140
|
-
initials.push(...midInits);
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
initials.push(...lastInits);
|
|
144
|
-
}
|
|
135
|
+
return only === NameType.FIRST_NAME ? firstInits : only === NameType.MIDDLE_NAME ? midInits : lastInits;
|
|
145
136
|
}
|
|
146
137
|
else if (orderedBy === NameOrder.FIRST_NAME) {
|
|
147
|
-
|
|
138
|
+
return [...firstInits, ...midInits, ...lastInits];
|
|
148
139
|
}
|
|
149
140
|
else {
|
|
150
|
-
|
|
141
|
+
return [...lastInits, ...firstInits, ...midInits];
|
|
151
142
|
}
|
|
152
|
-
return initials;
|
|
153
143
|
}
|
|
154
144
|
shorten(orderedBy) {
|
|
155
|
-
orderedBy
|
|
145
|
+
orderedBy ??= this.config.orderedBy;
|
|
146
|
+
const { firstName, lastName } = this.#fullName;
|
|
156
147
|
return orderedBy === NameOrder.FIRST_NAME
|
|
157
|
-
? [
|
|
158
|
-
: [
|
|
148
|
+
? [firstName.value, lastName.toString()].join(' ')
|
|
149
|
+
: [lastName.toString(), firstName.value].join(' ');
|
|
159
150
|
}
|
|
160
151
|
flatten(options) {
|
|
161
152
|
const { by = Flat.MIDDLE_NAME, limit = 20, recursive = false, withMore = false, withPeriod = true, surname, } = options;
|
|
162
153
|
if (this.length <= limit)
|
|
163
154
|
return this.full;
|
|
155
|
+
const { firstName, lastName, middleName } = this.#fullName;
|
|
164
156
|
const sep = withPeriod ? '.' : '';
|
|
165
|
-
const fn = this.#fullName.firstName.toString();
|
|
166
|
-
const mn = this.middleName().join(' ');
|
|
167
|
-
const ln = this.#fullName.lastName.toString();
|
|
168
157
|
const hasMid = this.hasMiddle;
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
const
|
|
158
|
+
const fn = firstName.toString();
|
|
159
|
+
const mn = this.middleName().join(' ');
|
|
160
|
+
const ln = lastName.toString();
|
|
161
|
+
const f = firstName.initials(withMore).join(sep + ' ') + sep;
|
|
162
|
+
const l = lastName.initials(surname).join(sep + ' ') + sep;
|
|
163
|
+
const m = hasMid ? middleName.map((n) => n.value[0]).join(sep + ' ') + sep : '';
|
|
172
164
|
let name = [];
|
|
173
165
|
if (this.config.orderedBy === NameOrder.FIRST_NAME) {
|
|
174
166
|
switch (by) {
|
|
@@ -249,8 +241,8 @@ export class Namefully {
|
|
|
249
241
|
pattern = 'o';
|
|
250
242
|
let group = '';
|
|
251
243
|
const formatted = [];
|
|
252
|
-
for (const char of pattern
|
|
253
|
-
if (
|
|
244
|
+
for (const char of pattern) {
|
|
245
|
+
if (ALLOWED_FORMAT_TOKENS.indexOf(char) === -1) {
|
|
254
246
|
throw new NotAllowedError({
|
|
255
247
|
source: this.full,
|
|
256
248
|
operation: 'format',
|
|
@@ -266,7 +258,8 @@ export class Namefully {
|
|
|
266
258
|
return formatted.join('').trim();
|
|
267
259
|
}
|
|
268
260
|
flip() {
|
|
269
|
-
this.config.
|
|
261
|
+
const order = this.config.orderedBy === NameOrder.FIRST_NAME ? NameOrder.LAST_NAME : NameOrder.FIRST_NAME;
|
|
262
|
+
this.config.update({ orderedBy: order });
|
|
270
263
|
}
|
|
271
264
|
split(separator = /[' -]/g) {
|
|
272
265
|
return this.birth.replace(separator, ' ').split(' ');
|
|
@@ -317,7 +310,7 @@ export class Namefully {
|
|
|
317
310
|
return new ArrayNameParser(raw);
|
|
318
311
|
if (typeof raw === 'object')
|
|
319
312
|
return new NamaParser(raw);
|
|
320
|
-
throw new InputError({ source: raw, message: 'Cannot parse raw data
|
|
313
|
+
throw new InputError({ source: raw, message: 'Cannot parse raw data; review expected data types.' });
|
|
321
314
|
}
|
|
322
315
|
#map(char) {
|
|
323
316
|
switch (char) {
|
|
@@ -345,16 +338,15 @@ export class Namefully {
|
|
|
345
338
|
case 'o':
|
|
346
339
|
case 'O':
|
|
347
340
|
return ((character) => {
|
|
348
|
-
const sep = this.config.ending ? ',' : ''
|
|
341
|
+
const sep = this.config.ending ? ',' : '';
|
|
342
|
+
const names = [];
|
|
349
343
|
if (this.prefix)
|
|
350
344
|
names.push(this.prefix);
|
|
351
345
|
names.push(`${this.last},`.toUpperCase());
|
|
352
|
-
if (this.hasMiddle)
|
|
346
|
+
if (this.hasMiddle)
|
|
353
347
|
names.push(this.first, this.middleName().join(' ') + sep);
|
|
354
|
-
|
|
355
|
-
else {
|
|
348
|
+
else
|
|
356
349
|
names.push(this.first + sep);
|
|
357
|
-
}
|
|
358
350
|
if (this.suffix)
|
|
359
351
|
names.push(this.suffix);
|
|
360
352
|
const nama = names.join(' ').trim();
|
|
@@ -370,10 +362,10 @@ export class Namefully {
|
|
|
370
362
|
return this.suffix?.toUpperCase();
|
|
371
363
|
case '$f':
|
|
372
364
|
case '$F':
|
|
373
|
-
return this.#fullName.firstName.
|
|
365
|
+
return this.#fullName.firstName.value[0];
|
|
374
366
|
case '$l':
|
|
375
367
|
case '$L':
|
|
376
|
-
return this.#fullName.lastName.
|
|
368
|
+
return this.#fullName.lastName.value[0];
|
|
377
369
|
case '$m':
|
|
378
370
|
case '$M':
|
|
379
371
|
return this.hasMiddle ? this.middle[0] : undefined;
|
package/dist/esm/parser.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { FullName } from './fullname.js';
|
|
2
1
|
import { Config } from './config.js';
|
|
3
2
|
import { NameIndex } from './utils.js';
|
|
3
|
+
import { FullName } 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.
|
|
@@ -17,13 +17,11 @@ export declare abstract class Parser<T = unknown> {
|
|
|
17
17
|
* to do so. The built parser only knows how to operate birth names.
|
|
18
18
|
*/
|
|
19
19
|
static build(text: string, index?: NameIndex): Parser;
|
|
20
|
-
/**
|
|
21
|
-
* Builds asynchronously a dynamic `Parser`.
|
|
22
|
-
*/
|
|
20
|
+
/** Builds asynchronously a dynamic `Parser`. */
|
|
23
21
|
static buildAsync(text: string, index?: NameIndex): Promise<Parser>;
|
|
24
22
|
/**
|
|
25
23
|
* Parses the raw data into a `FullName` while considering some options.
|
|
26
|
-
* @param options additional configuration to apply.
|
|
24
|
+
* @param options for additional configuration to apply.
|
|
27
25
|
*/
|
|
28
26
|
abstract parse(options?: Partial<Config>): FullName;
|
|
29
27
|
}
|
|
@@ -34,7 +32,6 @@ export declare class ArrayStringParser extends Parser<string[]> {
|
|
|
34
32
|
parse(options: Partial<Config>): FullName;
|
|
35
33
|
}
|
|
36
34
|
export declare class NamaParser extends Parser<JsonName> {
|
|
37
|
-
#private;
|
|
38
35
|
parse(options: Partial<Config>): FullName;
|
|
39
36
|
}
|
|
40
37
|
export declare class ArrayNameParser extends Parser<Name[]> {
|
package/dist/esm/parser.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { FullName } from './fullname.js';
|
|
2
1
|
import { Config } from './config.js';
|
|
3
2
|
import { NameIndex } from './utils.js';
|
|
4
|
-
import { ArrayStringValidator, ArrayNameValidator, NamaValidator } from './validator.js';
|
|
5
|
-
import { FirstName, LastName, Name } from './name.js';
|
|
6
|
-
import { Namon, Separator } from './types.js';
|
|
7
3
|
import { InputError } from './error.js';
|
|
4
|
+
import { FullName } from './fullname.js';
|
|
5
|
+
import { Namon, Separator } from './types.js';
|
|
6
|
+
import { FirstName, LastName, Name } from './name.js';
|
|
7
|
+
import { ArrayStringValidator, ArrayNameValidator, NamaValidator } from './validator.js';
|
|
8
8
|
export class Parser {
|
|
9
9
|
raw;
|
|
10
10
|
constructor(raw) {
|
|
@@ -14,7 +14,7 @@ export class Parser {
|
|
|
14
14
|
const parts = text.trim().split(Separator.SPACE.token);
|
|
15
15
|
const length = parts.length;
|
|
16
16
|
if (index instanceof NameIndex) {
|
|
17
|
-
const names = Object.entries(index.
|
|
17
|
+
const names = Object.entries(index.json())
|
|
18
18
|
.filter(([, position]) => position > -1 && position < length)
|
|
19
19
|
.map(([key, position]) => new Name(parts[position], Namon.all.get(key)));
|
|
20
20
|
return new ArrayNameParser(names);
|
|
@@ -78,16 +78,7 @@ export class ArrayStringParser extends Parser {
|
|
|
78
78
|
export class NamaParser extends Parser {
|
|
79
79
|
parse(options) {
|
|
80
80
|
const config = Config.merge(options);
|
|
81
|
-
|
|
82
|
-
NamaValidator.create().validateKeys(this.#asNama());
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
NamaValidator.create().validate(this.#asNama());
|
|
86
|
-
}
|
|
87
|
-
return FullName.parse(this.raw, config);
|
|
88
|
-
}
|
|
89
|
-
#asNama() {
|
|
90
|
-
return new Map(Object.entries(this.raw).map(([key, value]) => {
|
|
81
|
+
const names = new Map(Object.entries(this.raw).map(([key, value]) => {
|
|
91
82
|
const namon = Namon.cast(key);
|
|
92
83
|
if (!namon) {
|
|
93
84
|
throw new InputError({
|
|
@@ -97,6 +88,13 @@ export class NamaParser extends Parser {
|
|
|
97
88
|
}
|
|
98
89
|
return [namon, value];
|
|
99
90
|
}));
|
|
91
|
+
if (config.bypass) {
|
|
92
|
+
NamaValidator.create().validateKeys(names);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
NamaValidator.create().validate(names);
|
|
96
|
+
}
|
|
97
|
+
return FullName.parse(this.raw, config);
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
export class ArrayNameParser extends Parser {
|