@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.
Files changed (128) hide show
  1. package/README.md +8 -0
  2. package/dist/array/chunk.d.ts +1 -0
  3. package/dist/array/chunk.js +9 -0
  4. package/dist/array/index.d.ts +1 -0
  5. package/dist/array/index.js +4 -0
  6. package/dist/date/index.d.ts +1 -0
  7. package/dist/date/index.js +8 -0
  8. package/dist/date/iso-date-time.d.ts +127 -0
  9. package/dist/date/iso-date-time.js +256 -0
  10. package/dist/duration/add-durations.d.ts +1 -0
  11. package/dist/duration/add-durations.js +12 -0
  12. package/dist/duration/index.d.ts +3 -0
  13. package/dist/duration/index.js +8 -0
  14. package/dist/duration/is-duration.d.ts +1 -0
  15. package/dist/duration/is-duration.js +7 -0
  16. package/dist/duration/to-number.d.ts +1 -0
  17. package/dist/duration/to-number.js +14 -0
  18. package/dist/format/formatter.d.ts +5 -0
  19. package/dist/format/formatter.js +40 -0
  20. package/dist/format/index.d.ts +3 -0
  21. package/dist/format/index.js +13 -0
  22. package/dist/format/stringify.d.ts +38 -0
  23. package/dist/format/stringify.js +42 -0
  24. package/dist/format/template.d.ts +6 -0
  25. package/dist/format/template.js +35 -0
  26. package/dist/object/get.d.ts +1 -0
  27. package/dist/object/get.js +7 -0
  28. package/dist/object/index.d.ts +5 -0
  29. package/dist/object/index.js +12 -0
  30. package/dist/object/is-object.d.ts +1 -0
  31. package/dist/object/is-object.js +4 -0
  32. package/dist/object/omit.d.ts +1 -0
  33. package/dist/object/omit.js +18 -0
  34. package/dist/object/pick.d.ts +1 -0
  35. package/dist/object/pick.js +11 -0
  36. package/dist/object/set.d.ts +1 -0
  37. package/dist/object/set.js +14 -0
  38. package/dist/set/difference.d.ts +1 -0
  39. package/dist/set/difference.js +10 -0
  40. package/dist/set/index.d.ts +5 -0
  41. package/dist/set/index.js +12 -0
  42. package/dist/set/intersection.d.ts +1 -0
  43. package/dist/set/intersection.js +13 -0
  44. package/dist/set/is-superset.d.ts +1 -0
  45. package/dist/set/is-superset.js +12 -0
  46. package/dist/set/symmetric-difference.d.ts +1 -0
  47. package/dist/set/symmetric-difference.js +14 -0
  48. package/dist/set/union.d.ts +1 -0
  49. package/dist/set/union.js +10 -0
  50. package/dist/string/capitalize.d.ts +1 -0
  51. package/dist/string/capitalize.js +4 -0
  52. package/dist/string/index.d.ts +6 -0
  53. package/dist/string/index.js +14 -0
  54. package/dist/string/pluralize/index.d.ts +2 -0
  55. package/dist/string/pluralize/index.js +4 -0
  56. package/dist/string/pluralize/pluralize.d.ts +85 -0
  57. package/dist/string/pluralize/pluralize.js +210 -0
  58. package/dist/string/pluralize/rules/index.d.ts +4 -0
  59. package/dist/string/pluralize/rules/index.js +10 -0
  60. package/dist/string/pluralize/rules/irregular.d.ts +1 -0
  61. package/dist/string/pluralize/rules/irregular.js +62 -0
  62. package/dist/string/pluralize/rules/pluralization.d.ts +2 -0
  63. package/dist/string/pluralize/rules/pluralization.js +39 -0
  64. package/dist/string/pluralize/rules/singularization.d.ts +2 -0
  65. package/dist/string/pluralize/rules/singularization.js +47 -0
  66. package/dist/string/pluralize/rules/uncountable.d.ts +2 -0
  67. package/dist/string/pluralize/rules/uncountable.js +113 -0
  68. package/dist/string/pluralize/types.d.ts +3 -0
  69. package/dist/string/pluralize/types.js +1 -0
  70. package/dist/string/slugify/index.d.ts +1 -0
  71. package/dist/string/slugify/index.js +2263 -0
  72. package/dist/string/strip-html-tags.d.ts +1 -0
  73. package/dist/string/strip-html-tags.js +7 -0
  74. package/dist/string/to-int.d.ts +9 -0
  75. package/dist/string/to-int.js +10 -0
  76. package/dist/string/to-sentence-case.d.ts +1 -0
  77. package/dist/string/to-sentence-case.js +8 -0
  78. package/dist/string/trim.d.ts +1 -0
  79. package/dist/string/trim.js +11 -0
  80. package/dist/string/truncate.d.ts +1 -0
  81. package/dist/string/truncate.js +9 -0
  82. package/eslint.config.js +19 -0
  83. package/package.json +68 -0
  84. package/src/array/chunk.ts +6 -0
  85. package/src/array/index.ts +1 -0
  86. package/src/date/index.ts +1 -0
  87. package/src/date/iso-date-time.ts +356 -0
  88. package/src/duration/add-durations.ts +16 -0
  89. package/src/duration/index.ts +3 -0
  90. package/src/duration/is-duration.ts +5 -0
  91. package/src/duration/to-number.ts +18 -0
  92. package/src/format/formatter.ts +37 -0
  93. package/src/format/index.ts +3 -0
  94. package/src/format/stringify.ts +87 -0
  95. package/src/format/template.ts +48 -0
  96. package/src/object/get.ts +9 -0
  97. package/src/object/index.ts +5 -0
  98. package/src/object/is-object.ts +2 -0
  99. package/src/object/omit.ts +21 -0
  100. package/src/object/pick.ts +10 -0
  101. package/src/object/set.ts +15 -0
  102. package/src/set/difference.ts +9 -0
  103. package/src/set/index.ts +5 -0
  104. package/src/set/intersection.ts +12 -0
  105. package/src/set/is-superset.ts +12 -0
  106. package/src/set/symmetric-difference.ts +12 -0
  107. package/src/set/union.ts +8 -0
  108. package/src/string/capitalize.ts +2 -0
  109. package/src/string/index.ts +6 -0
  110. package/src/string/pluralize/index.ts +2 -0
  111. package/src/string/pluralize/pluralize.ts +296 -0
  112. package/src/string/pluralize/rules/index.ts +4 -0
  113. package/src/string/pluralize/rules/irregular.ts +59 -0
  114. package/src/string/pluralize/rules/pluralization.ts +40 -0
  115. package/src/string/pluralize/rules/singularization.ts +46 -0
  116. package/src/string/pluralize/rules/uncountable.ts +107 -0
  117. package/src/string/pluralize/types.ts +4 -0
  118. package/src/string/slugify/index.ts +3 -0
  119. package/src/string/strip-html-tags.ts +4 -0
  120. package/src/string/to-int.ts +20 -0
  121. package/src/string/to-sentence-case.ts +6 -0
  122. package/src/string/trim.ts +11 -0
  123. package/src/string/truncate.ts +11 -0
  124. package/tsconfig.json +18 -0
  125. package/tsconfig.lib.json +36 -0
  126. package/tsconfig.lib.tsbuildinfo +1 -0
  127. package/tsconfig.node.json +25 -0
  128. 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,7 @@
