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.
- package/dist/cjs/builder.js +6 -3
- package/dist/cjs/config.js +10 -5
- package/dist/cjs/constants.js +4 -26
- package/dist/cjs/data.js +42 -0
- package/dist/cjs/fullname.js +75 -8
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/name.js +1 -1
- package/dist/cjs/namefully.js +80 -22
- package/dist/cjs/parser.js +30 -14
- package/dist/cjs/types.js +18 -1
- package/dist/esm/builder.d.ts +2 -2
- package/dist/esm/builder.js +6 -3
- package/dist/esm/config.d.ts +4 -10
- package/dist/esm/config.js +10 -5
- package/dist/esm/constants.d.ts +3 -2
- package/dist/esm/constants.js +3 -25
- package/dist/esm/data.d.ts +31 -0
- package/dist/esm/data.js +38 -0
- package/dist/esm/fullname.d.ts +38 -1
- package/dist/esm/fullname.js +73 -7
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/name.d.ts +13 -7
- package/dist/esm/name.js +1 -1
- package/dist/esm/namefully.d.ts +64 -26
- package/dist/esm/namefully.js +80 -22
- package/dist/esm/parser.d.ts +9 -6
- package/dist/esm/parser.js +30 -15
- package/dist/esm/types.d.ts +3 -0
- package/dist/esm/types.js +18 -1
- package/dist/namefully.js +251 -74
- package/dist/namefully.min.js +1 -1
- package/package.json +2 -2
- package/readme.md +28 -4
package/dist/namefully.js
CHANGED
|
@@ -4,33 +4,11 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.namefully = {}));
|
|
5
5
|
})(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
|
-
const VERSION = '2.0
|
|
7
|
+
const VERSION = '2.2.0';
|
|
8
8
|
const MIN_NUMBER_OF_NAME_PARTS = 2;
|
|
9
9
|
const MAX_NUMBER_OF_NAME_PARTS = 5;
|
|
10
|
-
const ALLOWED_FORMAT_TOKENS = [
|
|
11
|
-
|
|
12
|
-
',',
|
|
13
|
-
' ',
|
|
14
|
-
'-',
|
|
15
|
-
'_',
|
|
16
|
-
'b',
|
|
17
|
-
'B',
|
|
18
|
-
'f',
|
|
19
|
-
'F',
|
|
20
|
-
'l',
|
|
21
|
-
'L',
|
|
22
|
-
'm',
|
|
23
|
-
'M',
|
|
24
|
-
'n',
|
|
25
|
-
'N',
|
|
26
|
-
'o',
|
|
27
|
-
'O',
|
|
28
|
-
'p',
|
|
29
|
-
'P',
|
|
30
|
-
's',
|
|
31
|
-
'S',
|
|
32
|
-
'$',
|
|
33
|
-
];
|
|
10
|
+
const ALLOWED_FORMAT_TOKENS = ` .,_-()[]<>'"bBfFlLmMnNoOpPsS$`;
|
|
11
|
+
const ZERO_WIDTH_SPACE = String.fromCharCode(8203);
|
|
34
12
|
|
|
35
13
|
exports.Title = void 0;
|
|
36
14
|
(function (Title) {
|
|
@@ -87,6 +65,13 @@
|
|
|
87
65
|
[Namon.LAST_NAME.key, Namon.LAST_NAME],
|
|
88
66
|
[Namon.SUFFIX.key, Namon.SUFFIX],
|
|
89
67
|
]);
|
|
68
|
+
static aliases = {
|
|
69
|
+
[Namon.PREFIX.key]: ['prefix', 'px', 'p'],
|
|
70
|
+
[Namon.FIRST_NAME.key]: ['firstname', 'first', 'fn', 'f'],
|
|
71
|
+
[Namon.MIDDLE_NAME.key]: ['middlename', 'middle', 'mid', 'mn', 'm'],
|
|
72
|
+
[Namon.LAST_NAME.key]: ['lastname', 'last', 'ln', 'l'],
|
|
73
|
+
[Namon.SUFFIX.key]: ['suffix', 'sx', 's'],
|
|
74
|
+
};
|
|
90
75
|
constructor(index, key) {
|
|
91
76
|
this.index = index;
|
|
92
77
|
this.key = key;
|
|
@@ -95,7 +80,9 @@
|
|
|
95
80
|
return Namon.all.has(key);
|
|
96
81
|
}
|
|
97
82
|
static cast(key) {
|
|
98
|
-
|
|
83
|
+
const searchValue = String(key).toLowerCase();
|
|
84
|
+
const namon = Object.entries(Namon.aliases).find(([, list]) => list.includes(searchValue))?.[0];
|
|
85
|
+
return Namon.has(namon ?? '') ? Namon.all.get(key) : undefined;
|
|
99
86
|
}
|
|
100
87
|
toString() {
|
|
101
88
|
return `Namon.${this.key}`;
|
|
@@ -134,6 +121,14 @@
|
|
|
134
121
|
this.name = name;
|
|
135
122
|
this.token = token;
|
|
136
123
|
}
|
|
124
|
+
static cast(key) {
|
|
125
|
+
for (const [name, separator] of Separator.all) {
|
|
126
|
+
if (separator.token === key || name.toLowerCase() === key.toLowerCase()) {
|
|
127
|
+
return separator;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
137
132
|
toString() {
|
|
138
133
|
return `Separator.${this.name}`;
|
|
139
134
|
}
|
|
@@ -472,7 +467,7 @@
|
|
|
472
467
|
return this.mother ?? '';
|
|
473
468
|
case exports.Surname.HYPHENATED:
|
|
474
469
|
return this.hasMother ? `${this.value}-${this.#mother}` : this.value;
|
|
475
|
-
|
|
470
|
+
default:
|
|
476
471
|
return this.hasMother ? `${this.value} ${this.#mother}` : this.value;
|
|
477
472
|
}
|
|
478
473
|
}
|
|
@@ -527,6 +522,7 @@
|
|
|
527
522
|
#ending;
|
|
528
523
|
#bypass;
|
|
529
524
|
#surname;
|
|
525
|
+
#mono;
|
|
530
526
|
static cache = new Map();
|
|
531
527
|
get orderedBy() {
|
|
532
528
|
return this.#orderedBy;
|
|
@@ -546,10 +542,13 @@
|
|
|
546
542
|
get surname() {
|
|
547
543
|
return this.#surname;
|
|
548
544
|
}
|
|
545
|
+
get mono() {
|
|
546
|
+
return this.#mono;
|
|
547
|
+
}
|
|
549
548
|
get name() {
|
|
550
549
|
return this.#name;
|
|
551
550
|
}
|
|
552
|
-
constructor(name, orderedBy = exports.NameOrder.FIRST_NAME, separator = Separator.SPACE, title = exports.Title.UK, ending = false, bypass = true, surname = exports.Surname.FATHER) {
|
|
551
|
+
constructor(name, orderedBy = exports.NameOrder.FIRST_NAME, separator = Separator.SPACE, title = exports.Title.UK, ending = false, bypass = true, surname = exports.Surname.FATHER, mono = false) {
|
|
553
552
|
this.#name = name;
|
|
554
553
|
this.#orderedBy = orderedBy;
|
|
555
554
|
this.#separator = separator;
|
|
@@ -557,6 +556,7 @@
|
|
|
557
556
|
this.#ending = ending;
|
|
558
557
|
this.#bypass = bypass;
|
|
559
558
|
this.#surname = surname;
|
|
559
|
+
this.#mono = mono;
|
|
560
560
|
}
|
|
561
561
|
static create(name = defaultName) {
|
|
562
562
|
if (!_a.cache.has(name))
|
|
@@ -575,11 +575,12 @@
|
|
|
575
575
|
config.#ending = other.ending ?? config.ending;
|
|
576
576
|
config.#bypass = other.bypass ?? config.bypass;
|
|
577
577
|
config.#surname = other.surname ?? config.surname;
|
|
578
|
+
config.#mono = other.mono ?? config.mono;
|
|
578
579
|
return config;
|
|
579
580
|
}
|
|
580
581
|
}
|
|
581
582
|
copyWith(options = {}) {
|
|
582
|
-
const { name, orderedBy, separator, title, ending, bypass, surname } = options;
|
|
583
|
+
const { name, orderedBy, separator, title, ending, bypass, surname, mono } = options;
|
|
583
584
|
const config = _a.create(this.#genNewName(name ?? this.name + copyAlias));
|
|
584
585
|
config.#orderedBy = orderedBy ?? this.orderedBy;
|
|
585
586
|
config.#separator = separator ?? this.separator;
|
|
@@ -587,6 +588,7 @@
|
|
|
587
588
|
config.#ending = ending ?? this.ending;
|
|
588
589
|
config.#bypass = bypass ?? this.bypass;
|
|
589
590
|
config.#surname = surname ?? this.surname;
|
|
591
|
+
config.#mono = mono ?? this.mono;
|
|
590
592
|
return config;
|
|
591
593
|
}
|
|
592
594
|
clone() {
|
|
@@ -599,11 +601,9 @@
|
|
|
599
601
|
this.#ending = false;
|
|
600
602
|
this.#bypass = true;
|
|
601
603
|
this.#surname = exports.Surname.FATHER;
|
|
604
|
+
this.#mono = false;
|
|
602
605
|
_a.cache.set(this.name, this);
|
|
603
606
|
}
|
|
604
|
-
updateOrder(orderedBy) {
|
|
605
|
-
this.update({ orderedBy });
|
|
606
|
-
}
|
|
607
607
|
update({ orderedBy, title, ending }) {
|
|
608
608
|
const config = _a.cache.get(this.name);
|
|
609
609
|
if (!config)
|
|
@@ -889,14 +889,18 @@
|
|
|
889
889
|
get suffix() {
|
|
890
890
|
return this.#suffix;
|
|
891
891
|
}
|
|
892
|
+
get isMono() {
|
|
893
|
+
return this instanceof Mononym;
|
|
894
|
+
}
|
|
892
895
|
static parse(json, config) {
|
|
893
896
|
try {
|
|
897
|
+
const { prefix, firstName: fn, middleName: mn, lastName: ln, suffix } = json;
|
|
894
898
|
return new FullName(config)
|
|
895
|
-
.setPrefix(
|
|
896
|
-
.setFirstName(
|
|
897
|
-
.setMiddleName(
|
|
898
|
-
.setLastName(
|
|
899
|
-
.setSuffix(
|
|
899
|
+
.setPrefix(prefix)
|
|
900
|
+
.setFirstName(typeof fn === 'string' ? fn : new FirstName(fn.value, ...(fn.more ?? [])))
|
|
901
|
+
.setMiddleName(typeof mn === 'string' ? [mn] : (mn ?? []))
|
|
902
|
+
.setLastName(typeof ln === 'string' ? ln : new LastName(ln.father, ln.mother))
|
|
903
|
+
.setSuffix(suffix);
|
|
900
904
|
}
|
|
901
905
|
catch (error) {
|
|
902
906
|
if (error instanceof NameError)
|
|
@@ -914,7 +918,7 @@
|
|
|
914
918
|
if (!this.#config.bypass)
|
|
915
919
|
Validators.prefix.validate(name);
|
|
916
920
|
const prefix = name instanceof Name ? name.value : name;
|
|
917
|
-
this.#prefix = Name.prefix(this.#config.title === exports.Title.US ? `${prefix}.` : prefix);
|
|
921
|
+
this.#prefix = Name.prefix(this.#config.title === exports.Title.US && !prefix.endsWith('.') ? `${prefix}.` : prefix);
|
|
918
922
|
return this;
|
|
919
923
|
}
|
|
920
924
|
setFirstName(name) {
|
|
@@ -945,13 +949,74 @@
|
|
|
945
949
|
this.#suffix = Name.suffix(name instanceof Name ? name.value : name);
|
|
946
950
|
return this;
|
|
947
951
|
}
|
|
948
|
-
has(
|
|
952
|
+
has(key) {
|
|
953
|
+
const namon = typeof key === 'string' ? Namon.cast(key) : key;
|
|
954
|
+
if (!namon)
|
|
955
|
+
return false;
|
|
949
956
|
if (namon.equal(Namon.PREFIX))
|
|
950
957
|
return !!this.#prefix;
|
|
951
958
|
if (namon.equal(Namon.SUFFIX))
|
|
952
959
|
return !!this.#suffix;
|
|
953
960
|
return namon.equal(Namon.MIDDLE_NAME) ? this.#middleName.length > 0 : true;
|
|
954
961
|
}
|
|
962
|
+
toString() {
|
|
963
|
+
if (this.isMono)
|
|
964
|
+
return this.value;
|
|
965
|
+
return Array.from(this.toIterable(true)).join(' ');
|
|
966
|
+
}
|
|
967
|
+
*toIterable(flat = false) {
|
|
968
|
+
if (this.#prefix)
|
|
969
|
+
yield this.#prefix;
|
|
970
|
+
if (flat) {
|
|
971
|
+
yield* this.#firstName.asNames;
|
|
972
|
+
yield* this.#middleName;
|
|
973
|
+
yield* this.#lastName.asNames;
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
yield this.#firstName;
|
|
977
|
+
yield* this.#middleName;
|
|
978
|
+
yield this.#lastName;
|
|
979
|
+
}
|
|
980
|
+
if (this.#suffix)
|
|
981
|
+
yield this.#suffix;
|
|
982
|
+
}
|
|
983
|
+
*[Symbol.iterator]() {
|
|
984
|
+
yield* this.toIterable(true);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
class Mononym extends FullName {
|
|
988
|
+
#namon;
|
|
989
|
+
#type;
|
|
990
|
+
constructor(name, options) {
|
|
991
|
+
super(options ?? { name: 'mononym', mono: true });
|
|
992
|
+
this.#namon = name.toString();
|
|
993
|
+
this.type = name instanceof Name ? name.type : Namon.FIRST_NAME;
|
|
994
|
+
}
|
|
995
|
+
set type(type) {
|
|
996
|
+
this.#type = typeof type === 'string' ? (Namon.cast(type) ?? Namon.FIRST_NAME) : type;
|
|
997
|
+
this.#build(this.#namon);
|
|
998
|
+
}
|
|
999
|
+
get type() {
|
|
1000
|
+
return this.#type;
|
|
1001
|
+
}
|
|
1002
|
+
get value() {
|
|
1003
|
+
return this.#namon;
|
|
1004
|
+
}
|
|
1005
|
+
#build(name) {
|
|
1006
|
+
this.setFirstName(ZERO_WIDTH_SPACE).setLastName(ZERO_WIDTH_SPACE).setMiddleName([]).setPrefix(null).setSuffix(null);
|
|
1007
|
+
if (this.#type.equal(Namon.FIRST_NAME))
|
|
1008
|
+
this.setFirstName(name);
|
|
1009
|
+
else if (this.#type.equal(Namon.LAST_NAME))
|
|
1010
|
+
this.setLastName(name);
|
|
1011
|
+
else if (this.#type.equal(Namon.MIDDLE_NAME))
|
|
1012
|
+
this.setMiddleName([name]);
|
|
1013
|
+
else if (this.#type.equal(Namon.PREFIX))
|
|
1014
|
+
this.setPrefix(name);
|
|
1015
|
+
else if (this.#type.equal(Namon.SUFFIX))
|
|
1016
|
+
this.setSuffix(name);
|
|
1017
|
+
else
|
|
1018
|
+
throw new NameError(name, 'invalid mononym type');
|
|
1019
|
+
}
|
|
955
1020
|
}
|
|
956
1021
|
|
|
957
1022
|
class Parser {
|
|
@@ -969,10 +1034,7 @@
|
|
|
969
1034
|
return new ArrayNameParser(names);
|
|
970
1035
|
}
|
|
971
1036
|
if (length < 2) {
|
|
972
|
-
throw new InputError({
|
|
973
|
-
source: text,
|
|
974
|
-
message: 'cannot build from invalid input',
|
|
975
|
-
});
|
|
1037
|
+
throw new InputError({ source: text, message: 'expecting at least 2 name parts' });
|
|
976
1038
|
}
|
|
977
1039
|
else if (length === 2 || length === 3) {
|
|
978
1040
|
return new StringParser(text);
|
|
@@ -996,13 +1058,15 @@
|
|
|
996
1058
|
parse(options) {
|
|
997
1059
|
const config = Config.merge(options);
|
|
998
1060
|
const names = this.raw.split(config.separator.token);
|
|
999
|
-
return new ArrayStringParser(names).parse(
|
|
1061
|
+
return new ArrayStringParser(names).parse(config);
|
|
1000
1062
|
}
|
|
1001
1063
|
}
|
|
1002
1064
|
class ArrayStringParser extends Parser {
|
|
1003
1065
|
parse(options) {
|
|
1004
1066
|
const config = Config.merge(options);
|
|
1005
|
-
|
|
1067
|
+
if (this.raw.length === 1 && config.mono) {
|
|
1068
|
+
return new MonoParser(this.raw[0]).parse(config);
|
|
1069
|
+
}
|
|
1006
1070
|
const raw = this.raw.map((n) => n.trim());
|
|
1007
1071
|
const index = NameIndex.when(config.orderedBy, raw.length);
|
|
1008
1072
|
const validator = new ArrayStringValidator(index);
|
|
@@ -1013,8 +1077,9 @@
|
|
|
1013
1077
|
validator.validate(raw);
|
|
1014
1078
|
}
|
|
1015
1079
|
const { firstName, lastName, middleName, prefix, suffix } = index;
|
|
1016
|
-
fullName
|
|
1017
|
-
|
|
1080
|
+
const fullName = new FullName(config)
|
|
1081
|
+
.setFirstName(new FirstName(raw[firstName]))
|
|
1082
|
+
.setLastName(new LastName(raw[lastName]));
|
|
1018
1083
|
if (raw.length >= 3)
|
|
1019
1084
|
fullName.setMiddleName(raw[middleName].split(config.separator.token));
|
|
1020
1085
|
if (raw.length >= 4)
|
|
@@ -1038,10 +1103,10 @@
|
|
|
1038
1103
|
return [namon, value];
|
|
1039
1104
|
}));
|
|
1040
1105
|
if (config.bypass) {
|
|
1041
|
-
|
|
1106
|
+
Validators.nama.validateKeys(names);
|
|
1042
1107
|
}
|
|
1043
1108
|
else {
|
|
1044
|
-
|
|
1109
|
+
Validators.nama.validate(names);
|
|
1045
1110
|
}
|
|
1046
1111
|
return FullName.parse(this.raw, config);
|
|
1047
1112
|
}
|
|
@@ -1049,8 +1114,13 @@
|
|
|
1049
1114
|
class ArrayNameParser extends Parser {
|
|
1050
1115
|
parse(options) {
|
|
1051
1116
|
const config = Config.merge(options);
|
|
1117
|
+
if (this.raw.length === 1 && config.mono) {
|
|
1118
|
+
return new MonoParser(this.raw[0]).parse(options);
|
|
1119
|
+
}
|
|
1120
|
+
else {
|
|
1121
|
+
ArrayNameValidator.create().validate(this.raw);
|
|
1122
|
+
}
|
|
1052
1123
|
const fullName = new FullName(config);
|
|
1053
|
-
ArrayNameValidator.create().validate(this.raw);
|
|
1054
1124
|
for (const name of this.raw) {
|
|
1055
1125
|
if (name.isPrefix) {
|
|
1056
1126
|
fullName.setPrefix(name);
|
|
@@ -1065,13 +1135,23 @@
|
|
|
1065
1135
|
fullName.middleName.push(name);
|
|
1066
1136
|
}
|
|
1067
1137
|
else if (name.isLastName) {
|
|
1068
|
-
const
|
|
1069
|
-
fullName.setLastName(
|
|
1138
|
+
const mother = name instanceof LastName ? name.mother : undefined;
|
|
1139
|
+
fullName.setLastName(new LastName(name.value, mother, config.surname));
|
|
1070
1140
|
}
|
|
1071
1141
|
}
|
|
1072
1142
|
return fullName;
|
|
1073
1143
|
}
|
|
1074
1144
|
}
|
|
1145
|
+
class MonoParser extends Parser {
|
|
1146
|
+
parse(options) {
|
|
1147
|
+
const config = Config.merge(options);
|
|
1148
|
+
if (config.bypass)
|
|
1149
|
+
Validators.namon.validate(this.raw);
|
|
1150
|
+
const type = config.mono instanceof Namon ? config.mono : Namon.FIRST_NAME;
|
|
1151
|
+
const name = this.raw instanceof Name ? this.raw : new Name(this.raw.trim(), type);
|
|
1152
|
+
return new Mononym(name, config);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1075
1155
|
|
|
1076
1156
|
class Namefully {
|
|
1077
1157
|
#fullName;
|
|
@@ -1092,7 +1172,12 @@
|
|
|
1092
1172
|
get config() {
|
|
1093
1173
|
return this.#fullName.config;
|
|
1094
1174
|
}
|
|
1175
|
+
get isMono() {
|
|
1176
|
+
return this.#fullName.isMono;
|
|
1177
|
+
}
|
|
1095
1178
|
get length() {
|
|
1179
|
+
if (this.isMono)
|
|
1180
|
+
return this.#fullName.toString().length;
|
|
1096
1181
|
return this.birth.length;
|
|
1097
1182
|
}
|
|
1098
1183
|
get prefix() {
|
|
@@ -1131,25 +1216,43 @@
|
|
|
1131
1216
|
get salutation() {
|
|
1132
1217
|
return this.format('p l');
|
|
1133
1218
|
}
|
|
1219
|
+
get parts() {
|
|
1220
|
+
return this.#fullName.toIterable();
|
|
1221
|
+
}
|
|
1222
|
+
get size() {
|
|
1223
|
+
return Array.from(this.parts).length;
|
|
1224
|
+
}
|
|
1225
|
+
*[Symbol.iterator]() {
|
|
1226
|
+
yield* this.#fullName.toIterable(true);
|
|
1227
|
+
}
|
|
1134
1228
|
toString() {
|
|
1135
1229
|
return this.full;
|
|
1136
1230
|
}
|
|
1137
|
-
get(
|
|
1138
|
-
|
|
1231
|
+
get(key) {
|
|
1232
|
+
const namon = typeof key === 'string' ? Namon.cast(key) : key;
|
|
1233
|
+
if (namon?.equal(Namon.PREFIX))
|
|
1139
1234
|
return this.#fullName.prefix;
|
|
1140
|
-
if (namon
|
|
1235
|
+
if (namon?.equal(Namon.FIRST_NAME))
|
|
1141
1236
|
return this.#fullName.firstName;
|
|
1142
|
-
if (namon
|
|
1237
|
+
if (namon?.equal(Namon.MIDDLE_NAME))
|
|
1143
1238
|
return this.#fullName.middleName;
|
|
1144
|
-
if (namon
|
|
1239
|
+
if (namon?.equal(Namon.LAST_NAME))
|
|
1145
1240
|
return this.#fullName.lastName;
|
|
1146
|
-
if (namon
|
|
1241
|
+
if (namon?.equal(Namon.SUFFIX))
|
|
1147
1242
|
return this.#fullName.suffix;
|
|
1148
1243
|
return undefined;
|
|
1149
1244
|
}
|
|
1150
1245
|
equal(other) {
|
|
1151
1246
|
return this.toString() === other.toString();
|
|
1152
1247
|
}
|
|
1248
|
+
deepEqual(other) {
|
|
1249
|
+
const others = Array.from(other.parts);
|
|
1250
|
+
for (const part of this.parts) {
|
|
1251
|
+
if (!others.some((name) => name.equal(part)))
|
|
1252
|
+
return false;
|
|
1253
|
+
}
|
|
1254
|
+
return true;
|
|
1255
|
+
}
|
|
1153
1256
|
toJson() {
|
|
1154
1257
|
return {
|
|
1155
1258
|
prefix: this.prefix,
|
|
@@ -1164,6 +1267,8 @@
|
|
|
1164
1267
|
return this.#fullName.has(namon);
|
|
1165
1268
|
}
|
|
1166
1269
|
fullName(orderedBy) {
|
|
1270
|
+
if (this.isMono)
|
|
1271
|
+
return this.#fullName.toString();
|
|
1167
1272
|
const sep = this.config.ending ? ',' : '';
|
|
1168
1273
|
const names = [];
|
|
1169
1274
|
if (this.prefix)
|
|
@@ -1172,13 +1277,21 @@
|
|
|
1172
1277
|
names.push(this.first, ...this.middleName(), this.last + sep);
|
|
1173
1278
|
}
|
|
1174
1279
|
else {
|
|
1175
|
-
names.push(this.last
|
|
1280
|
+
names.push(this.last);
|
|
1281
|
+
if (this.hasMiddle) {
|
|
1282
|
+
names.push(this.first, this.middleName().join(' ') + sep);
|
|
1283
|
+
}
|
|
1284
|
+
else {
|
|
1285
|
+
names.push(this.first + sep);
|
|
1286
|
+
}
|
|
1176
1287
|
}
|
|
1177
1288
|
if (this.suffix)
|
|
1178
1289
|
names.push(this.suffix);
|
|
1179
1290
|
return names.join(' ').trim();
|
|
1180
1291
|
}
|
|
1181
1292
|
birthName(orderedBy) {
|
|
1293
|
+
if (this.isMono)
|
|
1294
|
+
return this.#fullName.toString();
|
|
1182
1295
|
orderedBy ??= this.config.orderedBy;
|
|
1183
1296
|
return orderedBy === exports.NameOrder.FIRST_NAME
|
|
1184
1297
|
? [this.first, ...this.middleName(), this.last].join(' ')
|
|
@@ -1194,6 +1307,8 @@
|
|
|
1194
1307
|
return this.#fullName.lastName.toString(format);
|
|
1195
1308
|
}
|
|
1196
1309
|
initials(options) {
|
|
1310
|
+
if (this.isMono)
|
|
1311
|
+
return [this.#fullName.toString()[0]];
|
|
1197
1312
|
const { orderedBy = this.config.orderedBy, only = exports.NameType.BIRTH_NAME, asJson } = options ?? {};
|
|
1198
1313
|
const firstInits = this.#fullName.firstName.initials();
|
|
1199
1314
|
const midInits = this.#fullName.middleName.map((n) => n.value[0]);
|
|
@@ -1211,6 +1326,8 @@
|
|
|
1211
1326
|
}
|
|
1212
1327
|
}
|
|
1213
1328
|
shorten(orderedBy) {
|
|
1329
|
+
if (this.isMono)
|
|
1330
|
+
return this.#fullName.toString();
|
|
1214
1331
|
orderedBy ??= this.config.orderedBy;
|
|
1215
1332
|
const { firstName, lastName } = this.#fullName;
|
|
1216
1333
|
return orderedBy === exports.NameOrder.FIRST_NAME
|
|
@@ -1221,6 +1338,8 @@
|
|
|
1221
1338
|
const { by = exports.Flat.MIDDLE_NAME, limit = 20, recursive = false, withMore = false, withPeriod = true, surname, } = options;
|
|
1222
1339
|
if (this.length <= limit)
|
|
1223
1340
|
return this.full;
|
|
1341
|
+
if (this.isMono)
|
|
1342
|
+
return `${this.initials()}${withPeriod ? '.' : ''}`;
|
|
1224
1343
|
const { firstName, lastName, middleName } = this.#fullName;
|
|
1225
1344
|
const sep = withPeriod ? '.' : '';
|
|
1226
1345
|
const hasMid = this.hasMiddle;
|
|
@@ -1248,7 +1367,7 @@
|
|
|
1248
1367
|
case exports.Flat.MID_LAST:
|
|
1249
1368
|
name = hasMid ? [fn, m, l] : [fn, l];
|
|
1250
1369
|
break;
|
|
1251
|
-
|
|
1370
|
+
default:
|
|
1252
1371
|
name = hasMid ? [f, m, l] : [f, l];
|
|
1253
1372
|
break;
|
|
1254
1373
|
}
|
|
@@ -1270,7 +1389,7 @@
|
|
|
1270
1389
|
case exports.Flat.MID_LAST:
|
|
1271
1390
|
name = hasMid ? [l, fn, m] : [l, fn];
|
|
1272
1391
|
break;
|
|
1273
|
-
|
|
1392
|
+
default:
|
|
1274
1393
|
name = hasMid ? [l, f, m] : [l, f];
|
|
1275
1394
|
break;
|
|
1276
1395
|
}
|
|
@@ -1311,7 +1430,7 @@
|
|
|
1311
1430
|
let group = '';
|
|
1312
1431
|
const formatted = [];
|
|
1313
1432
|
for (const char of pattern) {
|
|
1314
|
-
if (ALLOWED_FORMAT_TOKENS.
|
|
1433
|
+
if (!ALLOWED_FORMAT_TOKENS.includes(char)) {
|
|
1315
1434
|
throw new NotAllowedError({
|
|
1316
1435
|
source: this.full,
|
|
1317
1436
|
operation: 'format',
|
|
@@ -1368,6 +1487,28 @@
|
|
|
1368
1487
|
toToggleCase() {
|
|
1369
1488
|
return toggleCase(this.birth);
|
|
1370
1489
|
}
|
|
1490
|
+
serialize() {
|
|
1491
|
+
const { config, firstName: fn, lastName: ln } = this.#fullName;
|
|
1492
|
+
return {
|
|
1493
|
+
names: {
|
|
1494
|
+
prefix: this.prefix,
|
|
1495
|
+
firstName: fn.hasMore ? { value: fn.value, more: fn.more } : fn.value,
|
|
1496
|
+
middleName: this.hasMiddle ? this.middleName() : undefined,
|
|
1497
|
+
lastName: ln.hasMother ? { father: ln.father, mother: ln.mother } : ln.value,
|
|
1498
|
+
suffix: this.suffix,
|
|
1499
|
+
},
|
|
1500
|
+
config: {
|
|
1501
|
+
name: config.name,
|
|
1502
|
+
orderedBy: config.orderedBy,
|
|
1503
|
+
separator: config.separator.token,
|
|
1504
|
+
title: config.title,
|
|
1505
|
+
ending: config.ending,
|
|
1506
|
+
bypass: config.bypass,
|
|
1507
|
+
surname: config.surname,
|
|
1508
|
+
mono: config.mono instanceof Namon ? config.mono.key : config.mono,
|
|
1509
|
+
},
|
|
1510
|
+
};
|
|
1511
|
+
}
|
|
1371
1512
|
#toParser(raw) {
|
|
1372
1513
|
if (raw instanceof Parser)
|
|
1373
1514
|
return raw;
|
|
@@ -1383,12 +1524,6 @@
|
|
|
1383
1524
|
}
|
|
1384
1525
|
#map(char) {
|
|
1385
1526
|
switch (char) {
|
|
1386
|
-
case '.':
|
|
1387
|
-
case ',':
|
|
1388
|
-
case ' ':
|
|
1389
|
-
case '-':
|
|
1390
|
-
case '_':
|
|
1391
|
-
return char;
|
|
1392
1527
|
case 'b':
|
|
1393
1528
|
return this.birth;
|
|
1394
1529
|
case 'B':
|
|
@@ -1430,16 +1565,19 @@
|
|
|
1430
1565
|
case 'S':
|
|
1431
1566
|
return this.suffix?.toUpperCase();
|
|
1432
1567
|
case '$f':
|
|
1433
|
-
case '$F':
|
|
1434
1568
|
return this.#fullName.firstName.value[0];
|
|
1569
|
+
case '$F':
|
|
1570
|
+
return this.#fullName.firstName.initials(true).join('');
|
|
1435
1571
|
case '$l':
|
|
1436
|
-
case '$L':
|
|
1437
1572
|
return this.#fullName.lastName.value[0];
|
|
1573
|
+
case '$L':
|
|
1574
|
+
return this.#fullName.lastName.initials().join('');
|
|
1438
1575
|
case '$m':
|
|
1439
|
-
case '$M':
|
|
1440
1576
|
return this.hasMiddle ? this.middle[0] : undefined;
|
|
1577
|
+
case '$M':
|
|
1578
|
+
return this.hasMiddle ? this.#fullName.middleName.map((n) => n.value[0]).join('') : undefined;
|
|
1441
1579
|
default:
|
|
1442
|
-
return undefined;
|
|
1580
|
+
return ALLOWED_FORMAT_TOKENS.includes(char) ? char : undefined;
|
|
1443
1581
|
}
|
|
1444
1582
|
}
|
|
1445
1583
|
}
|
|
@@ -1514,21 +1652,59 @@
|
|
|
1514
1652
|
static use({ names, prebuild, postbuild, preclear, postclear, }) {
|
|
1515
1653
|
return new NameBuilder(names ?? [], prebuild, postbuild, preclear, postclear);
|
|
1516
1654
|
}
|
|
1517
|
-
build(
|
|
1655
|
+
build(options) {
|
|
1518
1656
|
this.prebuild?.();
|
|
1519
1657
|
const names = [...this.queue];
|
|
1520
|
-
|
|
1658
|
+
const config = Config.merge(options);
|
|
1659
|
+
if (!config.mono)
|
|
1660
|
+
ArrayNameValidator.create().validate(names);
|
|
1521
1661
|
this.instance = new Namefully(names, config);
|
|
1522
1662
|
this.postbuild?.(this.instance);
|
|
1523
1663
|
return this.instance;
|
|
1524
1664
|
}
|
|
1525
1665
|
}
|
|
1526
1666
|
|
|
1667
|
+
function deserialize(data) {
|
|
1668
|
+
try {
|
|
1669
|
+
const parsed = typeof data === 'string' ? JSON.parse(data) : data;
|
|
1670
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
1671
|
+
throw new InputError({
|
|
1672
|
+
source: String(data),
|
|
1673
|
+
message: 'invalid serialized data; must be an object or a string',
|
|
1674
|
+
});
|
|
1675
|
+
}
|
|
1676
|
+
const { names, config } = parsed;
|
|
1677
|
+
const { firstName: fn, lastName: ln, middleName: mn, prefix: px, suffix: sx } = names;
|
|
1678
|
+
const builder = NameBuilder.of();
|
|
1679
|
+
if (px)
|
|
1680
|
+
builder.add(Name.prefix(px));
|
|
1681
|
+
if (sx)
|
|
1682
|
+
builder.add(Name.suffix(sx));
|
|
1683
|
+
if (mn)
|
|
1684
|
+
builder.add(...(typeof mn === 'string' ? [Name.middle(mn)] : mn.map((n) => Name.middle(n))));
|
|
1685
|
+
builder.add(typeof fn === 'string' ? Name.first(fn) : new FirstName(fn.value, ...(fn.more ?? [])));
|
|
1686
|
+
builder.add(typeof ln === 'string' ? Name.last(ln) : new LastName(ln.father, ln.mother));
|
|
1687
|
+
const separator = Separator.cast(config.separator);
|
|
1688
|
+
const mono = typeof config.mono === 'string' ? (Namon.cast(config.mono) ?? false) : config.mono;
|
|
1689
|
+
return builder.build({ ...config, separator, mono });
|
|
1690
|
+
}
|
|
1691
|
+
catch (error) {
|
|
1692
|
+
if (error instanceof NameError)
|
|
1693
|
+
throw error;
|
|
1694
|
+
throw new UnknownError({
|
|
1695
|
+
source: String(data),
|
|
1696
|
+
message: 'could not deserialize data',
|
|
1697
|
+
origin: error instanceof Error ? error : new Error(String(error)),
|
|
1698
|
+
});
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1527
1702
|
exports.Config = Config;
|
|
1528
1703
|
exports.FirstName = FirstName;
|
|
1529
1704
|
exports.FullName = FullName;
|
|
1530
1705
|
exports.InputError = InputError;
|
|
1531
1706
|
exports.LastName = LastName;
|
|
1707
|
+
exports.Mononym = Mononym;
|
|
1532
1708
|
exports.Name = Name;
|
|
1533
1709
|
exports.NameBuilder = NameBuilder;
|
|
1534
1710
|
exports.NameError = NameError;
|
|
@@ -1541,6 +1717,7 @@
|
|
|
1541
1717
|
exports.UnknownError = UnknownError;
|
|
1542
1718
|
exports.ValidationError = ValidationError;
|
|
1543
1719
|
exports.default = namefully;
|
|
1720
|
+
exports.deserialize = deserialize;
|
|
1544
1721
|
exports.isNameArray = isNameArray;
|
|
1545
1722
|
exports.version = VERSION;
|
|
1546
1723
|
|