@bccampus/utils 0.1.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/README.md +8 -0
- package/dist/array/chunk.d.ts +1 -0
- package/dist/array/chunk.js +9 -0
- package/dist/array/index.d.ts +1 -0
- package/dist/array/index.js +4 -0
- package/dist/date/index.d.ts +1 -0
- package/dist/date/index.js +8 -0
- package/dist/date/iso-date-time.d.ts +127 -0
- package/dist/date/iso-date-time.js +256 -0
- package/dist/duration/add-durations.d.ts +1 -0
- package/dist/duration/add-durations.js +12 -0
- package/dist/duration/index.d.ts +3 -0
- package/dist/duration/index.js +8 -0
- package/dist/duration/is-duration.d.ts +1 -0
- package/dist/duration/is-duration.js +7 -0
- package/dist/duration/to-number.d.ts +1 -0
- package/dist/duration/to-number.js +14 -0
- package/dist/format/formatter.d.ts +5 -0
- package/dist/format/formatter.js +40 -0
- package/dist/format/index.d.ts +3 -0
- package/dist/format/index.js +13 -0
- package/dist/format/stringify.d.ts +38 -0
- package/dist/format/stringify.js +42 -0
- package/dist/format/template.d.ts +6 -0
- package/dist/format/template.js +35 -0
- package/dist/object/get.d.ts +1 -0
- package/dist/object/get.js +7 -0
- package/dist/object/index.d.ts +5 -0
- package/dist/object/index.js +12 -0
- package/dist/object/is-object.d.ts +1 -0
- package/dist/object/is-object.js +4 -0
- package/dist/object/omit.d.ts +1 -0
- package/dist/object/omit.js +18 -0
- package/dist/object/pick.d.ts +1 -0
- package/dist/object/pick.js +11 -0
- package/dist/object/set.d.ts +1 -0
- package/dist/object/set.js +14 -0
- package/dist/set/difference.d.ts +1 -0
- package/dist/set/difference.js +10 -0
- package/dist/set/index.d.ts +5 -0
- package/dist/set/index.js +12 -0
- package/dist/set/intersection.d.ts +1 -0
- package/dist/set/intersection.js +13 -0
- package/dist/set/is-superset.d.ts +1 -0
- package/dist/set/is-superset.js +12 -0
- package/dist/set/symmetric-difference.d.ts +1 -0
- package/dist/set/symmetric-difference.js +14 -0
- package/dist/set/union.d.ts +1 -0
- package/dist/set/union.js +10 -0
- package/dist/string/capitalize.d.ts +1 -0
- package/dist/string/capitalize.js +4 -0
- package/dist/string/index.d.ts +6 -0
- package/dist/string/index.js +14 -0
- package/dist/string/pluralize/index.d.ts +2 -0
- package/dist/string/pluralize/index.js +4 -0
- package/dist/string/pluralize/pluralize.d.ts +85 -0
- package/dist/string/pluralize/pluralize.js +210 -0
- package/dist/string/pluralize/rules/index.d.ts +4 -0
- package/dist/string/pluralize/rules/index.js +10 -0
- package/dist/string/pluralize/rules/irregular.d.ts +1 -0
- package/dist/string/pluralize/rules/irregular.js +62 -0
- package/dist/string/pluralize/rules/pluralization.d.ts +2 -0
- package/dist/string/pluralize/rules/pluralization.js +39 -0
- package/dist/string/pluralize/rules/singularization.d.ts +2 -0
- package/dist/string/pluralize/rules/singularization.js +47 -0
- package/dist/string/pluralize/rules/uncountable.d.ts +2 -0
- package/dist/string/pluralize/rules/uncountable.js +113 -0
- package/dist/string/pluralize/types.d.ts +3 -0
- package/dist/string/pluralize/types.js +1 -0
- package/dist/string/slugify/index.d.ts +1 -0
- package/dist/string/slugify/index.js +2263 -0
- package/dist/string/strip-html-tags.d.ts +1 -0
- package/dist/string/strip-html-tags.js +7 -0
- package/dist/string/to-int.d.ts +9 -0
- package/dist/string/to-int.js +10 -0
- package/dist/string/to-sentence-case.d.ts +1 -0
- package/dist/string/to-sentence-case.js +8 -0
- package/dist/string/trim.d.ts +1 -0
- package/dist/string/trim.js +11 -0
- package/dist/string/truncate.d.ts +1 -0
- package/dist/string/truncate.js +9 -0
- package/eslint.config.js +19 -0
- package/package.json +68 -0
- package/src/array/chunk.ts +6 -0
- package/src/array/index.ts +1 -0
- package/src/date/index.ts +1 -0
- package/src/date/iso-date-time.ts +356 -0
- package/src/duration/add-durations.ts +16 -0
- package/src/duration/index.ts +3 -0
- package/src/duration/is-duration.ts +5 -0
- package/src/duration/to-number.ts +18 -0
- package/src/format/formatter.ts +37 -0
- package/src/format/index.ts +3 -0
- package/src/format/stringify.ts +87 -0
- package/src/format/template.ts +48 -0
- package/src/object/get.ts +9 -0
- package/src/object/index.ts +5 -0
- package/src/object/is-object.ts +2 -0
- package/src/object/omit.ts +21 -0
- package/src/object/pick.ts +10 -0
- package/src/object/set.ts +15 -0
- package/src/set/difference.ts +9 -0
- package/src/set/index.ts +5 -0
- package/src/set/intersection.ts +12 -0
- package/src/set/is-superset.ts +12 -0
- package/src/set/symmetric-difference.ts +12 -0
- package/src/set/union.ts +8 -0
- package/src/string/capitalize.ts +2 -0
- package/src/string/index.ts +6 -0
- package/src/string/pluralize/index.ts +2 -0
- package/src/string/pluralize/pluralize.ts +296 -0
- package/src/string/pluralize/rules/index.ts +4 -0
- package/src/string/pluralize/rules/irregular.ts +59 -0
- package/src/string/pluralize/rules/pluralization.ts +40 -0
- package/src/string/pluralize/rules/singularization.ts +46 -0
- package/src/string/pluralize/rules/uncountable.ts +107 -0
- package/src/string/pluralize/types.ts +4 -0
- package/src/string/slugify/index.ts +3 -0
- package/src/string/strip-html-tags.ts +4 -0
- package/src/string/to-int.ts +20 -0
- package/src/string/to-sentence-case.ts +6 -0
- package/src/string/trim.ts +11 -0
- package/src/string/truncate.ts +11 -0
- package/tsconfig.json +18 -0
- package/tsconfig.lib.json +36 -0
- package/tsconfig.lib.tsbuildinfo +1 -0
- package/tsconfig.node.json +25 -0
- package/vite.config.ts +77 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import "./formatter.js";
|
|
2
|
+
import { stringify } from "./stringify.js";
|
|
3
|
+
import { get } from "../object/get.js";
|
|
4
|
+
const tagRegExp = new RegExp(/\${([a-zA-Z0-9_.]+)}/gm);
|
|
5
|
+
const template = (text, templateVars) => {
|
|
6
|
+
return text.replace(tagRegExp, (match, key) => {
|
|
7
|
+
const templateVar = get(templateVars, key);
|
|
8
|
+
const value = typeof templateVar === "function" ? templateVar() : templateVar;
|
|
9
|
+
if (value === void 0) return match;
|
|
10
|
+
if (value === null) return "";
|
|
11
|
+
return stringify(value, { invalidValueString: "" });
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
const templateObject = (obj, templateVars) => {
|
|
15
|
+
const _objClone = {};
|
|
16
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
17
|
+
const _key = template(key, templateVars);
|
|
18
|
+
if (typeof value === "string") {
|
|
19
|
+
_objClone[_key] = template(value, templateVars);
|
|
20
|
+
} else if (value && typeof value === "object") {
|
|
21
|
+
if (Array.isArray(value))
|
|
22
|
+
_objClone[_key] = value.map(
|
|
23
|
+
(valueItem) => typeof valueItem === "string" ? template(valueItem, templateVars) : valueItem
|
|
24
|
+
);
|
|
25
|
+
else _objClone[_key] = templateObject(value, templateVars);
|
|
26
|
+
} else {
|
|
27
|
+
_objClone[_key] = value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return _objClone;
|
|
31
|
+
};
|
|
32
|
+
export {
|
|
33
|
+
template,
|
|
34
|
+
templateObject
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const get: <T extends object>(object: T, prop: string) => any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isObject: (object: unknown) => boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const omit: <T extends object>(object: T, props: string[]) => Partial<T>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const omit = (object, props) => {
|
|
2
|
+
const result = { ...object };
|
|
3
|
+
props.forEach((prop) => {
|
|
4
|
+
const propChunks = prop.split(".");
|
|
5
|
+
const lastChunk = propChunks.pop();
|
|
6
|
+
if (lastChunk) {
|
|
7
|
+
const ref = propChunks.reduce(
|
|
8
|
+
(reducedObject, key) => reducedObject && key in reducedObject ? reducedObject[key] : void 0,
|
|
9
|
+
result
|
|
10
|
+
);
|
|
11
|
+
if (ref && lastChunk in ref) delete ref[lastChunk];
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
return result;
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
omit
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pick: <T extends object>(object: T, props: string[]) => Partial<T>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const set: <T extends object, V>(object: T, prop: string, value: V) => T;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const set = (object, prop, value) => {
|
|
2
|
+
const propChunks = prop.split(".");
|
|
3
|
+
const lastChunk = propChunks.pop();
|
|
4
|
+
if (!lastChunk) return object;
|
|
5
|
+
const ref = propChunks.reduce((reducedObject, key) => {
|
|
6
|
+
if (reducedObject[key] === void 0) reducedObject[key] = {};
|
|
7
|
+
return reducedObject[key];
|
|
8
|
+
}, object);
|
|
9
|
+
ref[lastChunk] = value;
|
|
10
|
+
return object;
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
set
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function difference(setA: Iterable<any>, setB: Iterable<any>): Set<any>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { union } from "./union.js";
|
|
2
|
+
import { intersection } from "./intersection.js";
|
|
3
|
+
import { isSuperset } from "./is-superset.js";
|
|
4
|
+
import { difference } from "./difference.js";
|
|
5
|
+
import { symmetricDifference } from "./symmetric-difference.js";
|
|
6
|
+
export {
|
|
7
|
+
difference,
|
|
8
|
+
intersection,
|
|
9
|
+
isSuperset,
|
|
10
|
+
symmetricDifference,
|
|
11
|
+
union
|
|
12
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function intersection(setA: Iterable<any>, setB: Iterable<any>): Set<unknown>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
function intersection(setA, setB) {
|
|
2
|
+
const _setA = setA instanceof Set ? setA : new Set(setA);
|
|
3
|
+
const _intersection = /* @__PURE__ */ new Set();
|
|
4
|
+
for (const elem of setB) {
|
|
5
|
+
if (_setA.has(elem)) {
|
|
6
|
+
_intersection.add(elem);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return _intersection;
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
intersection
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isSuperset(set: Iterable<any>, subset: Iterable<any>): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function symmetricDifference(setA: Iterable<any>, setB: Iterable<any>): Set<any>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
function symmetricDifference(setA, setB) {
|
|
2
|
+
const _difference = new Set(setA);
|
|
3
|
+
for (const elem of setB) {
|
|
4
|
+
if (_difference.has(elem)) {
|
|
5
|
+
_difference.delete(elem);
|
|
6
|
+
} else {
|
|
7
|
+
_difference.add(elem);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return _difference;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
symmetricDifference
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function union(setA: Iterable<any>, setB: Iterable<any>): Set<any>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const capitalize: <T extends string>(s: T) => Capitalize<typeof s>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { truncate } from "./truncate.js";
|
|
2
|
+
import { trim } from "./trim.js";
|
|
3
|
+
import { stripHtmlTags } from "./strip-html-tags.js";
|
|
4
|
+
import { capitalize } from "./capitalize.js";
|
|
5
|
+
import { toSentenceCase } from "./to-sentence-case.js";
|
|
6
|
+
import { stringToInt } from "./to-int.js";
|
|
7
|
+
export {
|
|
8
|
+
capitalize,
|
|
9
|
+
stringToInt,
|
|
10
|
+
stripHtmlTags,
|
|
11
|
+
toSentenceCase,
|
|
12
|
+
trim,
|
|
13
|
+
truncate
|
|
14
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Rule, RuleKey, RuleValue } from './types';
|
|
2
|
+
export declare class Pluralize {
|
|
3
|
+
private pluralRules;
|
|
4
|
+
private singularRules;
|
|
5
|
+
private uncountables;
|
|
6
|
+
private irregularPlurals;
|
|
7
|
+
private irregularSingles;
|
|
8
|
+
constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Add a pluralization rule to the collection.
|
|
11
|
+
*/
|
|
12
|
+
addPluralRule(rule: RuleKey, replacement: RuleValue): void;
|
|
13
|
+
/**
|
|
14
|
+
* Add a singularization rule to the collection.
|
|
15
|
+
*/
|
|
16
|
+
addSingularRule(rule: RuleKey, replacement: RuleValue): void;
|
|
17
|
+
/**
|
|
18
|
+
* Add an uncountable word rule.
|
|
19
|
+
*/
|
|
20
|
+
addUncountableRule(word: RuleKey): void;
|
|
21
|
+
/**
|
|
22
|
+
* Add an irregular word definition.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} single
|
|
25
|
+
* @param {string} plural
|
|
26
|
+
*/
|
|
27
|
+
addIrregularRule(single: string, plural: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Sanitize a pluralization rule to a usable regular expression.
|
|
30
|
+
*/
|
|
31
|
+
sanitizeRule(rule: RuleKey): RegExp;
|
|
32
|
+
/**
|
|
33
|
+
* Pass in a word token to produce a function that can replicate the case on
|
|
34
|
+
* another word.
|
|
35
|
+
*/
|
|
36
|
+
restoreCase(word: string, token: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Interpolate a regexp string.
|
|
39
|
+
*
|
|
40
|
+
* @param {string} str
|
|
41
|
+
* @param {Array} args
|
|
42
|
+
* @return {string}
|
|
43
|
+
*/
|
|
44
|
+
interpolate(str: string, args: string[]): string;
|
|
45
|
+
/**
|
|
46
|
+
* Replace a word using a rule.
|
|
47
|
+
*/
|
|
48
|
+
replace(word: string, rule: Rule): string;
|
|
49
|
+
/**
|
|
50
|
+
* Sanitize a word by passing in the word and sanitization rules.
|
|
51
|
+
*/
|
|
52
|
+
sanitizeWord(token: string, word: string, rules: Rule[]): string;
|
|
53
|
+
/**
|
|
54
|
+
* Replace a word with the updated word.
|
|
55
|
+
*/
|
|
56
|
+
old_replaceWord(replaceMap: Record<string, string>, keepMap: Record<string, string>, rules: Rule[]): (word: string) => string;
|
|
57
|
+
/**
|
|
58
|
+
* Replace a word with the updated word.
|
|
59
|
+
*/
|
|
60
|
+
private replaceWord;
|
|
61
|
+
/**
|
|
62
|
+
* Check if a word is part of the map.
|
|
63
|
+
*/
|
|
64
|
+
private checkWord;
|
|
65
|
+
/**
|
|
66
|
+
* Pluralize or singularize a word based on the passed in count.
|
|
67
|
+
*/
|
|
68
|
+
pluralize(word: string, count: number, inclusive: boolean): string;
|
|
69
|
+
/**
|
|
70
|
+
* Pluralize a word.
|
|
71
|
+
*/
|
|
72
|
+
plural(singularWord: string): string;
|
|
73
|
+
/**
|
|
74
|
+
* Check if a word is plural.
|
|
75
|
+
*/
|
|
76
|
+
isPlural(word: string): void;
|
|
77
|
+
/**
|
|
78
|
+
* Singularize a word.
|
|
79
|
+
*/
|
|
80
|
+
singular(pluralWord: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* Check if a word is singular.
|
|
83
|
+
*/
|
|
84
|
+
isSingular(word: string): void;
|
|
85
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { IRREGULAR_WORDS } from "./rules/irregular.js";
|
|
2
|
+
import { PLURALIZATION_RULES } from "./rules/pluralization.js";
|
|
3
|
+
import { SINGULARIZATION_RULES } from "./rules/singularization.js";
|
|
4
|
+
import { UNCOUNTABLE_WORDS } from "./rules/uncountable.js";
|
|
5
|
+
const TagIndexRegExp = /\$(\d{1,2})/g;
|
|
6
|
+
class Pluralize {
|
|
7
|
+
// Rule storage - pluralize and singularize need to be run sequentially,
|
|
8
|
+
// while other rules can be optimized using an object for instant lookups.
|
|
9
|
+
pluralRules = [];
|
|
10
|
+
singularRules = [];
|
|
11
|
+
uncountables = {};
|
|
12
|
+
irregularPlurals = {};
|
|
13
|
+
irregularSingles = {};
|
|
14
|
+
constructor() {
|
|
15
|
+
for (let index = 0; index < IRREGULAR_WORDS.length; index += 1) {
|
|
16
|
+
this.addIrregularRule(
|
|
17
|
+
IRREGULAR_WORDS[index][0],
|
|
18
|
+
IRREGULAR_WORDS[index][1]
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
for (let index = 0; index < PLURALIZATION_RULES.length; index += 1) {
|
|
22
|
+
this.addPluralRule(
|
|
23
|
+
PLURALIZATION_RULES[index][0],
|
|
24
|
+
PLURALIZATION_RULES[index][1]
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
for (let index = 0; index < SINGULARIZATION_RULES.length; index += 1) {
|
|
28
|
+
this.addSingularRule(
|
|
29
|
+
SINGULARIZATION_RULES[index][0],
|
|
30
|
+
SINGULARIZATION_RULES[index][1]
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
for (let index = 0; index < UNCOUNTABLE_WORDS.length; index += 1) {
|
|
34
|
+
this.addUncountableRule(UNCOUNTABLE_WORDS[index]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Add a pluralization rule to the collection.
|
|
39
|
+
*/
|
|
40
|
+
addPluralRule(rule, replacement) {
|
|
41
|
+
this.pluralRules.push([this.sanitizeRule(rule), replacement]);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Add a singularization rule to the collection.
|
|
45
|
+
*/
|
|
46
|
+
addSingularRule(rule, replacement) {
|
|
47
|
+
this.singularRules.push([this.sanitizeRule(rule), replacement]);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Add an uncountable word rule.
|
|
51
|
+
*/
|
|
52
|
+
addUncountableRule(word) {
|
|
53
|
+
if (typeof word === "string") {
|
|
54
|
+
this.uncountables[word.toLowerCase()] = true;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.addPluralRule(word, "$0");
|
|
58
|
+
this.addSingularRule(word, "$0");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Add an irregular word definition.
|
|
62
|
+
*
|
|
63
|
+
* @param {string} single
|
|
64
|
+
* @param {string} plural
|
|
65
|
+
*/
|
|
66
|
+
addIrregularRule(single, plural) {
|
|
67
|
+
plural = plural.toLowerCase();
|
|
68
|
+
single = single.toLowerCase();
|
|
69
|
+
this.irregularSingles[single] = plural;
|
|
70
|
+
this.irregularPlurals[plural] = single;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Sanitize a pluralization rule to a usable regular expression.
|
|
74
|
+
*/
|
|
75
|
+
sanitizeRule(rule) {
|
|
76
|
+
if (typeof rule === "string") {
|
|
77
|
+
return new RegExp(`^${rule}$`, "i");
|
|
78
|
+
}
|
|
79
|
+
return rule;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Pass in a word token to produce a function that can replicate the case on
|
|
83
|
+
* another word.
|
|
84
|
+
*/
|
|
85
|
+
restoreCase(word, token) {
|
|
86
|
+
if (word === token) return token;
|
|
87
|
+
if (word === word.toLowerCase()) return token.toLowerCase();
|
|
88
|
+
if (word === word.toUpperCase()) return token.toUpperCase();
|
|
89
|
+
if (word[0] === word[0].toUpperCase()) {
|
|
90
|
+
return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
|
|
91
|
+
}
|
|
92
|
+
return token.toLowerCase();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Interpolate a regexp string.
|
|
96
|
+
*
|
|
97
|
+
* @param {string} str
|
|
98
|
+
* @param {Array} args
|
|
99
|
+
* @return {string}
|
|
100
|
+
*/
|
|
101
|
+
interpolate(str, args) {
|
|
102
|
+
return str.replace(TagIndexRegExp, (match, index) => {
|
|
103
|
+
return args[index] || "";
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Replace a word using a rule.
|
|
108
|
+
*/
|
|
109
|
+
replace(word, rule) {
|
|
110
|
+
return word.replace(rule[0], (match, index, ...args) => {
|
|
111
|
+
const result = this.interpolate(rule[1], args);
|
|
112
|
+
if (match === "") {
|
|
113
|
+
return this.restoreCase(word[index - 1], result);
|
|
114
|
+
}
|
|
115
|
+
return this.restoreCase(match, result);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Sanitize a word by passing in the word and sanitization rules.
|
|
120
|
+
*/
|
|
121
|
+
sanitizeWord(token, word, rules) {
|
|
122
|
+
if (!token.length || this.uncountables[token]) {
|
|
123
|
+
return word;
|
|
124
|
+
}
|
|
125
|
+
let len = rules.length;
|
|
126
|
+
while (len--) {
|
|
127
|
+
const rule = rules[len];
|
|
128
|
+
if (typeof rule[0] === "string" || rule[0].test(word))
|
|
129
|
+
return this.replace(word, rule);
|
|
130
|
+
}
|
|
131
|
+
return word;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Replace a word with the updated word.
|
|
135
|
+
*/
|
|
136
|
+
old_replaceWord(replaceMap, keepMap, rules) {
|
|
137
|
+
return (word) => {
|
|
138
|
+
const token = word.toLowerCase();
|
|
139
|
+
if (keepMap[token]) {
|
|
140
|
+
return this.restoreCase(word, token);
|
|
141
|
+
}
|
|
142
|
+
if (replaceMap[token]) {
|
|
143
|
+
return this.restoreCase(word, replaceMap[token]);
|
|
144
|
+
}
|
|
145
|
+
return this.sanitizeWord(token, word, rules);
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Replace a word with the updated word.
|
|
150
|
+
*/
|
|
151
|
+
replaceWord(word, direction) {
|
|
152
|
+
const replaceMap = direction === "SingularToPlural" ? this.irregularSingles : this.irregularPlurals;
|
|
153
|
+
const keepMap = direction === "SingularToPlural" ? this.irregularPlurals : this.irregularSingles;
|
|
154
|
+
const rules = direction === "SingularToPlural" ? this.pluralRules : this.singularRules;
|
|
155
|
+
const token = word.toLowerCase();
|
|
156
|
+
if (keepMap[token]) {
|
|
157
|
+
return this.restoreCase(word, token);
|
|
158
|
+
}
|
|
159
|
+
if (replaceMap[token]) {
|
|
160
|
+
return this.restoreCase(word, replaceMap[token]);
|
|
161
|
+
}
|
|
162
|
+
return this.sanitizeWord(token, word, rules);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Check if a word is part of the map.
|
|
166
|
+
*/
|
|
167
|
+
checkWord(word, reason) {
|
|
168
|
+
const replaceMap = reason === "Plurality" ? this.irregularSingles : this.irregularPlurals;
|
|
169
|
+
const keepMap = reason === "Plurality" ? this.irregularPlurals : this.irregularSingles;
|
|
170
|
+
const rules = reason === "Singularity" ? this.pluralRules : this.singularRules;
|
|
171
|
+
const token = word.toLowerCase();
|
|
172
|
+
if (keepMap[token]) return true;
|
|
173
|
+
if (replaceMap[token]) return false;
|
|
174
|
+
return this.sanitizeWord(token, token, rules) === token;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Pluralize or singularize a word based on the passed in count.
|
|
178
|
+
*/
|
|
179
|
+
pluralize(word, count, inclusive) {
|
|
180
|
+
const pluralized = count === 1 ? this.singular(word) : this.plural(word);
|
|
181
|
+
return (inclusive ? `${count} ` : "") + pluralized;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Pluralize a word.
|
|
185
|
+
*/
|
|
186
|
+
plural(singularWord) {
|
|
187
|
+
return this.replaceWord(singularWord, "SingularToPlural");
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Check if a word is plural.
|
|
191
|
+
*/
|
|
192
|
+
isPlural(word) {
|
|
193
|
+
this.checkWord(word, "Plurality");
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Singularize a word.
|
|
197
|
+
*/
|
|
198
|
+
singular(pluralWord) {
|
|
199
|
+
return this.replaceWord(pluralWord, "PluralToSingular");
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Check if a word is singular.
|
|
203
|
+
*/
|
|
204
|
+
isSingular(word) {
|
|
205
|
+
this.checkWord(word, "Singularity");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
export {
|
|
209
|
+
Pluralize
|
|
210
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IRREGULAR_WORDS } from "./irregular.js";
|
|
2
|
+
import { PLURALIZATION_RULES } from "./pluralization.js";
|
|
3
|
+
import { SINGULARIZATION_RULES } from "./singularization.js";
|
|
4
|
+
import { UNCOUNTABLE_WORDS } from "./uncountable.js";
|
|
5
|
+
export {
|
|
6
|
+
IRREGULAR_WORDS,
|
|
7
|
+
PLURALIZATION_RULES,
|
|
8
|
+
SINGULARIZATION_RULES,
|
|
9
|
+
UNCOUNTABLE_WORDS
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const IRREGULAR_WORDS: [string, string][];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const IRREGULAR_WORDS = [
|
|
2
|
+
// Pronouns.
|
|
3
|
+
["I", "we"],
|
|
4
|
+
["me", "us"],
|
|
5
|
+
["he", "they"],
|
|
6
|
+
["she", "they"],
|
|
7
|
+
["them", "them"],
|
|
8
|
+
["myself", "ourselves"],
|
|
9
|
+
["yourself", "yourselves"],
|
|
10
|
+
["itself", "themselves"],
|
|
11
|
+
["herself", "themselves"],
|
|
12
|
+
["himself", "themselves"],
|
|
13
|
+
["themself", "themselves"],
|
|
14
|
+
["is", "are"],
|
|
15
|
+
["was", "were"],
|
|
16
|
+
["has", "have"],
|
|
17
|
+
["this", "these"],
|
|
18
|
+
["that", "those"],
|
|
19
|
+
["my", "our"],
|
|
20
|
+
["its", "their"],
|
|
21
|
+
["his", "their"],
|
|
22
|
+
["her", "their"],
|
|
23
|
+
// Words ending in with a consonant and `o`.
|
|
24
|
+
["echo", "echoes"],
|
|
25
|
+
["dingo", "dingoes"],
|
|
26
|
+
["volcano", "volcanoes"],
|
|
27
|
+
["tornado", "tornadoes"],
|
|
28
|
+
["torpedo", "torpedoes"],
|
|
29
|
+
// Ends with `us`.
|
|
30
|
+
["genus", "genera"],
|
|
31
|
+
["viscus", "viscera"],
|
|
32
|
+
// Ends with `ma`.
|
|
33
|
+
["stigma", "stigmata"],
|
|
34
|
+
["stoma", "stomata"],
|
|
35
|
+
["dogma", "dogmata"],
|
|
36
|
+
["lemma", "lemmata"],
|
|
37
|
+
["schema", "schemata"],
|
|
38
|
+
["anathema", "anathemata"],
|
|
39
|
+
// Other irregular rules.
|
|
40
|
+
["ox", "oxen"],
|
|
41
|
+
["axe", "axes"],
|
|
42
|
+
["die", "dice"],
|
|
43
|
+
["yes", "yeses"],
|
|
44
|
+
["foot", "feet"],
|
|
45
|
+
["eave", "eaves"],
|
|
46
|
+
["goose", "geese"],
|
|
47
|
+
["tooth", "teeth"],
|
|
48
|
+
["quiz", "quizzes"],
|
|
49
|
+
["human", "humans"],
|
|
50
|
+
["proof", "proofs"],
|
|
51
|
+
["carve", "carves"],
|
|
52
|
+
["valve", "valves"],
|
|
53
|
+
["looey", "looies"],
|
|
54
|
+
["thief", "thieves"],
|
|
55
|
+
["groove", "grooves"],
|
|
56
|
+
["pickaxe", "pickaxes"],
|
|
57
|
+
["passerby", "passersby"],
|
|
58
|
+
["canvas", "canvases"]
|
|
59
|
+
];
|
|
60
|
+
export {
|
|
61
|
+
IRREGULAR_WORDS
|
|
62
|
+
};
|