@stonyx/utils 0.2.3-alpha.3 → 0.2.3-alpha.30
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 +16 -2
- package/dist/date.d.ts +1 -0
- package/dist/date.js +4 -0
- package/dist/file.d.ts +79 -0
- package/dist/file.js +234 -0
- package/dist/fuzzy-match.d.ts +26 -0
- package/dist/fuzzy-match.js +80 -0
- package/dist/object.d.ts +14 -0
- package/dist/object.js +60 -0
- package/dist/plurarize.d.ts +1 -0
- package/dist/plurarize.js +87 -0
- package/dist/promise.d.ts +1 -0
- package/dist/promise.js +5 -0
- package/dist/prompt.d.ts +8 -0
- package/dist/prompt.js +33 -0
- package/dist/string.d.ts +5 -0
- package/dist/string.js +32 -0
- package/package.json +41 -10
- package/.claude/improvements.md +0 -73
- package/.claude/project-structure.md +0 -168
- package/.github/workflows/ci.yml +0 -16
- package/.github/workflows/publish.yml +0 -35
- package/src/date.js +0 -5
- package/src/file.js +0 -145
- package/src/object.js +0 -61
- package/src/plurarize.js +0 -103
- package/src/promise.js +0 -5
- package/src/prompt.js +0 -29
- package/src/string.js +0 -35
package/src/plurarize.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
// --- Irregular nouns ---
|
|
2
|
-
const irregular = {
|
|
3
|
-
person: 'people',
|
|
4
|
-
man: 'men',
|
|
5
|
-
woman: 'women',
|
|
6
|
-
child: 'children',
|
|
7
|
-
tooth: 'teeth',
|
|
8
|
-
foot: 'feet',
|
|
9
|
-
mouse: 'mice',
|
|
10
|
-
goose: 'geese',
|
|
11
|
-
ox: 'oxen',
|
|
12
|
-
cactus: 'cacti',
|
|
13
|
-
nucleus: 'nuclei',
|
|
14
|
-
syllabus: 'syllabi',
|
|
15
|
-
focus: 'foci',
|
|
16
|
-
fungus: 'fungi',
|
|
17
|
-
appendix: 'appendices',
|
|
18
|
-
index: 'indices',
|
|
19
|
-
criterion: 'criteria',
|
|
20
|
-
phenomenon: 'phenomena',
|
|
21
|
-
die: 'dice',
|
|
22
|
-
thesis: 'theses',
|
|
23
|
-
analysis: 'analyses',
|
|
24
|
-
crisis: 'crises',
|
|
25
|
-
radius: 'radii',
|
|
26
|
-
corpus: 'corpora',
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
// --- Uncountables ---
|
|
30
|
-
const uncountable = new Set([
|
|
31
|
-
'sheep', 'fish', 'deer', 'series', 'species', 'news', 'information',
|
|
32
|
-
'rice', 'moose', 'bison', 'salmon', 'aircraft', 'offspring'
|
|
33
|
-
]);
|
|
34
|
-
|
|
35
|
-
// --- Exceptions ---
|
|
36
|
-
const fExceptions = new Set(['chief', 'roof', 'belief', 'chef', 'cliff', 'reef', 'proof', 'brief']);
|
|
37
|
-
|
|
38
|
-
// Keep only true irregular -o exceptions (consonant + o but take just "s")
|
|
39
|
-
const oExceptions = new Set(['piano', 'photo', 'halo', 'canto', 'solo']);
|
|
40
|
-
|
|
41
|
-
// --- Utility to preserve casing ---
|
|
42
|
-
function applyCasing(original, plural) {
|
|
43
|
-
if (original === original.toUpperCase()) return plural.toUpperCase();
|
|
44
|
-
if (original === original.toLowerCase()) return plural.toLowerCase();
|
|
45
|
-
if (original[0] === original[0].toUpperCase()) {
|
|
46
|
-
return plural.charAt(0).toUpperCase() + plural.slice(1);
|
|
47
|
-
}
|
|
48
|
-
return plural;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// --- Rule-based pluralization ---
|
|
52
|
-
const rules = [
|
|
53
|
-
// quiz → quizzes, waltz → waltzes, topaz → topazes
|
|
54
|
-
[/z$/i, w => (/iz$/i.test(w) ? w + 'zes' : w + 'es')],
|
|
55
|
-
|
|
56
|
-
// bus → buses, box → boxes, church → churches, but stomach → stomachs (exclude -ach)
|
|
57
|
-
[/(s|x|ch|sh)$/i, w => (/ach$/i.test(w) ? w + 's' : w + 'es')],
|
|
58
|
-
|
|
59
|
-
// vowel + y → +s (key → keys)
|
|
60
|
-
[/[aeiou]y$/i, w => w + 's'],
|
|
61
|
-
|
|
62
|
-
// consonant + y → -ies (city → cities)
|
|
63
|
-
[/y$/i, w => w.slice(0, -1) + 'ies'],
|
|
64
|
-
|
|
65
|
-
// -fe → -ves (knife → knives), but not chief/roof/etc
|
|
66
|
-
[/fe$/i, w => (fExceptions.has(w) ? w + 's' : w.slice(0, -2) + 'ves')],
|
|
67
|
-
|
|
68
|
-
// -f → -ves (wolf → wolves), but not cliff/etc
|
|
69
|
-
[/f$/i, w => (fExceptions.has(w) ? w + 's' : w.slice(0, -1) + 'ves')],
|
|
70
|
-
|
|
71
|
-
// -sis → -ses (analysis → analyses, thesis → theses)
|
|
72
|
-
[/sis$/i, w => w.slice(0, -2) + 'ses'],
|
|
73
|
-
|
|
74
|
-
// vowel + o → +s (zoo → zoos, video → videos, patio → patios)
|
|
75
|
-
[/[aeiou]o$/i, w => w + 's'],
|
|
76
|
-
|
|
77
|
-
// consonant + o → usually +es, unless in oExceptions
|
|
78
|
-
[/o$/i, w => (oExceptions.has(w) ? w + 's' : w + 'es')],
|
|
79
|
-
|
|
80
|
-
// default: just +s
|
|
81
|
-
[/$/i, w => w + 's']
|
|
82
|
-
];
|
|
83
|
-
|
|
84
|
-
// --- Exported pluralizer ---
|
|
85
|
-
export default function pluralize(word) {
|
|
86
|
-
if (typeof word !== 'string' || !/^[a-zA-Z]+$/.test(word)) return word;
|
|
87
|
-
|
|
88
|
-
const lower = word.toLowerCase();
|
|
89
|
-
|
|
90
|
-
if (uncountable.has(lower)) return word;
|
|
91
|
-
|
|
92
|
-
if (irregular[lower]) {
|
|
93
|
-
return applyCasing(word, irregular[lower]);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
for (const [pattern, transform] of rules) {
|
|
97
|
-
if (pattern.test(lower)) {
|
|
98
|
-
return applyCasing(word, transform(lower));
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return word; // fallback (shouldn't hit)
|
|
103
|
-
}
|
package/src/promise.js
DELETED
package/src/prompt.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { createInterface } from 'readline';
|
|
2
|
-
|
|
3
|
-
export function confirm(question, { input, output } = {}) {
|
|
4
|
-
const rl = createInterface({
|
|
5
|
-
input: input ?? process.stdin,
|
|
6
|
-
output: output ?? process.stdout,
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
return new Promise(resolve => {
|
|
10
|
-
rl.question(`${question} (y/N) `, answer => {
|
|
11
|
-
rl.close();
|
|
12
|
-
resolve(answer.trim().toLowerCase() === 'y');
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function prompt(question, { input, output } = {}) {
|
|
18
|
-
const rl = createInterface({
|
|
19
|
-
input: input ?? process.stdin,
|
|
20
|
-
output: output ?? process.stdout,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
return new Promise(resolve => {
|
|
24
|
-
rl.question(`${question} `, answer => {
|
|
25
|
-
rl.close();
|
|
26
|
-
resolve(answer.trim());
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
}
|
package/src/string.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
function kebabToCase(str, pascal=false) {
|
|
2
|
-
let out = '';
|
|
3
|
-
let upperNext = pascal; // PascalCase starts uppercase
|
|
4
|
-
for (let i = 0; i < str.length; i++) {
|
|
5
|
-
const ch = str.charAt(i);
|
|
6
|
-
if (ch === '-') {
|
|
7
|
-
upperNext = true;
|
|
8
|
-
} else if (upperNext) {
|
|
9
|
-
out += ch.toUpperCase();
|
|
10
|
-
upperNext = false;
|
|
11
|
-
} else {
|
|
12
|
-
out += ch;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return out;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function kebabCaseToCamelCase(str) {
|
|
19
|
-
return kebabToCase(str, false);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function kebabCaseToPascalCase(str) {
|
|
23
|
-
return kebabToCase(str, true);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function camelCaseToKebabCase(str) {
|
|
27
|
-
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function generateRandomString(length=8) {
|
|
31
|
-
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
32
|
-
return Array(length).fill('').map(() => characters.charAt(Math.floor(Math.random() * characters.length))).join('');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { default as pluralize } from './plurarize.js';
|