1
+ const get = (object, prop) => prop.split(".").reduce(
2
+ (reducedObject, key) => reducedObject && key in reducedObject ? reducedObject[key] : void 0,
3
+ object
4
+ );
5
+ export {
6
+ get
7
+ };
@@ -0,0 +1,5 @@
1
+ export * from './is-object';
2
+ export * from './get';
3
+ export * from './set';
4
+ export * from './omit';
5
+ export * from './pick';
@@ -0,0 +1,12 @@
1
+ import { isObject } from "./is-object.js";
2
+ import { get } from "./get.js";
3
+ import { set } from "./set.js";
4
+ import { omit } from "./omit.js";
5
+ import { pick } from "./pick.js";
6
+ export {
7
+ get,
8
+ isObject,
9
+ omit,
10
+ pick,
11
+ set
12
+ };
@@ -0,0 +1 @@
1
+ export declare const isObject: (object: unknown) => boolean;
@@ -0,0 +1,4 @@
1
+ const isObject = (object) => typeof object === "object" && !Array.isArray(object) && object !== null;
2
+ export {
3
+ isObject
4
+ };
@@ -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,11 @@
1
+ import { get } from "./get.js";
2
+ import { set } from "./set.js";
3
+ const pick = (object, props) => {
4
+ return props.reduce((result, key) => {
5
+ set(result, key, get(object, key));
6
+ return result;
7
+ }, {});
8
+ };
9
+ export {
10
+ pick
11
+ };
@@ -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,10 @@
1
+ function difference(setA, setB) {
2
+ const _difference = new Set(setA);
3
+ for (const elem of setB) {
4
+ _difference.delete(elem);
5
+ }
6
+ return _difference;
7
+ }
8
+ export {
9
+ difference
10
+ };
@@ -0,0 +1,5 @@
1
+ export * from './union';
2
+ export * from './intersection';
3
+ export * from './is-superset';
4
+ export * from './difference';
5
+ export * from './symmetric-difference';
@@ -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,12 @@
1
+ function isSuperset(set, subset) {
2
+ const _set = set instanceof Set ? set : new Set(set);
3
+ for (const elem of subset) {
4
+ if (!_set.has(elem)) {
5
+ return false;
6
+ }
7
+ }
8
+ return true;
9
+ }
10
+ export {
11
+ isSuperset
12
+ };
@@ -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,10 @@
1
+ function union(setA, setB) {
2
+ const _union = new Set(setA);
3
+ for (const elem of setB) {
4
+ _union.add(elem);
5
+ }
6
+ return _union;
7
+ }
8
+ export {
9
+ union
10
+ };
@@ -0,0 +1 @@
1
+ export declare const capitalize: <T extends string>(s: T) => Capitalize<typeof s>;
@@ -0,0 +1,4 @@
1
+ const capitalize = (s) => s[0].toUpperCase() + s.slice(1);
2
+ export {
3
+ capitalize
4
+ };
@@ -0,0 +1,6 @@
1
+ export * from './truncate';
2
+ export * from './trim';
3
+ export * from './strip-html-tags';
4
+ export * from './capitalize';
5
+ export * from './to-sentence-case';
6
+ export * from './to-int';
@@ -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,2 @@
1
+ export * from './pluralize';
2
+ export type * from './types';
@@ -0,0 +1,4 @@
1
+ import { Pluralize } from "./pluralize.js";
2
+ export {
3
+ Pluralize
4
+ };
@@ -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,4 @@
1
+ export { IRREGULAR_WORDS } from './irregular';
2
+ export { PLURALIZATION_RULES } from './pluralization';
3
+ export { SINGULARIZATION_RULES } from './singularization';
4
+ export { UNCOUNTABLE_WORDS } from './uncountable';
@@ -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
+ };
@@ -0,0 +1,2 @@
1
+ import { Rule } from '../types';
2
+ export declare const PLURALIZATION_RULES: Rule[];