namefully 2.0.1 → 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/constants.js +3 -3
- package/dist/cjs/error.js +3 -6
- package/dist/cjs/name.js +2 -2
- package/dist/cjs/namefully.js +1 -1
- package/dist/cjs/parser.js +8 -10
- package/dist/cjs/utils.js +2 -4
- package/dist/cjs/validator.js +5 -5
- package/dist/esm/constants.d.ts +2 -2
- package/dist/esm/constants.js +2 -2
- package/dist/esm/error.d.ts +7 -7
- package/dist/esm/error.js +3 -6
- package/dist/esm/name.d.ts +3 -3
- package/dist/esm/name.js +2 -2
- package/dist/esm/namefully.d.ts +6 -5
- package/dist/esm/namefully.js +2 -2
- package/dist/esm/parser.d.ts +2 -5
- package/dist/esm/parser.js +8 -10
- package/dist/esm/utils.d.ts +1 -1
- package/dist/esm/utils.js +2 -4
- package/dist/esm/validator.d.ts +1 -1
- package/dist/esm/validator.js +10 -10
- package/dist/namefully.js +20 -27
- package/dist/namefully.min.js +1 -1
- package/package.json +1 -1
- package/readme.md +2 -4
package/dist/cjs/constants.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.VERSION = '2.0.
|
|
3
|
+
exports.ALLOWED_FORMAT_TOKENS = exports.MAX_NUMBER_OF_NAME_PARTS = exports.MIN_NUMBER_OF_NAME_PARTS = exports.VERSION = void 0;
|
|
4
|
+
exports.VERSION = '2.0.2';
|
|
5
5
|
exports.MIN_NUMBER_OF_NAME_PARTS = 2;
|
|
6
6
|
exports.MAX_NUMBER_OF_NAME_PARTS = 5;
|
|
7
|
-
exports.
|
|
7
|
+
exports.ALLOWED_FORMAT_TOKENS = [
|
|
8
8
|
'.',
|
|
9
9
|
',',
|
|
10
10
|
' ',
|
package/dist/cjs/error.js
CHANGED
|
@@ -19,14 +19,11 @@ class NameError extends Error {
|
|
|
19
19
|
this.name = 'NameError';
|
|
20
20
|
}
|
|
21
21
|
get sourceAsString() {
|
|
22
|
-
let input = '';
|
|
23
|
-
if (!this.source)
|
|
24
|
-
input = '<undefined>';
|
|
25
22
|
if (typeof this.source === 'string')
|
|
26
|
-
|
|
23
|
+
return this.source;
|
|
27
24
|
if ((0, utils_js_1.isStringArray)(this.source))
|
|
28
|
-
|
|
29
|
-
return
|
|
25
|
+
return this.source.join(' ');
|
|
26
|
+
return '<undefined>';
|
|
30
27
|
}
|
|
31
28
|
get hasMessage() {
|
|
32
29
|
return this.message.trim().length > 0;
|
package/dist/cjs/name.js
CHANGED
|
@@ -75,8 +75,8 @@ class Name {
|
|
|
75
75
|
return this;
|
|
76
76
|
}
|
|
77
77
|
validate(name) {
|
|
78
|
-
if (name && name
|
|
79
|
-
throw new error_js_1.InputError({ source: name, message: 'must be
|
|
78
|
+
if (typeof name === 'string' && name.trim().length < 1) {
|
|
79
|
+
throw new error_js_1.InputError({ source: name, message: 'must be 1+ characters' });
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
}
|
package/dist/cjs/namefully.js
CHANGED
|
@@ -245,7 +245,7 @@ class Namefully {
|
|
|
245
245
|
let group = '';
|
|
246
246
|
const formatted = [];
|
|
247
247
|
for (const char of pattern) {
|
|
248
|
-
if (constants_js_1.
|
|
248
|
+
if (constants_js_1.ALLOWED_FORMAT_TOKENS.indexOf(char) === -1) {
|
|
249
249
|
throw new error_js_1.NotAllowedError({
|
|
250
250
|
source: this.full,
|
|
251
251
|
operation: 'format',
|
package/dist/cjs/parser.js
CHANGED
|
@@ -84,16 +84,7 @@ exports.ArrayStringParser = ArrayStringParser;
|
|
|
84
84
|
class NamaParser extends Parser {
|
|
85
85
|
parse(options) {
|
|
86
86
|
const config = config_js_1.Config.merge(options);
|
|
87
|
-
|
|
88
|
-
validator_js_1.NamaValidator.create().validateKeys(this.#asNama());
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
validator_js_1.NamaValidator.create().validate(this.#asNama());
|
|
92
|
-
}
|
|
93
|
-
return fullname_js_1.FullName.parse(this.raw, config);
|
|
94
|
-
}
|
|
95
|
-
#asNama() {
|
|
96
|
-
return new Map(Object.entries(this.raw).map(([key, value]) => {
|
|
87
|
+
const names = new Map(Object.entries(this.raw).map(([key, value]) => {
|
|
97
88
|
const namon = types_js_1.Namon.cast(key);
|
|
98
89
|
if (!namon) {
|
|
99
90
|
throw new error_js_1.InputError({
|
|
@@ -103,6 +94,13 @@ class NamaParser extends Parser {
|
|
|
103
94
|
}
|
|
104
95
|
return [namon, value];
|
|
105
96
|
}));
|
|
97
|
+
if (config.bypass) {
|
|
98
|
+
validator_js_1.NamaValidator.create().validateKeys(names);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
validator_js_1.NamaValidator.create().validate(names);
|
|
102
|
+
}
|
|
103
|
+
return fullname_js_1.FullName.parse(this.raw, config);
|
|
106
104
|
}
|
|
107
105
|
}
|
|
108
106
|
exports.NamaParser = NamaParser;
|
package/dist/cjs/utils.js
CHANGED
|
@@ -73,16 +73,14 @@ exports.NameIndex = NameIndex;
|
|
|
73
73
|
function capitalize(str, range = types_js_1.CapsRange.INITIAL) {
|
|
74
74
|
if (!str || range === types_js_1.CapsRange.NONE)
|
|
75
75
|
return str;
|
|
76
|
-
const initial = str[0].toUpperCase();
|
|
77
|
-
const rest = str.slice(1).toLowerCase();
|
|
76
|
+
const [initial, rest] = [str[0].toUpperCase(), str.slice(1).toLowerCase()];
|
|
78
77
|
return range === types_js_1.CapsRange.INITIAL ? initial.concat(rest) : str.toUpperCase();
|
|
79
78
|
}
|
|
80
79
|
exports.capitalize = capitalize;
|
|
81
80
|
function decapitalize(str, range = types_js_1.CapsRange.INITIAL) {
|
|
82
81
|
if (!str || range === types_js_1.CapsRange.NONE)
|
|
83
82
|
return str;
|
|
84
|
-
const initial = str[0].toLowerCase();
|
|
85
|
-
const rest = str.slice(1);
|
|
83
|
+
const [initial, rest] = [str[0].toLowerCase(), str.slice(1)];
|
|
86
84
|
return range === types_js_1.CapsRange.INITIAL ? initial.concat(rest) : str.toLowerCase();
|
|
87
85
|
}
|
|
88
86
|
exports.decapitalize = decapitalize;
|
package/dist/cjs/validator.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Validators = exports.ArrayNameValidator = exports.ArrayStringValidator = exports.NamaValidator = void 0;
|
|
4
|
-
const constants_js_1 = require("./constants.js");
|
|
5
|
-
const error_js_1 = require("./error.js");
|
|
6
|
-
const name_js_1 = require("./name.js");
|
|
7
4
|
const types_js_1 = require("./types.js");
|
|
8
5
|
const utils_js_1 = require("./utils.js");
|
|
6
|
+
const name_js_1 = require("./name.js");
|
|
7
|
+
const error_js_1 = require("./error.js");
|
|
8
|
+
const constants_js_1 = require("./constants.js");
|
|
9
9
|
class ValidationRule {
|
|
10
10
|
static base = /[a-zA-Z\u00C0-\u00D6\u00D8-\u00f6\u00f8-\u00ff\u0400-\u04FFΆ-ωΑ-ώ]/;
|
|
11
11
|
static namon = new RegExp(`^${ValidationRule.base.source}+(([' -]${ValidationRule.base.source})?${ValidationRule.base.source}*)*$`);
|
|
@@ -21,7 +21,7 @@ class ArrayValidator {
|
|
|
21
21
|
if (values.length === 0 || values.length < constants_js_1.MIN_NUMBER_OF_NAME_PARTS || values.length > constants_js_1.MAX_NUMBER_OF_NAME_PARTS) {
|
|
22
22
|
throw new error_js_1.InputError({
|
|
23
23
|
source: values.map((n) => n.toString()),
|
|
24
|
-
message: `expecting a list of ${constants_js_1.MIN_NUMBER_OF_NAME_PARTS}-${constants_js_1.
|
|
24
|
+
message: `expecting a list of ${constants_js_1.MIN_NUMBER_OF_NAME_PARTS}-${constants_js_1.MAX_NUMBER_OF_NAME_PARTS} elements`,
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
}
|
|
@@ -175,7 +175,7 @@ class NamaValidator {
|
|
|
175
175
|
else if (nama.size < constants_js_1.MIN_NUMBER_OF_NAME_PARTS || nama.size > constants_js_1.MAX_NUMBER_OF_NAME_PARTS) {
|
|
176
176
|
throw new error_js_1.InputError({
|
|
177
177
|
source: [...nama.values()],
|
|
178
|
-
message: `expecting ${constants_js_1.MIN_NUMBER_OF_NAME_PARTS}-${constants_js_1.
|
|
178
|
+
message: `expecting ${constants_js_1.MIN_NUMBER_OF_NAME_PARTS}-${constants_js_1.MAX_NUMBER_OF_NAME_PARTS} fields`,
|
|
179
179
|
});
|
|
180
180
|
}
|
|
181
181
|
if (!nama.has(types_js_1.Namon.FIRST_NAME)) {
|
package/dist/esm/constants.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const VERSION = "2.0.
|
|
1
|
+
export declare const VERSION = "2.0.2";
|
|
2
2
|
export declare const MIN_NUMBER_OF_NAME_PARTS = 2;
|
|
3
3
|
export declare const MAX_NUMBER_OF_NAME_PARTS = 5;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const ALLOWED_FORMAT_TOKENS: string[];
|
package/dist/esm/constants.js
CHANGED
package/dist/esm/error.d.ts
CHANGED
|
@@ -40,8 +40,8 @@ export declare enum NameErrorType {
|
|
|
40
40
|
* program failure. Au contraire, it is expected that a programmer using this utility
|
|
41
41
|
* would consider validating a name using its own business rules. That is not
|
|
42
42
|
* this utility's job to guess those rules. So, the predefined `ValidationRules`
|
|
43
|
-
* obey some common validation techniques when it comes to sanitizing a
|
|
44
|
-
* name. For this reason, the
|
|
43
|
+
* obey some common validation techniques when it comes to sanitizing a personal
|
|
44
|
+
* name. For this reason, the `Config.bypass` is set to `true` by default,
|
|
45
45
|
* indicating that those predefined rules should be skipped for the sake of the
|
|
46
46
|
* program.
|
|
47
47
|
*
|
|
@@ -50,7 +50,7 @@ export declare enum NameErrorType {
|
|
|
50
50
|
*
|
|
51
51
|
* A name error intends to provide useful information about what causes the error
|
|
52
52
|
* and let the user take initiative on what happens next to the given name:
|
|
53
|
-
* reconstructing it or
|
|
53
|
+
* reconstructing it or discarding it.
|
|
54
54
|
*/
|
|
55
55
|
export declare class NameError extends Error {
|
|
56
56
|
readonly source: NameSource;
|
|
@@ -58,8 +58,8 @@ export declare class NameError extends Error {
|
|
|
58
58
|
/**
|
|
59
59
|
* Creates an error with a message describing the issue for a name source.
|
|
60
60
|
* @param source name input that caused the error
|
|
61
|
-
* @param message
|
|
62
|
-
* @param type of `NameErrorType`
|
|
61
|
+
* @param message describing the failure.
|
|
62
|
+
* @param type of error via `NameErrorType`
|
|
63
63
|
*/
|
|
64
64
|
constructor(source: NameSource, message?: string, type?: NameErrorType);
|
|
65
65
|
/** The actual source input which caused the error. */
|
|
@@ -72,9 +72,9 @@ export declare class NameError extends Error {
|
|
|
72
72
|
/**
|
|
73
73
|
* An error thrown when a name source input is incorrect.
|
|
74
74
|
*
|
|
75
|
-
* A `Name` is a name for this utility under certain criteria (i.e.,
|
|
75
|
+
* A `Name` is a name for this utility under certain criteria (i.e., 1+ chars),
|
|
76
76
|
* hence, a wrong input will cause this kind of error. Another common reason
|
|
77
|
-
* may be a wrong key in a
|
|
77
|
+
* may be a wrong key in a JSON name parsing mechanism.
|
|
78
78
|
*
|
|
79
79
|
* Keep in mind that this error is different from a `ValidationError`.
|
|
80
80
|
*/
|
package/dist/esm/error.js
CHANGED
|
@@ -16,14 +16,11 @@ export class NameError extends Error {
|
|
|
16
16
|
this.name = 'NameError';
|
|
17
17
|
}
|
|
18
18
|
get sourceAsString() {
|
|
19
|
-
let input = '';
|
|
20
|
-
if (!this.source)
|
|
21
|
-
input = '<undefined>';
|
|
22
19
|
if (typeof this.source === 'string')
|
|
23
|
-
|
|
20
|
+
return this.source;
|
|
24
21
|
if (isStringArray(this.source))
|
|
25
|
-
|
|
26
|
-
return
|
|
22
|
+
return this.source.join(' ');
|
|
23
|
+
return '<undefined>';
|
|
27
24
|
}
|
|
28
25
|
get hasMessage() {
|
|
29
26
|
return this.message.trim().length > 0;
|
package/dist/esm/name.d.ts
CHANGED
|
@@ -84,8 +84,8 @@ export declare class LastName extends Name {
|
|
|
84
84
|
/**
|
|
85
85
|
* Creates an extended version of `Name` and flags it as a last name `type`.
|
|
86
86
|
*
|
|
87
|
-
* Some people may keep their
|
|
88
|
-
* from their
|
|
87
|
+
* Some people may keep their @param mother's surname and want to keep a clear cut
|
|
88
|
+
* from their @param father's surname. However, there are no clear rules about it.
|
|
89
89
|
*/
|
|
90
90
|
constructor(father: string, mother?: string, format?: Surname);
|
|
91
91
|
/** The surname inherited from the father side. */
|
|
@@ -108,7 +108,7 @@ export declare class LastName extends Name {
|
|
|
108
108
|
format?: Surname;
|
|
109
109
|
}): LastName;
|
|
110
110
|
}
|
|
111
|
-
export declare function isNameArray(value?: unknown):
|
|
111
|
+
export declare function isNameArray(value?: unknown): value is Name[];
|
|
112
112
|
/** JSON signature for `FullName` data. */
|
|
113
113
|
export interface JsonName {
|
|
114
114
|
prefix?: string;
|
package/dist/esm/name.js
CHANGED
|
@@ -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
|
}
|
package/dist/esm/namefully.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ import { Parser } from './parser.js';
|
|
|
31
31
|
* this: `John Smith`, where `John` is the first name piece and `Smith`, the last
|
|
32
32
|
* name piece.
|
|
33
33
|
*
|
|
34
|
-
* @see {link 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}
|
|
35
35
|
* for more info on name standards.
|
|
36
36
|
*
|
|
37
37
|
* **IMPORTANT**: Keep in mind that the order of appearance (or name order) matters
|
|
@@ -50,13 +50,14 @@ import { Parser } from './parser.js';
|
|
|
50
50
|
*/
|
|
51
51
|
export declare class Namefully {
|
|
52
52
|
#private;
|
|
53
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Creates a name with distinguishable parts.
|
|
54
55
|
* @param names element to parse.
|
|
55
56
|
* @param options additional settings.
|
|
56
57
|
*
|
|
57
58
|
* Optional parameters may be provided with specifics on how to treat a full
|
|
58
|
-
* name during its existence. All name parts must have at least
|
|
59
|
-
*
|
|
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.
|
|
60
61
|
*/
|
|
61
62
|
constructor(names: string | string[] | Name[] | JsonName | Parser, options?: Partial<Config>);
|
|
62
63
|
/**
|
|
@@ -69,7 +70,7 @@ export declare class Namefully {
|
|
|
69
70
|
/**
|
|
70
71
|
* Constructs a `Namefully` instance from a text.
|
|
71
72
|
*
|
|
72
|
-
*
|
|
73
|
+
* @throws a `NameError` if the @param text cannot be parsed. Use `tryParse`
|
|
73
74
|
* instead if a `null` return is preferred over a throwable error.
|
|
74
75
|
*
|
|
75
76
|
* This operation is computed asynchronously, which gives more flexibility at
|
package/dist/esm/namefully.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
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
4
|
import { Flat, NameOrder, NameType, Namon } from './types.js';
|
|
@@ -242,7 +242,7 @@ export class Namefully {
|
|
|
242
242
|
let group = '';
|
|
243
243
|
const formatted = [];
|
|
244
244
|
for (const char of pattern) {
|
|
245
|
-
if (
|
|
245
|
+
if (ALLOWED_FORMAT_TOKENS.indexOf(char) === -1) {
|
|
246
246
|
throw new NotAllowedError({
|
|
247
247
|
source: this.full,
|
|
248
248
|
operation: 'format',
|
package/dist/esm/parser.d.ts
CHANGED
|
@@ -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
|
@@ -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 {
|
package/dist/esm/utils.d.ts
CHANGED
|
@@ -50,4 +50,4 @@ export declare function capitalize(str: string, range?: CapsRange): string;
|
|
|
50
50
|
export declare function decapitalize(str: string, range?: CapsRange): string;
|
|
51
51
|
/** Toggles a string representation. */
|
|
52
52
|
export declare function toggleCase(str: string): string;
|
|
53
|
-
export declare function isStringArray(value?: unknown):
|
|
53
|
+
export declare function isStringArray(value?: unknown): value is string[];
|
package/dist/esm/utils.js
CHANGED
|
@@ -69,15 +69,13 @@ export class NameIndex {
|
|
|
69
69
|
export function capitalize(str, range = CapsRange.INITIAL) {
|
|
70
70
|
if (!str || range === CapsRange.NONE)
|
|
71
71
|
return str;
|
|
72
|
-
const initial = str[0].toUpperCase();
|
|
73
|
-
const rest = str.slice(1).toLowerCase();
|
|
72
|
+
const [initial, rest] = [str[0].toUpperCase(), str.slice(1).toLowerCase()];
|
|
74
73
|
return range === CapsRange.INITIAL ? initial.concat(rest) : str.toUpperCase();
|
|
75
74
|
}
|
|
76
75
|
export function decapitalize(str, range = CapsRange.INITIAL) {
|
|
77
76
|
if (!str || range === CapsRange.NONE)
|
|
78
77
|
return str;
|
|
79
|
-
const initial = str[0].toLowerCase();
|
|
80
|
-
const rest = str.slice(1);
|
|
78
|
+
const [initial, rest] = [str[0].toLowerCase(), str.slice(1)];
|
|
81
79
|
return range === CapsRange.INITIAL ? initial.concat(rest) : str.toLowerCase();
|
|
82
80
|
}
|
|
83
81
|
export function toggleCase(str) {
|
package/dist/esm/validator.d.ts
CHANGED
package/dist/esm/validator.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { MIN_NUMBER_OF_NAME_PARTS, MAX_NUMBER_OF_NAME_PARTS } from './constants.js';
|
|
2
|
-
import { InputError, ValidationError } from './error.js';
|
|
3
|
-
import { FirstName, LastName, Name, isNameArray } from './name.js';
|
|
4
1
|
import { Namon } from './types.js';
|
|
5
2
|
import { NameIndex } from './utils.js';
|
|
3
|
+
import { FirstName, LastName, Name, isNameArray } from './name.js';
|
|
4
|
+
import { InputError, ValidationError } from './error.js';
|
|
5
|
+
import { MIN_NUMBER_OF_NAME_PARTS as MIN, MAX_NUMBER_OF_NAME_PARTS as MAX } from './constants.js';
|
|
6
6
|
class ValidationRule {
|
|
7
7
|
static base = /[a-zA-Z\u00C0-\u00D6\u00D8-\u00f6\u00f8-\u00ff\u0400-\u04FFΆ-ωΑ-ώ]/;
|
|
8
8
|
static namon = new RegExp(`^${ValidationRule.base.source}+(([' -]${ValidationRule.base.source})?${ValidationRule.base.source}*)*$`);
|
|
@@ -15,10 +15,10 @@ const toNameSource = (values) => {
|
|
|
15
15
|
};
|
|
16
16
|
class ArrayValidator {
|
|
17
17
|
validate(values) {
|
|
18
|
-
if (values.length === 0 || values.length <
|
|
18
|
+
if (values.length === 0 || values.length < MIN || values.length > MAX) {
|
|
19
19
|
throw new InputError({
|
|
20
20
|
source: values.map((n) => n.toString()),
|
|
21
|
-
message: `expecting a list of ${
|
|
21
|
+
message: `expecting a list of ${MIN}-${MAX} elements`,
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -169,10 +169,10 @@ export class NamaValidator {
|
|
|
169
169
|
if (!nama.size) {
|
|
170
170
|
throw new InputError({ source: undefined, message: 'Map<k,v> must not be empty' });
|
|
171
171
|
}
|
|
172
|
-
else if (nama.size <
|
|
172
|
+
else if (nama.size < MIN || nama.size > MAX) {
|
|
173
173
|
throw new InputError({
|
|
174
174
|
source: [...nama.values()],
|
|
175
|
-
message: `expecting ${
|
|
175
|
+
message: `expecting ${MIN}-${MAX} fields`,
|
|
176
176
|
});
|
|
177
177
|
}
|
|
178
178
|
if (!nama.has(Namon.FIRST_NAME)) {
|
|
@@ -210,10 +210,10 @@ export class ArrayNameValidator {
|
|
|
210
210
|
return this.#validator || (this.#validator = new ArrayNameValidator());
|
|
211
211
|
}
|
|
212
212
|
validate(value) {
|
|
213
|
-
if (value.length <
|
|
213
|
+
if (value.length < MIN) {
|
|
214
214
|
throw new InputError({
|
|
215
215
|
source: toNameSource(value),
|
|
216
|
-
message: `expecting at least ${
|
|
216
|
+
message: `expecting at least ${MIN} elements`,
|
|
217
217
|
});
|
|
218
218
|
}
|
|
219
219
|
if (!this.#hasBasicNames(value)) {
|
|
@@ -230,7 +230,7 @@ export class ArrayNameValidator {
|
|
|
230
230
|
accumulator[name.type.key] = name.toString();
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
|
-
return Object.keys(accumulator).length ===
|
|
233
|
+
return Object.keys(accumulator).length === MIN;
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
export class Validators {
|
package/dist/namefully.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
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.0.2';
|
|
8
8
|
const MIN_NUMBER_OF_NAME_PARTS = 2;
|
|
9
9
|
const MAX_NUMBER_OF_NAME_PARTS = 5;
|
|
10
|
-
const
|
|
10
|
+
const ALLOWED_FORMAT_TOKENS = [
|
|
11
11
|
'.',
|
|
12
12
|
',',
|
|
13
13
|
' ',
|
|
@@ -208,15 +208,13 @@
|
|
|
208
208
|
function capitalize(str, range = exports.CapsRange.INITIAL) {
|
|
209
209
|
if (!str || range === exports.CapsRange.NONE)
|
|
210
210
|
return str;
|
|
211
|
-
const initial = str[0].toUpperCase();
|
|
212
|
-
const rest = str.slice(1).toLowerCase();
|
|
211
|
+
const [initial, rest] = [str[0].toUpperCase(), str.slice(1).toLowerCase()];
|
|
213
212
|
return range === exports.CapsRange.INITIAL ? initial.concat(rest) : str.toUpperCase();
|
|
214
213
|
}
|
|
215
214
|
function decapitalize(str, range = exports.CapsRange.INITIAL) {
|
|
216
215
|
if (!str || range === exports.CapsRange.NONE)
|
|
217
216
|
return str;
|
|
218
|
-
const initial = str[0].toLowerCase();
|
|
219
|
-
const rest = str.slice(1);
|
|
217
|
+
const [initial, rest] = [str[0].toLowerCase(), str.slice(1)];
|
|
220
218
|
return range === exports.CapsRange.INITIAL ? initial.concat(rest) : str.toLowerCase();
|
|
221
219
|
}
|
|
222
220
|
function toggleCase(str) {
|
|
@@ -246,14 +244,11 @@
|
|
|
246
244
|
this.name = 'NameError';
|
|
247
245
|
}
|
|
248
246
|
get sourceAsString() {
|
|
249
|
-
let input = '';
|
|
250
|
-
if (!this.source)
|
|
251
|
-
input = '<undefined>';
|
|
252
247
|
if (typeof this.source === 'string')
|
|
253
|
-
|
|
248
|
+
return this.source;
|
|
254
249
|
if (isStringArray(this.source))
|
|
255
|
-
|
|
256
|
-
return
|
|
250
|
+
return this.source.join(' ');
|
|
251
|
+
return '<undefined>';
|
|
257
252
|
}
|
|
258
253
|
get hasMessage() {
|
|
259
254
|
return this.message.trim().length > 0;
|
|
@@ -387,8 +382,8 @@
|
|
|
387
382
|
return this;
|
|
388
383
|
}
|
|
389
384
|
validate(name) {
|
|
390
|
-
if (name && name
|
|
391
|
-
throw new InputError({ source: name, message: 'must be
|
|
385
|
+
if (typeof name === 'string' && name.trim().length < 1) {
|
|
386
|
+
throw new InputError({ source: name, message: 'must be 1+ characters' });
|
|
392
387
|
}
|
|
393
388
|
}
|
|
394
389
|
}
|
|
@@ -641,7 +636,7 @@
|
|
|
641
636
|
if (values.length === 0 || values.length < MIN_NUMBER_OF_NAME_PARTS || values.length > MAX_NUMBER_OF_NAME_PARTS) {
|
|
642
637
|
throw new InputError({
|
|
643
638
|
source: values.map((n) => n.toString()),
|
|
644
|
-
message: `expecting a list of ${MIN_NUMBER_OF_NAME_PARTS}-${
|
|
639
|
+
message: `expecting a list of ${MIN_NUMBER_OF_NAME_PARTS}-${MAX_NUMBER_OF_NAME_PARTS} elements`,
|
|
645
640
|
});
|
|
646
641
|
}
|
|
647
642
|
}
|
|
@@ -795,7 +790,7 @@
|
|
|
795
790
|
else if (nama.size < MIN_NUMBER_OF_NAME_PARTS || nama.size > MAX_NUMBER_OF_NAME_PARTS) {
|
|
796
791
|
throw new InputError({
|
|
797
792
|
source: [...nama.values()],
|
|
798
|
-
message: `expecting ${MIN_NUMBER_OF_NAME_PARTS}-${
|
|
793
|
+
message: `expecting ${MIN_NUMBER_OF_NAME_PARTS}-${MAX_NUMBER_OF_NAME_PARTS} fields`,
|
|
799
794
|
});
|
|
800
795
|
}
|
|
801
796
|
if (!nama.has(Namon.FIRST_NAME)) {
|
|
@@ -1032,16 +1027,7 @@
|
|
|
1032
1027
|
class NamaParser extends Parser {
|
|
1033
1028
|
parse(options) {
|
|
1034
1029
|
const config = Config.merge(options);
|
|
1035
|
-
|
|
1036
|
-
NamaValidator.create().validateKeys(this.#asNama());
|
|
1037
|
-
}
|
|
1038
|
-
else {
|
|
1039
|
-
NamaValidator.create().validate(this.#asNama());
|
|
1040
|
-
}
|
|
1041
|
-
return FullName.parse(this.raw, config);
|
|
1042
|
-
}
|
|
1043
|
-
#asNama() {
|
|
1044
|
-
return new Map(Object.entries(this.raw).map(([key, value]) => {
|
|
1030
|
+
const names = new Map(Object.entries(this.raw).map(([key, value]) => {
|
|
1045
1031
|
const namon = Namon.cast(key);
|
|
1046
1032
|
if (!namon) {
|
|
1047
1033
|
throw new InputError({
|
|
@@ -1051,6 +1037,13 @@
|
|
|
1051
1037
|
}
|
|
1052
1038
|
return [namon, value];
|
|
1053
1039
|
}));
|
|
1040
|
+
if (config.bypass) {
|
|
1041
|
+
NamaValidator.create().validateKeys(names);
|
|
1042
|
+
}
|
|
1043
|
+
else {
|
|
1044
|
+
NamaValidator.create().validate(names);
|
|
1045
|
+
}
|
|
1046
|
+
return FullName.parse(this.raw, config);
|
|
1054
1047
|
}
|
|
1055
1048
|
}
|
|
1056
1049
|
class ArrayNameParser extends Parser {
|
|
@@ -1318,7 +1311,7 @@
|
|
|
1318
1311
|
let group = '';
|
|
1319
1312
|
const formatted = [];
|
|
1320
1313
|
for (const char of pattern) {
|
|
1321
|
-
if (
|
|
1314
|
+
if (ALLOWED_FORMAT_TOKENS.indexOf(char) === -1) {
|
|
1322
1315
|
throw new NotAllowedError({
|
|
1323
1316
|
source: this.full,
|
|
1324
1317
|
operation: 'format',
|
package/dist/namefully.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).namefully={})}(this,function(e){"use strict";const t=[".",","," ","-","_","b","B","f","F","l","L","m","M","n","N","o","O","p","P","s","S","$"];var s,a,i,r,n,o,h,l;e.Title=void 0,(s=e.Title||(e.Title={})).US="US",s.UK="UK",e.Surname=void 0,(a=e.Surname||(e.Surname={})).FATHER="father",a.MOTHER="mother",a.HYPHENATED="hyphenated",a.ALL="all",e.NameOrder=void 0,(i=e.NameOrder||(e.NameOrder={})).FIRST_NAME="firstName",i.LAST_NAME="lastName",e.NameType=void 0,(r=e.NameType||(e.NameType={})).FIRST_NAME="firstName",r.MIDDLE_NAME="middleName",r.LAST_NAME="lastName",r.BIRTH_NAME="birthName",e.Flat=void 0,(n=e.Flat||(e.Flat={})).FIRST_NAME="firstName",n.MIDDLE_NAME="middleName",n.LAST_NAME="lastName",n.FIRST_MID="firstMid",n.MID_LAST="midLast",n.ALL="all",e.CapsRange=void 0,(o=e.CapsRange||(e.CapsRange={}))[o.NONE=0]="NONE",o[o.INITIAL=1]="INITIAL",o[o.ALL=2]="ALL";class u{index;key;static PREFIX=new u(0,"prefix");static FIRST_NAME=new u(1,"firstName");static MIDDLE_NAME=new u(2,"middleName");static LAST_NAME=new u(3,"lastName");static SUFFIX=new u(4,"suffix");static values=[u.PREFIX,u.FIRST_NAME,u.MIDDLE_NAME,u.LAST_NAME,u.SUFFIX];static all=new Map([[u.PREFIX.key,u.PREFIX],[u.FIRST_NAME.key,u.FIRST_NAME],[u.MIDDLE_NAME.key,u.MIDDLE_NAME],[u.LAST_NAME.key,u.LAST_NAME],[u.SUFFIX.key,u.SUFFIX]]);constructor(e,t){this.index=e,this.key=t}static has(e){return u.all.has(e)}static cast(e){return u.has(e)?u.all.get(e):void 0}toString(){return`Namon.${this.key}`}equal(e){return e instanceof u&&e.index===this.index&&e.key===this.key}}class m{name;token;static COMMA=new m("comma",",");static COLON=new m("colon",":");static DOUBLE_QUOTE=new m("doubleQuote",'"');static EMPTY=new m("empty","");static HYPHEN=new m("hyphen","-");static PERIOD=new m("period",".");static SEMI_COLON=new m("semiColon",";");static SINGLE_QUOTE=new m("singleQuote","'");static SPACE=new m("space"," ");static UNDERSCORE=new m("underscore","_");static all=new Map([[m.COMMA.name,m.COMMA],[m.COLON.name,m.COLON],[m.DOUBLE_QUOTE.name,m.DOUBLE_QUOTE],[m.EMPTY.name,m.EMPTY],[m.HYPHEN.name,m.HYPHEN],[m.PERIOD.name,m.PERIOD],[m.SEMI_COLON.name,m.SEMI_COLON],[m.SINGLE_QUOTE.name,m.SINGLE_QUOTE],[m.SPACE.name,m.SPACE],[m.UNDERSCORE.name,m.UNDERSCORE]]);static tokens=[...m.all.values()].map(e=>e.token);constructor(e,t){this.name=e,this.token=t}toString(){return`Separator.${this.name}`}}class c{prefix;firstName;middleName;lastName;suffix;static get min(){return 2}static get max(){return 5}constructor(e,t,s,a,i){this.prefix=e,this.firstName=t,this.middleName=s,this.lastName=a,this.suffix=i}static base(){return new c(-1,0,-1,1,-1)}static when(t,s=2){if(t===e.NameOrder.FIRST_NAME)switch(s){case 2:return new c(-1,0,-1,1,-1);case 3:return new c(-1,0,1,2,-1);case 4:return new c(0,1,2,3,-1);case 5:return new c(0,1,2,3,4);default:return c.base()}else switch(s){case 2:return new c(-1,1,-1,0,-1);case 3:return new c(-1,1,2,0,-1);case 4:return new c(0,2,3,1,-1);case 5:return new c(0,2,3,1,4);default:return c.base()}}static only({prefix:e=-1,firstName:t,middleName:s=-1,lastName:a,suffix:i=-1}){return new c(e,t,s,a,i)}toJson(){return{prefix:this.prefix,firstName:this.firstName,middleName:this.middleName,lastName:this.lastName,suffix:this.suffix}}json=this.toJson}function d(t,s=e.CapsRange.INITIAL){if(!t||s===e.CapsRange.NONE)return t;const a=t[0].toUpperCase(),i=t.slice(1).toLowerCase();return s===e.CapsRange.INITIAL?a.concat(i):t.toUpperCase()}function f(t,s=e.CapsRange.INITIAL){if(!t||s===e.CapsRange.NONE)return t;const a=t[0].toLowerCase(),i=t.slice(1);return s===e.CapsRange.INITIAL?a.concat(i):t.toLowerCase()}function N(e){return Array.isArray(e)&&e.length>0&&e.every(e=>"string"==typeof e)}e.NameErrorType=void 0,(h=e.NameErrorType||(e.NameErrorType={}))[h.INPUT=0]="INPUT",h[h.VALIDATION=1]="VALIDATION",h[h.NOT_ALLOWED=2]="NOT_ALLOWED",h[h.UNKNOWN=3]="UNKNOWN";class p extends Error{source;type;constructor(t,s,a=e.NameErrorType.UNKNOWN){super(s),this.source=t,this.type=a,this.name="NameError"}get sourceAsString(){let e="";return this.source||(e="<undefined>"),"string"==typeof this.source&&(e=this.source),N(this.source)&&(e=this.source.join(" ")),e}get hasMessage(){return this.message.trim().length>0}toString(){let e=`${this.name} (${this.sourceAsString})`;return this.hasMessage&&(e=`${e}: ${this.message}`),e}}class g extends p{constructor(t){super(t.source,t.message,e.NameErrorType.INPUT),this.name="InputError"}}class E extends p{nameType;constructor(t){super(t.source,t.message,e.NameErrorType.VALIDATION),this.nameType=t.nameType,this.name="ValidationError"}toString(){let e=`${this.name} (${this.nameType}='${this.sourceAsString}')`;return this.hasMessage&&(e=`${e}: ${this.message}`),e}}class w extends p{operation;constructor(t){super(t.source,t.message,e.NameErrorType.NOT_ALLOWED),this.operation=t.operation,this.name="NotAllowedError"}toString(){let e=`${this.name} (${this.sourceAsString})`;return this.operation&&this.operation.trim().length>0&&(e=`${e} - ${this.operation}`),this.hasMessage&&(e=`${e}: ${this.message}`),e}}class y extends p{origin;constructor(t){super(t.source,t.message,e.NameErrorType.UNKNOWN),this.origin=t.origin,this.name="UnknownError"}toString(){let e=super.toString();return this.origin&&(e+=`\n${this.origin.toString()}`),e}}class A{type;#e;initial;capsRange;constructor(t,s,a){this.type=s,this.capsRange=a??e.CapsRange.INITIAL,this.value=t,a&&this.caps(a)}set value(e){this.validate(e),this.#e=e,this.initial=e[0]}get value(){return this.#e}get length(){return this.#e.length}get isPrefix(){return this.type===u.PREFIX}get isFirstName(){return this.type===u.FIRST_NAME}get isMiddleName(){return this.type===u.MIDDLE_NAME}get isLastName(){return this.type===u.LAST_NAME}get isSuffix(){return this.type===u.SUFFIX}static prefix(e){return new A(e,u.PREFIX)}static first(e){return new A(e,u.FIRST_NAME)}static middle(e){return new A(e,u.MIDDLE_NAME)}static last(e){return new A(e,u.LAST_NAME)}static suffix(e){return new A(e,u.SUFFIX)}initials(){return[this.initial]}toString(){return this.#e}equal(e){return e instanceof A&&e.value===this.value&&e.type===this.type}caps(e){return this.value=d(this.#e,e??this.capsRange),this}decaps(e){return this.value=f(this.#e,e??this.capsRange),this}validate(e){if(e&&e?.trim()?.length<2)throw new g({source:e,message:"must be 2+ characters"})}}class M extends A{#t;constructor(e,...t){super(e,u.FIRST_NAME),t.forEach(this.validate),this.#t=t}get hasMore(){return this.#t.length>0}get length(){return super.length+(this.hasMore?this.#t.reduce((e,t)=>e+t).length:0)}get asNames(){const e=[A.first(this.value)];return this.hasMore&&e.push(...this.#t.map(A.first)),e}get more(){return this.#t}toString(e=!1){return e&&this.hasMore?`${this.value} ${this.#t.join(" ")}`.trim():this.value}initials(e=!1){const t=[this.initial];return e&&this.hasMore&&t.push(...this.#t.map(e=>e[0])),t}caps(e){return e=e||this.capsRange,this.value=d(this.value,e),this.hasMore&&(this.#t=this.#t.map(t=>d(t,e))),this}decaps(e){return e=e||this.capsRange,this.value=f(this.value,e),this.hasMore&&(this.#t=this.#t.map(t=>f(t,e))),this}copyWith(e){return new M(e?.first??this.value,...e?.more??this.#t)}}class v extends A{format;#s;constructor(t,s,a=e.Surname.FATHER){super(t,u.LAST_NAME),this.format=a,this.validate(s),this.#s=s}get father(){return this.value}get mother(){return this.#s}get hasMother(){return!!this.#s}get length(){return super.length+(this.#s?.length??0)}get asNames(){const e=[A.last(this.value)];return this.#s&&e.push(A.last(this.#s)),e}toString(t){switch(t=t??this.format){case e.Surname.FATHER:return this.value;case e.Surname.MOTHER:return this.mother??"";case e.Surname.HYPHENATED:return this.hasMother?`${this.value}-${this.#s}`:this.value;case e.Surname.ALL:return this.hasMother?`${this.value} ${this.#s}`:this.value}}initials(t){const s=[];switch(t??this.format){case e.Surname.HYPHENATED:case e.Surname.ALL:s.push(this.initial),this.#s&&s.push(this.#s[0]);break;case e.Surname.MOTHER:this.#s&&s.push(this.#s[0]);break;default:s.push(this.initial)}return s}caps(e){return e??=this.capsRange,this.value=d(this.value,e),this.hasMother&&(this.#s=d(this.#s,e)),this}decaps(e){return e??=this.capsRange,this.value=f(this.value,e),this.hasMother&&(this.#s=f(this.#s,e)),this}copyWith(e){return new v(e?.father??this.value,e?.mother??this.mother,e?.format??this.format)}}function S(e){return Array.isArray(e)&&e.length>0&&e.every(e=>e instanceof A)}const T="_copy";class I{#a;#i;#r;#n;#o;#h;#l;static cache=new Map;get orderedBy(){return this.#i}get separator(){return this.#r}get title(){return this.#n}get ending(){return this.#o}get bypass(){return this.#h}get surname(){return this.#l}get name(){return this.#a}constructor(t,s=e.NameOrder.FIRST_NAME,a=m.SPACE,i=e.Title.UK,r=!1,n=!0,o=e.Surname.FATHER){this.#a=t,this.#i=s,this.#r=a,this.#n=i,this.#o=r,this.#h=n,this.#l=o}static create(e="default"){return l.cache.has(e)||l.cache.set(e,new l(e)),l.cache.get(e)}static merge(e){if(e){const t=l.create(e.name);return t.#i=e.orderedBy??t.orderedBy,t.#r=e.separator??t.separator,t.#n=e.title??t.title,t.#o=e.ending??t.ending,t.#h=e.bypass??t.bypass,t.#l=e.surname??t.surname,t}return l.create()}copyWith(e={}){const{name:t,orderedBy:s,separator:a,title:i,ending:r,bypass:n,surname:o}=e,h=l.create(this.#u(t??this.name+T));return h.#i=s??this.orderedBy,h.#r=a??this.separator,h.#n=i??this.title,h.#o=r??this.ending,h.#h=n??this.bypass,h.#l=o??this.surname,h}clone(){return this.copyWith()}reset(){this.#i=e.NameOrder.FIRST_NAME,this.#r=m.SPACE,this.#n=e.Title.UK,this.#o=!1,this.#h=!0,this.#l=e.Surname.FATHER,l.cache.set(this.name,this)}updateOrder(e){this.update({orderedBy:e})}update({orderedBy:e,title:t,ending:s}){const a=l.cache.get(this.name);a&&(e!==this.#i&&(a.#i=e),t!==this.#n&&(a.#n=t),s!==this.#o&&(a.#o=s))}#u(e){return e===this.name||l.cache.has(e)?this.#u(e+T):e}}l=I;class x{static base=/[a-zA-Z\u00C0-\u00D6\u00D8-\u00f6\u00f8-\u00ff\u0400-\u04FFΆ-ωΑ-ώ]/;static namon=new RegExp(`^${x.base.source}+(([' -]${x.base.source})?${x.base.source}*)*$`);static firstName=x.namon;static middleName=new RegExp(`^${x.base.source}+(([' -]${x.base.source})?${x.base.source}*)*$`);static lastName=x.namon}const L=e=>S(e)?e.map(e=>e.toString()).join(" "):"";class F{validate(e){if(0===e.length||e.length<2||e.length>5)throw new g({source:e.map(e=>e.toString()),message:"expecting a list of 2-2 elements"})}}class _{static#m;static create(){return this.#m||(this.#m=new _)}validate(e,t){if(e instanceof A)D.create().validate(e,t);else{if("string"!=typeof e)throw new g({source:typeof e,message:"expecting types of string or Name"});if(!x.namon.test(e))throw new E({source:e,nameType:"namon",message:"invalid name content failing namon regex"})}}}class b{static#m;static create(){return this.#m||(this.#m=new b)}validate(e){if(e instanceof M)e.asNames.forEach(e=>this.validate(e.value));else{if("string"!=typeof e)throw new g({source:typeof e,message:"expecting types string or FirstName"});if(!x.firstName.test(e))throw new E({source:e,nameType:"firstName",message:"invalid name content failing firstName regex"})}}}class R{static#m;static create(){return this.#m||(this.#m=new R)}validate(e){if("string"==typeof e){if(!x.middleName.test(e))throw new E({source:e,nameType:"middleName",message:"invalid name content failing middleName regex"})}else{if(!Array.isArray(e))throw new g({source:typeof e,message:"expecting types of string, string[] or Name[]"});try{const t=_.create();for(const s of e)t.validate(s,u.MIDDLE_NAME)}catch(t){throw new E({source:L(e),nameType:"middleName",message:t?.message})}}}}class O{static#m;static create(){return this.#m||(this.#m=new O)}validate(e){if(e instanceof v)e.asNames.forEach(e=>this.validate(e.value));else{if("string"!=typeof e)throw new g({source:typeof e,message:"expecting types string or LastName"});if(!x.lastName.test(e))throw new E({source:e,nameType:"lastName",message:"invalid name content failing lastName regex"})}}}class D{static#m;static create(){return this.#m||(this.#m=new D)}validate(e,t){if(t&&e.type!==t)throw new E({source:e.toString(),nameType:e.type.toString(),message:"wrong name type; only Namon types are supported"});if(!x.namon.test(e.value))throw new E({source:e.toString(),nameType:e.type.toString(),message:"invalid name content failing namon regex"})}}class C{static#m;static create(){return this.#m||(this.#m=new C)}validate(e){this.validateKeys(e),$.firstName.validate(e.get(u.FIRST_NAME)),$.lastName.validate(e.get(u.LAST_NAME)),e.has(u.PREFIX)&&$.namon.validate(e.get(u.PREFIX)),e.has(u.SUFFIX)&&$.namon.validate(e.get(u.SUFFIX))}validateKeys(e){if(!e.size)throw new g({source:void 0,message:"Map<k,v> must not be empty"});if(e.size<2||e.size>5)throw new g({source:[...e.values()],message:"expecting 2-2 fields"});if(!e.has(u.FIRST_NAME))throw new g({source:[...e.values()],message:'"firstName" is a required key'});if(!e.has(u.LAST_NAME))throw new g({source:[...e.values()],message:'"lastName" is a required key'})}}class U extends F{index;constructor(e=c.base()){super(),this.index=e}validate(e){this.validateIndex(e),$.firstName.validate(e[this.index.firstName]),$.lastName.validate(e[this.index.lastName]),e.length>=3&&$.middleName.validate(e[this.index.middleName]),e.length>=4&&$.namon.validate(e[this.index.prefix]),5===e.length&&$.namon.validate(e[this.index.suffix])}validateIndex(e){super.validate(e)}}class P{static#m;static create(){return this.#m||(this.#m=new P)}validate(e){if(e.length<2)throw new g({source:L(e),message:"expecting at least 2 elements"});if(!this.#c(e))throw new g({source:L(e),message:"both first and last names are required"})}#c(e){const t={};for(const s of e)(s.isFirstName||s.isLastName)&&(t[s.type.key]=s.toString());return 2===Object.keys(t).length}}class ${static namon=_.create();static nama=C.create();static prefix=_.create();static firstName=b.create();static middleName=R.create();static lastName=O.create();static suffix=_.create()}class j{#d;#f;#N=[];#p;#g;#E;constructor(e){this.#E=I.merge(e)}get config(){return this.#E}get prefix(){return this.#d}get firstName(){return this.#f}get lastName(){return this.#p}get middleName(){return this.#N}get suffix(){return this.#g}static parse(e,t){try{return new j(t).setPrefix(e.prefix).setFirstName(e.firstName).setMiddleName(e.middleName??[]).setLastName(e.lastName).setSuffix(e.suffix)}catch(t){if(t instanceof p)throw t;throw new y({source:Object.values(e).join(" "),message:"could not parse JSON content",origin:t instanceof Error?t:new Error(String(t))})}}setPrefix(t){if(!t)return this;this.#E.bypass||$.prefix.validate(t);const s=t instanceof A?t.value:t;return this.#d=A.prefix(this.#E.title===e.Title.US?`${s}.`:s),this}setFirstName(e){return this.#E.bypass||$.firstName.validate(e),this.#f=e instanceof M?e:new M(e),this}setLastName(e){return this.#E.bypass||$.lastName.validate(e),this.#p=e instanceof v?e:new v(e),this}setMiddleName(e){return Array.isArray(e)?(this.#E.bypass||$.middleName.validate(e),this.#N=e.map(e=>e instanceof A?e:A.middle(e)),this):this}setSuffix(e){return e?(this.#E.bypass||$.suffix.validate(e),this.#g=A.suffix(e instanceof A?e.value:e),this):this}has(e){return e.equal(u.PREFIX)?!!this.#d:e.equal(u.SUFFIX)?!!this.#g:!e.equal(u.MIDDLE_NAME)||this.#N.length>0}}class k{raw;constructor(e){this.raw=e}static build(e,t){const s=e.trim().split(m.SPACE.token),a=s.length;if(t instanceof c){const e=Object.entries(t.json()).filter(([,e])=>e>-1&&e<a).map(([e,t])=>new A(s[t],u.all.get(e)));return new X(e)}if(a<2)throw new g({source:e,message:"cannot build from invalid input"});if(2===a||3===a)return new B(e);{const e=s.pop(),[t,...a]=s;return new q([t,a.join(" "),e])}}static buildAsync(e,t){try{return Promise.resolve(k.build(e,t))}catch(e){return Promise.reject(e)}}}class B extends k{parse(e){const t=I.merge(e),s=this.raw.split(t.separator.token);return new q(s).parse(e)}}class q extends k{parse(e){const t=I.merge(e),s=new j(t),a=this.raw.map(e=>e.trim()),i=c.when(t.orderedBy,a.length),r=new U(i);t.bypass?r.validateIndex(a):r.validate(a);const{firstName:n,lastName:o,middleName:h,prefix:l,suffix:u}=i;return s.setFirstName(new M(a[n])),s.setLastName(new v(a[o])),a.length>=3&&s.setMiddleName(a[h].split(t.separator.token)),a.length>=4&&s.setPrefix(A.prefix(a[l])),5===a.length&&s.setSuffix(A.suffix(a[u])),s}}class H extends k{parse(e){const t=I.merge(e);return t.bypass?C.create().validateKeys(this.#w()):C.create().validate(this.#w()),j.parse(this.raw,t)}#w(){return new Map(Object.entries(this.raw).map(([e,t])=>{const s=u.cast(e);if(!s)throw new g({source:Object.values(this.raw).join(" "),message:`unsupported key "${e}"`});return[s,t]}))}}class X extends k{parse(e){const t=I.merge(e),s=new j(t);P.create().validate(this.raw);for(const e of this.raw)if(e.isPrefix)s.setPrefix(e);else if(e.isSuffix)s.setSuffix(e);else if(e.isFirstName)s.setFirstName(e instanceof M?e:new M(e.value));else if(e.isMiddleName)s.middleName.push(e);else if(e.isLastName){const a=new v(e.value,e instanceof v?e.mother:void 0,t.surname);s.setLastName(a)}return s}}class W{#y;constructor(e,t){this.#y=this.#A(e).parse(t)}static tryParse(e,t){try{return new W(k.build(e,t))}catch{return}}static async parse(e,t){return k.buildAsync(e,t).then(e=>new W(e))}get config(){return this.#y.config}get length(){return this.birth.length}get prefix(){return this.#y.prefix?.toString()}get first(){return this.firstName()}get middle(){return this.hasMiddle?this.middleName()[0]:void 0}get hasMiddle(){return this.#y.has(u.MIDDLE_NAME)}get last(){return this.lastName()}get suffix(){return this.#y.suffix?.toString()}get birth(){return this.birthName()}get short(){return this.shorten()}get long(){return this.birth}get full(){return this.fullName()}get public(){return this.format("f $l")}get salutation(){return this.format("p l")}toString(){return this.full}get(e){return e.equal(u.PREFIX)?this.#y.prefix:e.equal(u.FIRST_NAME)?this.#y.firstName:e.equal(u.MIDDLE_NAME)?this.#y.middleName:e.equal(u.LAST_NAME)?this.#y.lastName:e.equal(u.SUFFIX)?this.#y.suffix:void 0}equal(e){return this.toString()===e.toString()}toJson(){return{prefix:this.prefix,firstName:this.first,middleName:this.middleName(),lastName:this.last,suffix:this.suffix}}json=this.toJson;has(e){return this.#y.has(e)}fullName(t){const s=this.config.ending?",":"",a=[];return this.prefix&&a.push(this.prefix),(t??this.config.orderedBy)===e.NameOrder.FIRST_NAME?a.push(this.first,...this.middleName(),this.last+s):a.push(this.last,this.first,this.middleName().join(" ")+s),this.suffix&&a.push(this.suffix),a.join(" ").trim()}birthName(t){return t??=this.config.orderedBy,t===e.NameOrder.FIRST_NAME?[this.first,...this.middleName(),this.last].join(" "):[this.last,this.first,...this.middleName()].join(" ")}firstName(e=!0){return this.#y.firstName.toString(e)}middleName(){return this.#y.middleName.map(e=>e.value)}lastName(e){return this.#y.lastName.toString(e)}initials(t){const{orderedBy:s=this.config.orderedBy,only:a=e.NameType.BIRTH_NAME,asJson:i}=t??{},r=this.#y.firstName.initials(),n=this.#y.middleName.map(e=>e.value[0]),o=this.#y.lastName.initials();return i?{firstName:r,middleName:n,lastName:o}:a!==e.NameType.BIRTH_NAME?a===e.NameType.FIRST_NAME?r:a===e.NameType.MIDDLE_NAME?n:o:s===e.NameOrder.FIRST_NAME?[...r,...n,...o]:[...o,...r,...n]}shorten(t){t??=this.config.orderedBy;const{firstName:s,lastName:a}=this.#y;return t===e.NameOrder.FIRST_NAME?[s.value,a.toString()].join(" "):[a.toString(),s.value].join(" ")}flatten(t){const{by:s=e.Flat.MIDDLE_NAME,limit:a=20,recursive:i=!1,withMore:r=!1,withPeriod:n=!0,surname:o}=t;if(this.length<=a)return this.full;const{firstName:h,lastName:l,middleName:u}=this.#y,m=n?".":"",c=this.hasMiddle,d=h.toString(),f=this.middleName().join(" "),N=l.toString(),p=h.initials(r).join(m+" ")+m,g=l.initials(o).join(m+" ")+m,E=c?u.map(e=>e.value[0]).join(m+" ")+m:"";let w=[];if(this.config.orderedBy===e.NameOrder.FIRST_NAME)switch(s){case e.Flat.FIRST_NAME:w=c?[p,f,N]:[p,N];break;case e.Flat.LAST_NAME:w=c?[d,f,g]:[d,g];break;case e.Flat.MIDDLE_NAME:w=c?[d,E,N]:[d,N];break;case e.Flat.FIRST_MID:w=c?[p,E,N]:[p,N];break;case e.Flat.MID_LAST:w=c?[d,E,g]:[d,g];break;case e.Flat.ALL:w=c?[p,E,g]:[p,g]}else switch(s){case e.Flat.FIRST_NAME:w=c?[N,p,f]:[N,p];break;case e.Flat.LAST_NAME:w=c?[g,d,f]:[g,d];break;case e.Flat.MIDDLE_NAME:w=c?[N,d,E]:[N,d];break;case e.Flat.FIRST_MID:w=c?[N,p,E]:[N,p];break;case e.Flat.MID_LAST:w=c?[g,d,E]:[g,d];break;case e.Flat.ALL:w=c?[g,p,E]:[g,p]}const y=w.join(" ");if(i&&y.length>a){const a=s===e.Flat.FIRST_NAME?e.Flat.MIDDLE_NAME:s===e.Flat.MIDDLE_NAME?e.Flat.LAST_NAME:s===e.Flat.LAST_NAME?e.Flat.FIRST_MID:s===e.Flat.FIRST_MID?e.Flat.MID_LAST:s===e.Flat.MID_LAST||s===e.Flat.ALL?e.Flat.ALL:s;return a===s?y:this.flatten({...t,by:a})}return y}zip(t=e.Flat.MID_LAST,s=!0){return this.flatten({limit:0,by:t,withPeriod:s})}format(e){if("short"===e)return this.short;if("long"===e)return this.long;if("public"===e)return this.public;"official"===e&&(e="o");let s="";const a=[];for(const i of e){if(-1===t.indexOf(i))throw new w({source:this.full,operation:"format",message:`unsupported character <${i}> from ${e}.`});s+=i,"$"!==i&&(a.push(this.#M(s)??""),s="")}return a.join("").trim()}flip(){const t=this.config.orderedBy===e.NameOrder.FIRST_NAME?e.NameOrder.LAST_NAME:e.NameOrder.FIRST_NAME;this.config.update({orderedBy:t})}split(e=/[' -]/g){return this.birth.replace(e," ").split(" ")}join(e=""){return this.split().join(e)}toUpperCase(){return this.birth.toUpperCase()}toLowerCase(){return this.birth.toLowerCase()}toCamelCase(){return f(this.toPascalCase())}toPascalCase(){return this.split().map(e=>d(e)).join("")}toSnakeCase(){return this.split().map(e=>e.toLowerCase()).join("_")}toHyphenCase(){return this.split().map(e=>e.toLowerCase()).join("-")}toDotCase(){return this.split().map(e=>e.toLowerCase()).join(".")}toToggleCase(){return this.birth.split("").map(e=>e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()).join("")}#A(e){if(e instanceof k)return e;if("string"==typeof e)return new B(e);if(N(e))return new q(e);if(S(e))return new X(e);if("object"==typeof e)return new H(e);throw new g({source:e,message:"Cannot parse raw data; review expected data types."})}#M(e){switch(e){case".":case",":case" ":case"-":case"_":return e;case"b":return this.birth;case"B":return this.birth.toUpperCase();case"f":return this.first;case"F":return this.first.toUpperCase();case"l":return this.last;case"L":return this.last.toUpperCase();case"m":case"M":return"m"===e?this.middleName().join(" "):this.middleName().join(" ").toUpperCase();case"o":case"O":return(e=>{const t=this.config.ending?",":"",s=[];this.prefix&&s.push(this.prefix),s.push(`${this.last},`.toUpperCase()),this.hasMiddle?s.push(this.first,this.middleName().join(" ")+t):s.push(this.first+t),this.suffix&&s.push(this.suffix);const a=s.join(" ").trim();return"o"===e?a:a.toUpperCase()})(e);case"p":return this.prefix;case"P":return this.prefix?.toUpperCase();case"s":return this.suffix;case"S":return this.suffix?.toUpperCase();case"$f":case"$F":return this.#y.firstName.value[0];case"$l":case"$L":return this.#y.lastName.value[0];case"$m":case"$M":return this.hasMiddle?this.middle[0]:void 0;default:return}}}class K{prebuild;postbuild;preclear;postclear;queue=[];instance=null;constructor(e,t,s,a){this.prebuild=e,this.postbuild=t,this.preclear=s,this.postclear=a}get size(){return this.queue.length}removeFirst(){return this.queue.length>0?this.queue.shift():void 0}removeLast(){return this.queue.length>0?this.queue.pop():void 0}addFirst(e){this.queue.unshift(e)}addLast(e){this.queue.push(e)}add(...e){this.queue.push(...e)}remove(e){const t=this.queue.indexOf(e);return-1!==t&&(this.queue.splice(t,1),!0)}removeWhere(e){this.queue=this.queue.filter(t=>!e(t))}retainWhere(e){this.queue=this.queue.filter(e)}clear(){null!==this.instance&&this.preclear?.(this.instance),this.queue=[],this.postclear?.(),this.instance=null}}class Y extends K{constructor(e,t,s,a,i){super(t,s,a,i),this.add(...e)}static create(e){return new Y(e?[e]:[])}static of(...e){return new Y(e)}static use({names:e,prebuild:t,postbuild:s,preclear:a,postclear:i}){return new Y(e??[],t,s,a,i)}build(e){this.prebuild?.();const t=[...this.queue];return P.create().validate(t),this.instance=new W(t,e),this.postbuild?.(this.instance),this.instance}}e.Config=I,e.FirstName=M,e.FullName=j,e.InputError=g,e.LastName=v,e.Name=A,e.NameBuilder=Y,e.NameError=p,e.NameIndex=c,e.Namefully=W,e.Namon=u,e.NotAllowedError=w,e.Parser=k,e.Separator=m,e.UnknownError=y,e.ValidationError=E,e.default=(e,t)=>new W(e,t),e.isNameArray=S,e.version="2.0.1",Object.defineProperty(e,"__esModule",{value:!0})});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).namefully={})}(this,function(e){"use strict";const t=[".",","," ","-","_","b","B","f","F","l","L","m","M","n","N","o","O","p","P","s","S","$"];var s,a,i,r,n,o,h,l;e.Title=void 0,(s=e.Title||(e.Title={})).US="US",s.UK="UK",e.Surname=void 0,(a=e.Surname||(e.Surname={})).FATHER="father",a.MOTHER="mother",a.HYPHENATED="hyphenated",a.ALL="all",e.NameOrder=void 0,(i=e.NameOrder||(e.NameOrder={})).FIRST_NAME="firstName",i.LAST_NAME="lastName",e.NameType=void 0,(r=e.NameType||(e.NameType={})).FIRST_NAME="firstName",r.MIDDLE_NAME="middleName",r.LAST_NAME="lastName",r.BIRTH_NAME="birthName",e.Flat=void 0,(n=e.Flat||(e.Flat={})).FIRST_NAME="firstName",n.MIDDLE_NAME="middleName",n.LAST_NAME="lastName",n.FIRST_MID="firstMid",n.MID_LAST="midLast",n.ALL="all",e.CapsRange=void 0,(o=e.CapsRange||(e.CapsRange={}))[o.NONE=0]="NONE",o[o.INITIAL=1]="INITIAL",o[o.ALL=2]="ALL";class u{index;key;static PREFIX=new u(0,"prefix");static FIRST_NAME=new u(1,"firstName");static MIDDLE_NAME=new u(2,"middleName");static LAST_NAME=new u(3,"lastName");static SUFFIX=new u(4,"suffix");static values=[u.PREFIX,u.FIRST_NAME,u.MIDDLE_NAME,u.LAST_NAME,u.SUFFIX];static all=new Map([[u.PREFIX.key,u.PREFIX],[u.FIRST_NAME.key,u.FIRST_NAME],[u.MIDDLE_NAME.key,u.MIDDLE_NAME],[u.LAST_NAME.key,u.LAST_NAME],[u.SUFFIX.key,u.SUFFIX]]);constructor(e,t){this.index=e,this.key=t}static has(e){return u.all.has(e)}static cast(e){return u.has(e)?u.all.get(e):void 0}toString(){return`Namon.${this.key}`}equal(e){return e instanceof u&&e.index===this.index&&e.key===this.key}}class m{name;token;static COMMA=new m("comma",",");static COLON=new m("colon",":");static DOUBLE_QUOTE=new m("doubleQuote",'"');static EMPTY=new m("empty","");static HYPHEN=new m("hyphen","-");static PERIOD=new m("period",".");static SEMI_COLON=new m("semiColon",";");static SINGLE_QUOTE=new m("singleQuote","'");static SPACE=new m("space"," ");static UNDERSCORE=new m("underscore","_");static all=new Map([[m.COMMA.name,m.COMMA],[m.COLON.name,m.COLON],[m.DOUBLE_QUOTE.name,m.DOUBLE_QUOTE],[m.EMPTY.name,m.EMPTY],[m.HYPHEN.name,m.HYPHEN],[m.PERIOD.name,m.PERIOD],[m.SEMI_COLON.name,m.SEMI_COLON],[m.SINGLE_QUOTE.name,m.SINGLE_QUOTE],[m.SPACE.name,m.SPACE],[m.UNDERSCORE.name,m.UNDERSCORE]]);static tokens=[...m.all.values()].map(e=>e.token);constructor(e,t){this.name=e,this.token=t}toString(){return`Separator.${this.name}`}}class c{prefix;firstName;middleName;lastName;suffix;static get min(){return 2}static get max(){return 5}constructor(e,t,s,a,i){this.prefix=e,this.firstName=t,this.middleName=s,this.lastName=a,this.suffix=i}static base(){return new c(-1,0,-1,1,-1)}static when(t,s=2){if(t===e.NameOrder.FIRST_NAME)switch(s){case 2:return new c(-1,0,-1,1,-1);case 3:return new c(-1,0,1,2,-1);case 4:return new c(0,1,2,3,-1);case 5:return new c(0,1,2,3,4);default:return c.base()}else switch(s){case 2:return new c(-1,1,-1,0,-1);case 3:return new c(-1,1,2,0,-1);case 4:return new c(0,2,3,1,-1);case 5:return new c(0,2,3,1,4);default:return c.base()}}static only({prefix:e=-1,firstName:t,middleName:s=-1,lastName:a,suffix:i=-1}){return new c(e,t,s,a,i)}toJson(){return{prefix:this.prefix,firstName:this.firstName,middleName:this.middleName,lastName:this.lastName,suffix:this.suffix}}json=this.toJson}function d(t,s=e.CapsRange.INITIAL){if(!t||s===e.CapsRange.NONE)return t;const[a,i]=[t[0].toUpperCase(),t.slice(1).toLowerCase()];return s===e.CapsRange.INITIAL?a.concat(i):t.toUpperCase()}function f(t,s=e.CapsRange.INITIAL){if(!t||s===e.CapsRange.NONE)return t;const[a,i]=[t[0].toLowerCase(),t.slice(1)];return s===e.CapsRange.INITIAL?a.concat(i):t.toLowerCase()}function N(e){return Array.isArray(e)&&e.length>0&&e.every(e=>"string"==typeof e)}e.NameErrorType=void 0,(h=e.NameErrorType||(e.NameErrorType={}))[h.INPUT=0]="INPUT",h[h.VALIDATION=1]="VALIDATION",h[h.NOT_ALLOWED=2]="NOT_ALLOWED",h[h.UNKNOWN=3]="UNKNOWN";class p extends Error{source;type;constructor(t,s,a=e.NameErrorType.UNKNOWN){super(s),this.source=t,this.type=a,this.name="NameError"}get sourceAsString(){return"string"==typeof this.source?this.source:N(this.source)?this.source.join(" "):"<undefined>"}get hasMessage(){return this.message.trim().length>0}toString(){let e=`${this.name} (${this.sourceAsString})`;return this.hasMessage&&(e=`${e}: ${this.message}`),e}}class g extends p{constructor(t){super(t.source,t.message,e.NameErrorType.INPUT),this.name="InputError"}}class E extends p{nameType;constructor(t){super(t.source,t.message,e.NameErrorType.VALIDATION),this.nameType=t.nameType,this.name="ValidationError"}toString(){let e=`${this.name} (${this.nameType}='${this.sourceAsString}')`;return this.hasMessage&&(e=`${e}: ${this.message}`),e}}class y extends p{operation;constructor(t){super(t.source,t.message,e.NameErrorType.NOT_ALLOWED),this.operation=t.operation,this.name="NotAllowedError"}toString(){let e=`${this.name} (${this.sourceAsString})`;return this.operation&&this.operation.trim().length>0&&(e=`${e} - ${this.operation}`),this.hasMessage&&(e=`${e}: ${this.message}`),e}}class w extends p{origin;constructor(t){super(t.source,t.message,e.NameErrorType.UNKNOWN),this.origin=t.origin,this.name="UnknownError"}toString(){let e=super.toString();return this.origin&&(e+=`\n${this.origin.toString()}`),e}}class A{type;#e;initial;capsRange;constructor(t,s,a){this.type=s,this.capsRange=a??e.CapsRange.INITIAL,this.value=t,a&&this.caps(a)}set value(e){this.validate(e),this.#e=e,this.initial=e[0]}get value(){return this.#e}get length(){return this.#e.length}get isPrefix(){return this.type===u.PREFIX}get isFirstName(){return this.type===u.FIRST_NAME}get isMiddleName(){return this.type===u.MIDDLE_NAME}get isLastName(){return this.type===u.LAST_NAME}get isSuffix(){return this.type===u.SUFFIX}static prefix(e){return new A(e,u.PREFIX)}static first(e){return new A(e,u.FIRST_NAME)}static middle(e){return new A(e,u.MIDDLE_NAME)}static last(e){return new A(e,u.LAST_NAME)}static suffix(e){return new A(e,u.SUFFIX)}initials(){return[this.initial]}toString(){return this.#e}equal(e){return e instanceof A&&e.value===this.value&&e.type===this.type}caps(e){return this.value=d(this.#e,e??this.capsRange),this}decaps(e){return this.value=f(this.#e,e??this.capsRange),this}validate(e){if("string"==typeof e&&e.trim().length<1)throw new g({source:e,message:"must be 1+ characters"})}}class M extends A{#t;constructor(e,...t){super(e,u.FIRST_NAME),t.forEach(this.validate),this.#t=t}get hasMore(){return this.#t.length>0}get length(){return super.length+(this.hasMore?this.#t.reduce((e,t)=>e+t).length:0)}get asNames(){const e=[A.first(this.value)];return this.hasMore&&e.push(...this.#t.map(A.first)),e}get more(){return this.#t}toString(e=!1){return e&&this.hasMore?`${this.value} ${this.#t.join(" ")}`.trim():this.value}initials(e=!1){const t=[this.initial];return e&&this.hasMore&&t.push(...this.#t.map(e=>e[0])),t}caps(e){return e=e||this.capsRange,this.value=d(this.value,e),this.hasMore&&(this.#t=this.#t.map(t=>d(t,e))),this}decaps(e){return e=e||this.capsRange,this.value=f(this.value,e),this.hasMore&&(this.#t=this.#t.map(t=>f(t,e))),this}copyWith(e){return new M(e?.first??this.value,...e?.more??this.#t)}}class v extends A{format;#s;constructor(t,s,a=e.Surname.FATHER){super(t,u.LAST_NAME),this.format=a,this.validate(s),this.#s=s}get father(){return this.value}get mother(){return this.#s}get hasMother(){return!!this.#s}get length(){return super.length+(this.#s?.length??0)}get asNames(){const e=[A.last(this.value)];return this.#s&&e.push(A.last(this.#s)),e}toString(t){switch(t=t??this.format){case e.Surname.FATHER:return this.value;case e.Surname.MOTHER:return this.mother??"";case e.Surname.HYPHENATED:return this.hasMother?`${this.value}-${this.#s}`:this.value;case e.Surname.ALL:return this.hasMother?`${this.value} ${this.#s}`:this.value}}initials(t){const s=[];switch(t??this.format){case e.Surname.HYPHENATED:case e.Surname.ALL:s.push(this.initial),this.#s&&s.push(this.#s[0]);break;case e.Surname.MOTHER:this.#s&&s.push(this.#s[0]);break;default:s.push(this.initial)}return s}caps(e){return e??=this.capsRange,this.value=d(this.value,e),this.hasMother&&(this.#s=d(this.#s,e)),this}decaps(e){return e??=this.capsRange,this.value=f(this.value,e),this.hasMother&&(this.#s=f(this.#s,e)),this}copyWith(e){return new v(e?.father??this.value,e?.mother??this.mother,e?.format??this.format)}}function S(e){return Array.isArray(e)&&e.length>0&&e.every(e=>e instanceof A)}const T="_copy";class I{#a;#i;#r;#n;#o;#h;#l;static cache=new Map;get orderedBy(){return this.#i}get separator(){return this.#r}get title(){return this.#n}get ending(){return this.#o}get bypass(){return this.#h}get surname(){return this.#l}get name(){return this.#a}constructor(t,s=e.NameOrder.FIRST_NAME,a=m.SPACE,i=e.Title.UK,r=!1,n=!0,o=e.Surname.FATHER){this.#a=t,this.#i=s,this.#r=a,this.#n=i,this.#o=r,this.#h=n,this.#l=o}static create(e="default"){return l.cache.has(e)||l.cache.set(e,new l(e)),l.cache.get(e)}static merge(e){if(e){const t=l.create(e.name);return t.#i=e.orderedBy??t.orderedBy,t.#r=e.separator??t.separator,t.#n=e.title??t.title,t.#o=e.ending??t.ending,t.#h=e.bypass??t.bypass,t.#l=e.surname??t.surname,t}return l.create()}copyWith(e={}){const{name:t,orderedBy:s,separator:a,title:i,ending:r,bypass:n,surname:o}=e,h=l.create(this.#u(t??this.name+T));return h.#i=s??this.orderedBy,h.#r=a??this.separator,h.#n=i??this.title,h.#o=r??this.ending,h.#h=n??this.bypass,h.#l=o??this.surname,h}clone(){return this.copyWith()}reset(){this.#i=e.NameOrder.FIRST_NAME,this.#r=m.SPACE,this.#n=e.Title.UK,this.#o=!1,this.#h=!0,this.#l=e.Surname.FATHER,l.cache.set(this.name,this)}updateOrder(e){this.update({orderedBy:e})}update({orderedBy:e,title:t,ending:s}){const a=l.cache.get(this.name);a&&(e!==this.#i&&(a.#i=e),t!==this.#n&&(a.#n=t),s!==this.#o&&(a.#o=s))}#u(e){return e===this.name||l.cache.has(e)?this.#u(e+T):e}}l=I;class x{static base=/[a-zA-Z\u00C0-\u00D6\u00D8-\u00f6\u00f8-\u00ff\u0400-\u04FFΆ-ωΑ-ώ]/;static namon=new RegExp(`^${x.base.source}+(([' -]${x.base.source})?${x.base.source}*)*$`);static firstName=x.namon;static middleName=new RegExp(`^${x.base.source}+(([' -]${x.base.source})?${x.base.source}*)*$`);static lastName=x.namon}const L=e=>S(e)?e.map(e=>e.toString()).join(" "):"";class F{validate(e){if(0===e.length||e.length<2||e.length>5)throw new g({source:e.map(e=>e.toString()),message:"expecting a list of 2-5 elements"})}}class _{static#m;static create(){return this.#m||(this.#m=new _)}validate(e,t){if(e instanceof A)D.create().validate(e,t);else{if("string"!=typeof e)throw new g({source:typeof e,message:"expecting types of string or Name"});if(!x.namon.test(e))throw new E({source:e,nameType:"namon",message:"invalid name content failing namon regex"})}}}class b{static#m;static create(){return this.#m||(this.#m=new b)}validate(e){if(e instanceof M)e.asNames.forEach(e=>this.validate(e.value));else{if("string"!=typeof e)throw new g({source:typeof e,message:"expecting types string or FirstName"});if(!x.firstName.test(e))throw new E({source:e,nameType:"firstName",message:"invalid name content failing firstName regex"})}}}class R{static#m;static create(){return this.#m||(this.#m=new R)}validate(e){if("string"==typeof e){if(!x.middleName.test(e))throw new E({source:e,nameType:"middleName",message:"invalid name content failing middleName regex"})}else{if(!Array.isArray(e))throw new g({source:typeof e,message:"expecting types of string, string[] or Name[]"});try{const t=_.create();for(const s of e)t.validate(s,u.MIDDLE_NAME)}catch(t){throw new E({source:L(e),nameType:"middleName",message:t?.message})}}}}class O{static#m;static create(){return this.#m||(this.#m=new O)}validate(e){if(e instanceof v)e.asNames.forEach(e=>this.validate(e.value));else{if("string"!=typeof e)throw new g({source:typeof e,message:"expecting types string or LastName"});if(!x.lastName.test(e))throw new E({source:e,nameType:"lastName",message:"invalid name content failing lastName regex"})}}}class D{static#m;static create(){return this.#m||(this.#m=new D)}validate(e,t){if(t&&e.type!==t)throw new E({source:e.toString(),nameType:e.type.toString(),message:"wrong name type; only Namon types are supported"});if(!x.namon.test(e.value))throw new E({source:e.toString(),nameType:e.type.toString(),message:"invalid name content failing namon regex"})}}class C{static#m;static create(){return this.#m||(this.#m=new C)}validate(e){this.validateKeys(e),$.firstName.validate(e.get(u.FIRST_NAME)),$.lastName.validate(e.get(u.LAST_NAME)),e.has(u.PREFIX)&&$.namon.validate(e.get(u.PREFIX)),e.has(u.SUFFIX)&&$.namon.validate(e.get(u.SUFFIX))}validateKeys(e){if(!e.size)throw new g({source:void 0,message:"Map<k,v> must not be empty"});if(e.size<2||e.size>5)throw new g({source:[...e.values()],message:"expecting 2-5 fields"});if(!e.has(u.FIRST_NAME))throw new g({source:[...e.values()],message:'"firstName" is a required key'});if(!e.has(u.LAST_NAME))throw new g({source:[...e.values()],message:'"lastName" is a required key'})}}class U extends F{index;constructor(e=c.base()){super(),this.index=e}validate(e){this.validateIndex(e),$.firstName.validate(e[this.index.firstName]),$.lastName.validate(e[this.index.lastName]),e.length>=3&&$.middleName.validate(e[this.index.middleName]),e.length>=4&&$.namon.validate(e[this.index.prefix]),5===e.length&&$.namon.validate(e[this.index.suffix])}validateIndex(e){super.validate(e)}}class P{static#m;static create(){return this.#m||(this.#m=new P)}validate(e){if(e.length<2)throw new g({source:L(e),message:"expecting at least 2 elements"});if(!this.#c(e))throw new g({source:L(e),message:"both first and last names are required"})}#c(e){const t={};for(const s of e)(s.isFirstName||s.isLastName)&&(t[s.type.key]=s.toString());return 2===Object.keys(t).length}}class ${static namon=_.create();static nama=C.create();static prefix=_.create();static firstName=b.create();static middleName=R.create();static lastName=O.create();static suffix=_.create()}class j{#d;#f;#N=[];#p;#g;#E;constructor(e){this.#E=I.merge(e)}get config(){return this.#E}get prefix(){return this.#d}get firstName(){return this.#f}get lastName(){return this.#p}get middleName(){return this.#N}get suffix(){return this.#g}static parse(e,t){try{return new j(t).setPrefix(e.prefix).setFirstName(e.firstName).setMiddleName(e.middleName??[]).setLastName(e.lastName).setSuffix(e.suffix)}catch(t){if(t instanceof p)throw t;throw new w({source:Object.values(e).join(" "),message:"could not parse JSON content",origin:t instanceof Error?t:new Error(String(t))})}}setPrefix(t){if(!t)return this;this.#E.bypass||$.prefix.validate(t);const s=t instanceof A?t.value:t;return this.#d=A.prefix(this.#E.title===e.Title.US?`${s}.`:s),this}setFirstName(e){return this.#E.bypass||$.firstName.validate(e),this.#f=e instanceof M?e:new M(e),this}setLastName(e){return this.#E.bypass||$.lastName.validate(e),this.#p=e instanceof v?e:new v(e),this}setMiddleName(e){return Array.isArray(e)?(this.#E.bypass||$.middleName.validate(e),this.#N=e.map(e=>e instanceof A?e:A.middle(e)),this):this}setSuffix(e){return e?(this.#E.bypass||$.suffix.validate(e),this.#g=A.suffix(e instanceof A?e.value:e),this):this}has(e){return e.equal(u.PREFIX)?!!this.#d:e.equal(u.SUFFIX)?!!this.#g:!e.equal(u.MIDDLE_NAME)||this.#N.length>0}}class k{raw;constructor(e){this.raw=e}static build(e,t){const s=e.trim().split(m.SPACE.token),a=s.length;if(t instanceof c){const e=Object.entries(t.json()).filter(([,e])=>e>-1&&e<a).map(([e,t])=>new A(s[t],u.all.get(e)));return new X(e)}if(a<2)throw new g({source:e,message:"cannot build from invalid input"});if(2===a||3===a)return new B(e);{const e=s.pop(),[t,...a]=s;return new q([t,a.join(" "),e])}}static buildAsync(e,t){try{return Promise.resolve(k.build(e,t))}catch(e){return Promise.reject(e)}}}class B extends k{parse(e){const t=I.merge(e),s=this.raw.split(t.separator.token);return new q(s).parse(e)}}class q extends k{parse(e){const t=I.merge(e),s=new j(t),a=this.raw.map(e=>e.trim()),i=c.when(t.orderedBy,a.length),r=new U(i);t.bypass?r.validateIndex(a):r.validate(a);const{firstName:n,lastName:o,middleName:h,prefix:l,suffix:u}=i;return s.setFirstName(new M(a[n])),s.setLastName(new v(a[o])),a.length>=3&&s.setMiddleName(a[h].split(t.separator.token)),a.length>=4&&s.setPrefix(A.prefix(a[l])),5===a.length&&s.setSuffix(A.suffix(a[u])),s}}class H extends k{parse(e){const t=I.merge(e),s=new Map(Object.entries(this.raw).map(([e,t])=>{const s=u.cast(e);if(!s)throw new g({source:Object.values(this.raw).join(" "),message:`unsupported key "${e}"`});return[s,t]}));return t.bypass?C.create().validateKeys(s):C.create().validate(s),j.parse(this.raw,t)}}class X extends k{parse(e){const t=I.merge(e),s=new j(t);P.create().validate(this.raw);for(const e of this.raw)if(e.isPrefix)s.setPrefix(e);else if(e.isSuffix)s.setSuffix(e);else if(e.isFirstName)s.setFirstName(e instanceof M?e:new M(e.value));else if(e.isMiddleName)s.middleName.push(e);else if(e.isLastName){const a=new v(e.value,e instanceof v?e.mother:void 0,t.surname);s.setLastName(a)}return s}}class W{#y;constructor(e,t){this.#y=this.#w(e).parse(t)}static tryParse(e,t){try{return new W(k.build(e,t))}catch{return}}static async parse(e,t){return k.buildAsync(e,t).then(e=>new W(e))}get config(){return this.#y.config}get length(){return this.birth.length}get prefix(){return this.#y.prefix?.toString()}get first(){return this.firstName()}get middle(){return this.hasMiddle?this.middleName()[0]:void 0}get hasMiddle(){return this.#y.has(u.MIDDLE_NAME)}get last(){return this.lastName()}get suffix(){return this.#y.suffix?.toString()}get birth(){return this.birthName()}get short(){return this.shorten()}get long(){return this.birth}get full(){return this.fullName()}get public(){return this.format("f $l")}get salutation(){return this.format("p l")}toString(){return this.full}get(e){return e.equal(u.PREFIX)?this.#y.prefix:e.equal(u.FIRST_NAME)?this.#y.firstName:e.equal(u.MIDDLE_NAME)?this.#y.middleName:e.equal(u.LAST_NAME)?this.#y.lastName:e.equal(u.SUFFIX)?this.#y.suffix:void 0}equal(e){return this.toString()===e.toString()}toJson(){return{prefix:this.prefix,firstName:this.first,middleName:this.middleName(),lastName:this.last,suffix:this.suffix}}json=this.toJson;has(e){return this.#y.has(e)}fullName(t){const s=this.config.ending?",":"",a=[];return this.prefix&&a.push(this.prefix),(t??this.config.orderedBy)===e.NameOrder.FIRST_NAME?a.push(this.first,...this.middleName(),this.last+s):a.push(this.last,this.first,this.middleName().join(" ")+s),this.suffix&&a.push(this.suffix),a.join(" ").trim()}birthName(t){return t??=this.config.orderedBy,t===e.NameOrder.FIRST_NAME?[this.first,...this.middleName(),this.last].join(" "):[this.last,this.first,...this.middleName()].join(" ")}firstName(e=!0){return this.#y.firstName.toString(e)}middleName(){return this.#y.middleName.map(e=>e.value)}lastName(e){return this.#y.lastName.toString(e)}initials(t){const{orderedBy:s=this.config.orderedBy,only:a=e.NameType.BIRTH_NAME,asJson:i}=t??{},r=this.#y.firstName.initials(),n=this.#y.middleName.map(e=>e.value[0]),o=this.#y.lastName.initials();return i?{firstName:r,middleName:n,lastName:o}:a!==e.NameType.BIRTH_NAME?a===e.NameType.FIRST_NAME?r:a===e.NameType.MIDDLE_NAME?n:o:s===e.NameOrder.FIRST_NAME?[...r,...n,...o]:[...o,...r,...n]}shorten(t){t??=this.config.orderedBy;const{firstName:s,lastName:a}=this.#y;return t===e.NameOrder.FIRST_NAME?[s.value,a.toString()].join(" "):[a.toString(),s.value].join(" ")}flatten(t){const{by:s=e.Flat.MIDDLE_NAME,limit:a=20,recursive:i=!1,withMore:r=!1,withPeriod:n=!0,surname:o}=t;if(this.length<=a)return this.full;const{firstName:h,lastName:l,middleName:u}=this.#y,m=n?".":"",c=this.hasMiddle,d=h.toString(),f=this.middleName().join(" "),N=l.toString(),p=h.initials(r).join(m+" ")+m,g=l.initials(o).join(m+" ")+m,E=c?u.map(e=>e.value[0]).join(m+" ")+m:"";let y=[];if(this.config.orderedBy===e.NameOrder.FIRST_NAME)switch(s){case e.Flat.FIRST_NAME:y=c?[p,f,N]:[p,N];break;case e.Flat.LAST_NAME:y=c?[d,f,g]:[d,g];break;case e.Flat.MIDDLE_NAME:y=c?[d,E,N]:[d,N];break;case e.Flat.FIRST_MID:y=c?[p,E,N]:[p,N];break;case e.Flat.MID_LAST:y=c?[d,E,g]:[d,g];break;case e.Flat.ALL:y=c?[p,E,g]:[p,g]}else switch(s){case e.Flat.FIRST_NAME:y=c?[N,p,f]:[N,p];break;case e.Flat.LAST_NAME:y=c?[g,d,f]:[g,d];break;case e.Flat.MIDDLE_NAME:y=c?[N,d,E]:[N,d];break;case e.Flat.FIRST_MID:y=c?[N,p,E]:[N,p];break;case e.Flat.MID_LAST:y=c?[g,d,E]:[g,d];break;case e.Flat.ALL:y=c?[g,p,E]:[g,p]}const w=y.join(" ");if(i&&w.length>a){const a=s===e.Flat.FIRST_NAME?e.Flat.MIDDLE_NAME:s===e.Flat.MIDDLE_NAME?e.Flat.LAST_NAME:s===e.Flat.LAST_NAME?e.Flat.FIRST_MID:s===e.Flat.FIRST_MID?e.Flat.MID_LAST:s===e.Flat.MID_LAST||s===e.Flat.ALL?e.Flat.ALL:s;return a===s?w:this.flatten({...t,by:a})}return w}zip(t=e.Flat.MID_LAST,s=!0){return this.flatten({limit:0,by:t,withPeriod:s})}format(e){if("short"===e)return this.short;if("long"===e)return this.long;if("public"===e)return this.public;"official"===e&&(e="o");let s="";const a=[];for(const i of e){if(-1===t.indexOf(i))throw new y({source:this.full,operation:"format",message:`unsupported character <${i}> from ${e}.`});s+=i,"$"!==i&&(a.push(this.#A(s)??""),s="")}return a.join("").trim()}flip(){const t=this.config.orderedBy===e.NameOrder.FIRST_NAME?e.NameOrder.LAST_NAME:e.NameOrder.FIRST_NAME;this.config.update({orderedBy:t})}split(e=/[' -]/g){return this.birth.replace(e," ").split(" ")}join(e=""){return this.split().join(e)}toUpperCase(){return this.birth.toUpperCase()}toLowerCase(){return this.birth.toLowerCase()}toCamelCase(){return f(this.toPascalCase())}toPascalCase(){return this.split().map(e=>d(e)).join("")}toSnakeCase(){return this.split().map(e=>e.toLowerCase()).join("_")}toHyphenCase(){return this.split().map(e=>e.toLowerCase()).join("-")}toDotCase(){return this.split().map(e=>e.toLowerCase()).join(".")}toToggleCase(){return this.birth.split("").map(e=>e===e.toUpperCase()?e.toLowerCase():e.toUpperCase()).join("")}#w(e){if(e instanceof k)return e;if("string"==typeof e)return new B(e);if(N(e))return new q(e);if(S(e))return new X(e);if("object"==typeof e)return new H(e);throw new g({source:e,message:"Cannot parse raw data; review expected data types."})}#A(e){switch(e){case".":case",":case" ":case"-":case"_":return e;case"b":return this.birth;case"B":return this.birth.toUpperCase();case"f":return this.first;case"F":return this.first.toUpperCase();case"l":return this.last;case"L":return this.last.toUpperCase();case"m":case"M":return"m"===e?this.middleName().join(" "):this.middleName().join(" ").toUpperCase();case"o":case"O":return(e=>{const t=this.config.ending?",":"",s=[];this.prefix&&s.push(this.prefix),s.push(`${this.last},`.toUpperCase()),this.hasMiddle?s.push(this.first,this.middleName().join(" ")+t):s.push(this.first+t),this.suffix&&s.push(this.suffix);const a=s.join(" ").trim();return"o"===e?a:a.toUpperCase()})(e);case"p":return this.prefix;case"P":return this.prefix?.toUpperCase();case"s":return this.suffix;case"S":return this.suffix?.toUpperCase();case"$f":case"$F":return this.#y.firstName.value[0];case"$l":case"$L":return this.#y.lastName.value[0];case"$m":case"$M":return this.hasMiddle?this.middle[0]:void 0;default:return}}}class K{prebuild;postbuild;preclear;postclear;queue=[];instance=null;constructor(e,t,s,a){this.prebuild=e,this.postbuild=t,this.preclear=s,this.postclear=a}get size(){return this.queue.length}removeFirst(){return this.queue.length>0?this.queue.shift():void 0}removeLast(){return this.queue.length>0?this.queue.pop():void 0}addFirst(e){this.queue.unshift(e)}addLast(e){this.queue.push(e)}add(...e){this.queue.push(...e)}remove(e){const t=this.queue.indexOf(e);return-1!==t&&(this.queue.splice(t,1),!0)}removeWhere(e){this.queue=this.queue.filter(t=>!e(t))}retainWhere(e){this.queue=this.queue.filter(e)}clear(){null!==this.instance&&this.preclear?.(this.instance),this.queue=[],this.postclear?.(),this.instance=null}}class Y extends K{constructor(e,t,s,a,i){super(t,s,a,i),this.add(...e)}static create(e){return new Y(e?[e]:[])}static of(...e){return new Y(e)}static use({names:e,prebuild:t,postbuild:s,preclear:a,postclear:i}){return new Y(e??[],t,s,a,i)}build(e){this.prebuild?.();const t=[...this.queue];return P.create().validate(t),this.instance=new W(t,e),this.postbuild?.(this.instance),this.instance}}e.Config=I,e.FirstName=M,e.FullName=j,e.InputError=g,e.LastName=v,e.Name=A,e.NameBuilder=Y,e.NameError=p,e.NameIndex=c,e.Namefully=W,e.Namon=u,e.NotAllowedError=y,e.Parser=k,e.Separator=m,e.UnknownError=w,e.ValidationError=E,e.default=(e,t)=>new W(e,t),e.isNameArray=S,e.version="2.0.2",Object.defineProperty(e,"__esModule",{value:!0})});
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
[![npm version][version-img]][version-url]
|
|
4
4
|
[![JSR Version][jsr-version]][jsr-url]
|
|
5
5
|
[![CI build][ci-img]][ci-url]
|
|
6
|
-
[![Coverage Status][codecov-img]][codecov-url]
|
|
7
6
|
[![MIT License][license-img]][license-url]
|
|
8
7
|
|
|
9
8
|
Human name handling made easy.
|
|
@@ -276,7 +275,8 @@ other words, the most basic/typical case is a name that looks like this:
|
|
|
276
275
|
> is as shown above and will be used as a basis for future examples and use cases.
|
|
277
276
|
|
|
278
277
|
Once imported, all that is required to do is to create an instance of
|
|
279
|
-
`Namefully` and the rest will follow.
|
|
278
|
+
`Namefully` and the rest will follow. Keep in mind that all name parts must have
|
|
279
|
+
at least one (1) character to proceed.
|
|
280
280
|
|
|
281
281
|
### Basic cases
|
|
282
282
|
|
|
@@ -324,8 +324,6 @@ The underlying content of this utility is licensed under [MIT License][license-u
|
|
|
324
324
|
[jsr-url]: https://jsr.io/@ralflorent/namefully
|
|
325
325
|
[ci-img]: https://github.com/ralflorent/namefully/workflows/build/badge.svg
|
|
326
326
|
[ci-url]: https://github.com/ralflorent/namefully/actions/workflows/ci.yml
|
|
327
|
-
[codecov-img]: https://codecov.io/gh/ralflorent/namefully/branch/main/graph/badge.svg
|
|
328
|
-
[codecov-url]: https://codecov.io/gh/ralflorent/namefully
|
|
329
327
|
[license-img]: https://img.shields.io/npm/l/namefully
|
|
330
328
|
[license-url]: https://opensource.org/licenses/MIT
|
|
331
329
|
|