namefully 1.3.0 → 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.
- package/dist/{lib → cjs}/builder.js +15 -13
- package/dist/cjs/config.js +100 -0
- package/dist/{lib → cjs}/constants.js +1 -1
- package/dist/{lib → cjs}/error.js +8 -5
- package/dist/cjs/fullname.js +102 -0
- package/dist/{lib → cjs}/index.js +18 -15
- package/dist/cjs/name.js +218 -0
- package/dist/cjs/namefully.js +391 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/parser.js +135 -0
- package/dist/{lib → cjs}/types.js +40 -36
- package/dist/{lib → cjs}/utils.js +17 -17
- package/dist/cjs/validator.js +266 -0
- package/dist/{types → esm}/builder.d.ts +8 -8
- package/dist/esm/builder.js +78 -0
- package/dist/{types → esm}/config.d.ts +1 -1
- package/dist/esm/config.js +96 -0
- package/dist/{types → esm}/constants.d.ts +1 -1
- package/dist/esm/constants.js +27 -0
- package/dist/{types → esm}/error.d.ts +2 -3
- package/dist/esm/error.js +87 -0
- package/dist/{types/full-name.d.ts → esm/fullname.d.ts} +3 -3
- package/dist/esm/fullname.js +98 -0
- package/dist/esm/index.d.ts +25 -0
- package/dist/esm/index.js +12 -0
- package/dist/{types → esm}/name.d.ts +2 -1
- package/dist/esm/name.js +211 -0
- package/dist/{types → esm}/namefully.d.ts +8 -8
- package/dist/esm/namefully.js +387 -0
- package/dist/esm/package.json +1 -0
- package/dist/{types → esm}/parser.d.ts +4 -4
- package/dist/esm/parser.js +127 -0
- package/dist/esm/types.js +106 -0
- package/dist/{types → esm}/utils.d.ts +1 -2
- package/dist/esm/utils.js +96 -0
- package/dist/{types → esm}/validator.d.ts +3 -3
- package/dist/esm/validator.js +259 -0
- package/dist/namefully.js +1580 -0
- package/dist/namefully.min.js +1 -0
- package/package.json +44 -27
- package/readme.md +1 -1
- package/dist/lib/config.js +0 -112
- package/dist/lib/full-name.js +0 -115
- package/dist/lib/name.js +0 -230
- package/dist/lib/namefully.js +0 -417
- package/dist/lib/parser.js +0 -144
- package/dist/lib/validator.js +0 -285
- package/dist/types/index.d.ts +0 -25
- package/dist/umd/namefully.js +0 -1931
- package/dist/umd/namefully.min.js +0 -1
- /package/dist/{types → esm}/types.d.ts +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Config } from './config.js';
|
|
2
|
+
import { NameError, UnknownError } from './error.js';
|
|
3
|
+
import { FirstName, LastName, Name } from './name.js';
|
|
4
|
+
import { Namon, Title } from './types.js';
|
|
5
|
+
import { Validators } from './validator.js';
|
|
6
|
+
export class FullName {
|
|
7
|
+
#prefix;
|
|
8
|
+
#firstName;
|
|
9
|
+
#middleName = [];
|
|
10
|
+
#lastName;
|
|
11
|
+
#suffix;
|
|
12
|
+
#config;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.#config = Config.merge(options);
|
|
15
|
+
}
|
|
16
|
+
get config() {
|
|
17
|
+
return this.#config;
|
|
18
|
+
}
|
|
19
|
+
get prefix() {
|
|
20
|
+
return this.#prefix;
|
|
21
|
+
}
|
|
22
|
+
get firstName() {
|
|
23
|
+
return this.#firstName;
|
|
24
|
+
}
|
|
25
|
+
get lastName() {
|
|
26
|
+
return this.#lastName;
|
|
27
|
+
}
|
|
28
|
+
get middleName() {
|
|
29
|
+
return this.#middleName;
|
|
30
|
+
}
|
|
31
|
+
get suffix() {
|
|
32
|
+
return this.#suffix;
|
|
33
|
+
}
|
|
34
|
+
static parse(json, config) {
|
|
35
|
+
try {
|
|
36
|
+
const fullName = new FullName(config);
|
|
37
|
+
fullName.setPrefix(json.prefix);
|
|
38
|
+
fullName.setFirstName(json.firstName);
|
|
39
|
+
fullName.setMiddleName(json.middleName ?? []);
|
|
40
|
+
fullName.setLastName(json.lastName);
|
|
41
|
+
fullName.setSuffix(json.suffix);
|
|
42
|
+
return fullName;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error instanceof NameError)
|
|
46
|
+
throw error;
|
|
47
|
+
throw new UnknownError({
|
|
48
|
+
source: Object.values(json).join(' '),
|
|
49
|
+
message: 'could not parse JSON content',
|
|
50
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
setPrefix(name) {
|
|
55
|
+
if (!name)
|
|
56
|
+
return this;
|
|
57
|
+
if (!this.#config.bypass)
|
|
58
|
+
Validators.prefix.validate(name);
|
|
59
|
+
const prefix = name instanceof Name ? name.value : name;
|
|
60
|
+
this.#prefix = Name.prefix(this.#config.title === Title.US ? `${prefix}.` : prefix);
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
setFirstName(name) {
|
|
64
|
+
if (!this.#config.bypass)
|
|
65
|
+
Validators.firstName.validate(name);
|
|
66
|
+
this.#firstName = name instanceof FirstName ? name : new FirstName(name);
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
setLastName(name) {
|
|
70
|
+
if (!this.#config.bypass)
|
|
71
|
+
Validators.lastName.validate(name);
|
|
72
|
+
this.#lastName = name instanceof LastName ? name : new LastName(name);
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
setMiddleName(names) {
|
|
76
|
+
if (!Array.isArray(names))
|
|
77
|
+
return this;
|
|
78
|
+
if (!this.#config.bypass)
|
|
79
|
+
Validators.middleName.validate(names);
|
|
80
|
+
this.#middleName = names.map((name) => (name instanceof Name ? name : Name.middle(name)));
|
|
81
|
+
return this;
|
|
82
|
+
}
|
|
83
|
+
setSuffix(name) {
|
|
84
|
+
if (!name)
|
|
85
|
+
return this;
|
|
86
|
+
if (!this.#config.bypass)
|
|
87
|
+
Validators.suffix.validate(name);
|
|
88
|
+
this.#suffix = Name.suffix(name instanceof Name ? name.value : name);
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
has(namon) {
|
|
92
|
+
if (namon.equal(Namon.PREFIX))
|
|
93
|
+
return !!this.#prefix;
|
|
94
|
+
if (namon.equal(Namon.SUFFIX))
|
|
95
|
+
return !!this.#suffix;
|
|
96
|
+
return namon.equal(Namon.MIDDLE_NAME) ? this.#middleName.length > 0 : true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Welcome to namefully!
|
|
3
|
+
*
|
|
4
|
+
* `namefully` is a JavaScript utility for handling personal names.
|
|
5
|
+
*
|
|
6
|
+
* Sources
|
|
7
|
+
* - repo: https://github.com/ralflorent/namefully
|
|
8
|
+
* - docs: https://namefully.netlify.app
|
|
9
|
+
* - npm: https://npmjs.com/package/namefully
|
|
10
|
+
* - jsr: https://jsr.io/@ralflorent/namefully
|
|
11
|
+
*
|
|
12
|
+
* @license MIT
|
|
13
|
+
*/
|
|
14
|
+
import namefully from './namefully.js';
|
|
15
|
+
export * from './builder.js';
|
|
16
|
+
export * from './config.js';
|
|
17
|
+
export { VERSION as version } from './constants.js';
|
|
18
|
+
export * from './error.js';
|
|
19
|
+
export * from './fullname.js';
|
|
20
|
+
export * from './name.js';
|
|
21
|
+
export * from './namefully.js';
|
|
22
|
+
export { Parser } from './parser.js';
|
|
23
|
+
export * from './types.js';
|
|
24
|
+
export { NameIndex } from './utils.js';
|
|
25
|
+
export default namefully;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import namefully from './namefully.js';
|
|
2
|
+
export * from './builder.js';
|
|
3
|
+
export * from './config.js';
|
|
4
|
+
export { VERSION as version } from './constants.js';
|
|
5
|
+
export * from './error.js';
|
|
6
|
+
export * from './fullname.js';
|
|
7
|
+
export * from './name.js';
|
|
8
|
+
export * from './namefully.js';
|
|
9
|
+
export { Parser } from './parser.js';
|
|
10
|
+
export * from './types.js';
|
|
11
|
+
export { NameIndex } from './utils.js';
|
|
12
|
+
export default namefully;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CapsRange, Namon, Surname } from './types';
|
|
1
|
+
import { CapsRange, Namon, Surname } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Representation of a string type name with some extra capabilities.
|
|
4
4
|
*/
|
|
@@ -114,6 +114,7 @@ export declare class LastName extends Name {
|
|
|
114
114
|
format?: Surname;
|
|
115
115
|
}): LastName;
|
|
116
116
|
}
|
|
117
|
+
export declare function isNameArray(value?: unknown): boolean;
|
|
117
118
|
/**
|
|
118
119
|
* JSON signature for `FullName` data.
|
|
119
120
|
*/
|
package/dist/esm/name.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { InputError } from './error.js';
|
|
2
|
+
import { CapsRange, Namon, Surname } from './types.js';
|
|
3
|
+
import { capitalize, decapitalize } from './utils.js';
|
|
4
|
+
export class Name {
|
|
5
|
+
type;
|
|
6
|
+
#namon;
|
|
7
|
+
initial;
|
|
8
|
+
capsRange;
|
|
9
|
+
constructor(value, type, capsRange) {
|
|
10
|
+
this.type = type;
|
|
11
|
+
this.capsRange = capsRange ?? CapsRange.INITIAL;
|
|
12
|
+
this.value = value;
|
|
13
|
+
if (capsRange)
|
|
14
|
+
this.caps(capsRange);
|
|
15
|
+
}
|
|
16
|
+
set value(newValue) {
|
|
17
|
+
this.validate(newValue);
|
|
18
|
+
this.#namon = newValue;
|
|
19
|
+
this.initial = newValue[0];
|
|
20
|
+
}
|
|
21
|
+
get value() {
|
|
22
|
+
return this.#namon;
|
|
23
|
+
}
|
|
24
|
+
get length() {
|
|
25
|
+
return this.#namon.length;
|
|
26
|
+
}
|
|
27
|
+
get isPrefix() {
|
|
28
|
+
return this.type === Namon.PREFIX;
|
|
29
|
+
}
|
|
30
|
+
get isFirstName() {
|
|
31
|
+
return this.type === Namon.FIRST_NAME;
|
|
32
|
+
}
|
|
33
|
+
get isMiddleName() {
|
|
34
|
+
return this.type === Namon.MIDDLE_NAME;
|
|
35
|
+
}
|
|
36
|
+
get isLastName() {
|
|
37
|
+
return this.type === Namon.LAST_NAME;
|
|
38
|
+
}
|
|
39
|
+
get isSuffix() {
|
|
40
|
+
return this.type === Namon.SUFFIX;
|
|
41
|
+
}
|
|
42
|
+
static prefix(value) {
|
|
43
|
+
return new this(value, Namon.PREFIX);
|
|
44
|
+
}
|
|
45
|
+
static first(value) {
|
|
46
|
+
return new this(value, Namon.FIRST_NAME);
|
|
47
|
+
}
|
|
48
|
+
static middle(value) {
|
|
49
|
+
return new this(value, Namon.MIDDLE_NAME);
|
|
50
|
+
}
|
|
51
|
+
static last(value) {
|
|
52
|
+
return new this(value, Namon.LAST_NAME);
|
|
53
|
+
}
|
|
54
|
+
static suffix(value) {
|
|
55
|
+
return new this(value, Namon.SUFFIX);
|
|
56
|
+
}
|
|
57
|
+
initials() {
|
|
58
|
+
return [this.initial];
|
|
59
|
+
}
|
|
60
|
+
toString() {
|
|
61
|
+
return this.#namon;
|
|
62
|
+
}
|
|
63
|
+
equal(other) {
|
|
64
|
+
return other instanceof Name && other.value === this.value && other.type === this.type;
|
|
65
|
+
}
|
|
66
|
+
caps(range) {
|
|
67
|
+
this.value = capitalize(this.#namon, range ?? this.capsRange);
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
decaps(range) {
|
|
71
|
+
this.value = decapitalize(this.#namon, range ?? this.capsRange);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
validate(name) {
|
|
75
|
+
if (name && name?.trim()?.length < 2) {
|
|
76
|
+
throw new InputError({ source: name, message: 'must be 2+ characters' });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export class FirstName extends Name {
|
|
81
|
+
#more;
|
|
82
|
+
constructor(value, ...more) {
|
|
83
|
+
super(value, Namon.FIRST_NAME);
|
|
84
|
+
more.forEach((n) => this.validate(n));
|
|
85
|
+
this.#more = more;
|
|
86
|
+
}
|
|
87
|
+
get hasMore() {
|
|
88
|
+
return this.#more.length > 0;
|
|
89
|
+
}
|
|
90
|
+
get length() {
|
|
91
|
+
return super.length + (this.hasMore ? this.#more.reduce((acc, n) => acc + n).length : 0);
|
|
92
|
+
}
|
|
93
|
+
get asNames() {
|
|
94
|
+
const names = [Name.first(this.value)];
|
|
95
|
+
if (this.hasMore) {
|
|
96
|
+
names.push(...this.#more.map((n) => Name.first(n)));
|
|
97
|
+
}
|
|
98
|
+
return names;
|
|
99
|
+
}
|
|
100
|
+
get more() {
|
|
101
|
+
return this.#more;
|
|
102
|
+
}
|
|
103
|
+
toString(withMore = false) {
|
|
104
|
+
return withMore && this.hasMore ? `${this.value} ${this.#more.join(' ')}`.trim() : this.value;
|
|
105
|
+
}
|
|
106
|
+
initials(withMore = false) {
|
|
107
|
+
const inits = [this.initial];
|
|
108
|
+
if (withMore && this.hasMore) {
|
|
109
|
+
inits.push(...this.#more.map((n) => n[0]));
|
|
110
|
+
}
|
|
111
|
+
return inits;
|
|
112
|
+
}
|
|
113
|
+
caps(range) {
|
|
114
|
+
range = range || this.capsRange;
|
|
115
|
+
this.value = capitalize(this.value, range);
|
|
116
|
+
if (this.hasMore)
|
|
117
|
+
this.#more = this.#more.map((n) => capitalize(n, range));
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
decaps(range) {
|
|
121
|
+
range = range || this.capsRange;
|
|
122
|
+
this.value = decapitalize(this.value, range);
|
|
123
|
+
if (this.hasMore)
|
|
124
|
+
this.#more = this.#more.map((n) => decapitalize(n, range));
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
copyWith(values) {
|
|
128
|
+
return new FirstName(values?.first ?? this.value, ...(values?.more ?? this.#more));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export class LastName extends Name {
|
|
132
|
+
format;
|
|
133
|
+
#mother;
|
|
134
|
+
constructor(father, mother, format = Surname.FATHER) {
|
|
135
|
+
super(father, Namon.LAST_NAME);
|
|
136
|
+
this.format = format;
|
|
137
|
+
this.validate(mother);
|
|
138
|
+
this.#mother = mother;
|
|
139
|
+
}
|
|
140
|
+
get father() {
|
|
141
|
+
return this.value;
|
|
142
|
+
}
|
|
143
|
+
get mother() {
|
|
144
|
+
return this.#mother;
|
|
145
|
+
}
|
|
146
|
+
get hasMother() {
|
|
147
|
+
return !!this.#mother;
|
|
148
|
+
}
|
|
149
|
+
get length() {
|
|
150
|
+
return super.length + (this.#mother?.length ?? 0);
|
|
151
|
+
}
|
|
152
|
+
get asNames() {
|
|
153
|
+
const names = [Name.last(this.value)];
|
|
154
|
+
if (this.#mother)
|
|
155
|
+
names.push(Name.last(this.#mother));
|
|
156
|
+
return names;
|
|
157
|
+
}
|
|
158
|
+
toString(format) {
|
|
159
|
+
format = format ?? this.format;
|
|
160
|
+
switch (format) {
|
|
161
|
+
case Surname.FATHER:
|
|
162
|
+
return this.value;
|
|
163
|
+
case Surname.MOTHER:
|
|
164
|
+
return this.mother ?? '';
|
|
165
|
+
case Surname.HYPHENATED:
|
|
166
|
+
return this.hasMother ? `${this.value}-${this.#mother}` : this.value;
|
|
167
|
+
case Surname.ALL:
|
|
168
|
+
return this.hasMother ? `${this.value} ${this.#mother}` : this.value;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
initials(format) {
|
|
172
|
+
format = format || this.format;
|
|
173
|
+
const inits = [];
|
|
174
|
+
switch (format) {
|
|
175
|
+
case Surname.MOTHER:
|
|
176
|
+
if (this.#mother)
|
|
177
|
+
inits.push(this.#mother[0]);
|
|
178
|
+
break;
|
|
179
|
+
case Surname.HYPHENATED:
|
|
180
|
+
case Surname.ALL:
|
|
181
|
+
inits.push(this.initial);
|
|
182
|
+
if (this.#mother)
|
|
183
|
+
inits.push(this.#mother[0]);
|
|
184
|
+
break;
|
|
185
|
+
case Surname.FATHER:
|
|
186
|
+
default:
|
|
187
|
+
inits.push(this.initial);
|
|
188
|
+
}
|
|
189
|
+
return inits;
|
|
190
|
+
}
|
|
191
|
+
caps(range) {
|
|
192
|
+
range = range || this.capsRange;
|
|
193
|
+
this.value = capitalize(this.value, range);
|
|
194
|
+
if (this.hasMother)
|
|
195
|
+
this.#mother = capitalize(this.#mother, range);
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
decaps(range) {
|
|
199
|
+
range = range || this.capsRange;
|
|
200
|
+
this.value = decapitalize(this.value, range);
|
|
201
|
+
if (this.hasMother)
|
|
202
|
+
this.#mother = decapitalize(this.#mother, range);
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
copyWith(values) {
|
|
206
|
+
return new LastName(values?.father ?? this.value, values?.mother ?? this.mother, values?.format ?? this.format);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
export function isNameArray(value) {
|
|
210
|
+
return Array.isArray(value) && value.length > 0 && value.every((e) => e instanceof Name);
|
|
211
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Config } from './config';
|
|
2
|
-
import { Name, JsonName } from './name';
|
|
3
|
-
import { Parser } from './parser';
|
|
4
|
-
import { Flat, NameOrder, NameType, Namon, Nullable, Surname } from './types';
|
|
5
|
-
import { NameIndex } from './utils';
|
|
1
|
+
import { Config } from './config.js';
|
|
2
|
+
import { Name, JsonName } from './name.js';
|
|
3
|
+
import { Parser } from './parser.js';
|
|
4
|
+
import { Flat, NameOrder, NameType, Namon, Nullable, Surname } from './types.js';
|
|
5
|
+
import { NameIndex } from './utils.js';
|
|
6
6
|
/**
|
|
7
7
|
* A helper for organizing person names in a particular order, way, or shape.
|
|
8
8
|
*
|
|
@@ -86,17 +86,17 @@ export declare class Namefully {
|
|
|
86
86
|
/** The number of characters of the `birthName`, including spaces. */
|
|
87
87
|
get length(): number;
|
|
88
88
|
/** The prefix part. */
|
|
89
|
-
get prefix():
|
|
89
|
+
get prefix(): string | undefined;
|
|
90
90
|
/** The firt name part. */
|
|
91
91
|
get first(): string;
|
|
92
92
|
/** The first middle name part if any. */
|
|
93
|
-
get middle():
|
|
93
|
+
get middle(): string | undefined;
|
|
94
94
|
/** Returns true if any middle name has been set. */
|
|
95
95
|
get hasMiddle(): boolean;
|
|
96
96
|
/** The last name part. */
|
|
97
97
|
get last(): string;
|
|
98
98
|
/** The suffix part. */
|
|
99
|
-
get suffix():
|
|
99
|
+
get suffix(): string | undefined;
|
|
100
100
|
/** The birth name part. */
|
|
101
101
|
get birth(): string;
|
|
102
102
|
/** The shortest version of a person name. */
|