@guanghechen/string 1.0.1
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 +100 -0
- package/lib/cjs/index.cjs +202 -0
- package/lib/esm/index.mjs +187 -0
- package/lib/types/index.d.ts +132 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<header>
|
|
2
|
+
<h1 align="center">
|
|
3
|
+
<a href="https://github.com/guanghechen/sora/tree/@guanghechen/string@1.0.1/packages/string#readme">@guanghechen/string</a>
|
|
4
|
+
</h1>
|
|
5
|
+
<div align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/@guanghechen/string">
|
|
7
|
+
<img
|
|
8
|
+
alt="Npm Version"
|
|
9
|
+
src="https://img.shields.io/npm/v/@guanghechen/string.svg"
|
|
10
|
+
/>
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/@guanghechen/string">
|
|
13
|
+
<img
|
|
14
|
+
alt="Npm Download"
|
|
15
|
+
src="https://img.shields.io/npm/dm/@guanghechen/string.svg"
|
|
16
|
+
/>
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/@guanghechen/string">
|
|
19
|
+
<img
|
|
20
|
+
alt="Npm License"
|
|
21
|
+
src="https://img.shields.io/npm/l/@guanghechen/string.svg"
|
|
22
|
+
/>
|
|
23
|
+
</a>
|
|
24
|
+
<a href="https://github.com/nodejs/node">
|
|
25
|
+
<img
|
|
26
|
+
alt="Node.js Version"
|
|
27
|
+
src="https://img.shields.io/node/v/@guanghechen/string"
|
|
28
|
+
/>
|
|
29
|
+
</a>
|
|
30
|
+
<a href="https://github.com/facebook/jest">
|
|
31
|
+
<img
|
|
32
|
+
alt="Tested with Jest"
|
|
33
|
+
src="https://img.shields.io/badge/tested_with-jest-9c465e.svg"
|
|
34
|
+
/>
|
|
35
|
+
</a>
|
|
36
|
+
<a href="https://github.com/prettier/prettier">
|
|
37
|
+
<img
|
|
38
|
+
alt="Code Style: prettier"
|
|
39
|
+
src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square"
|
|
40
|
+
/>
|
|
41
|
+
</a>
|
|
42
|
+
</div>
|
|
43
|
+
</header>
|
|
44
|
+
<br/>
|
|
45
|
+
|
|
46
|
+
Utilities for processing strings or stringify other type data.
|
|
47
|
+
|
|
48
|
+
## Install
|
|
49
|
+
|
|
50
|
+
* npm
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm install --save-dev @guanghechen/string
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
* yarn
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
yarn add --dev @guanghechen/string
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Usage
|
|
63
|
+
|
|
64
|
+
* `transformer` utilities
|
|
65
|
+
|
|
66
|
+
Name | Description
|
|
67
|
+
:--------------------:|:---------------------------------------
|
|
68
|
+
`toCamelCase` | `'test string' => 'testString'`
|
|
69
|
+
`toCapitalCase` | `'test string' => 'Test String'`
|
|
70
|
+
`toConstantCase` | `'test string' => 'TEST_STRING'`
|
|
71
|
+
`toDotCase` | `'test string' => 'test.string'`
|
|
72
|
+
`toKebabCase` | `'test string' => 'test-string'`
|
|
73
|
+
`toLowerCase` | `'TEST STRING' => 'test string'`
|
|
74
|
+
`toPascalCase` | `'test string' => 'TestString'`
|
|
75
|
+
`toPathCase` | `'test string' => 'test/string'`
|
|
76
|
+
`toSentenceCase` | `'testString' => 'Test string'`
|
|
77
|
+
`toSnakeCase` | `'test string' => 'test_string'`
|
|
78
|
+
`toTitleCase` | `'a simple test' => 'A Simple Test'`
|
|
79
|
+
`toUpperCase` | `'test string' => 'TEST STRING'`
|
|
80
|
+
|
|
81
|
+
- `composeTextTransformers`: Compose multiple ITextTransformer into one.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import {
|
|
85
|
+
composeTextTransformers,
|
|
86
|
+
toKebabCase,
|
|
87
|
+
toTrim,
|
|
88
|
+
} from '@guanghechen/string'
|
|
89
|
+
|
|
90
|
+
// function composeTextTransformers (
|
|
91
|
+
// ...transformers: ReadonlyArray<ITextTransformer>
|
|
92
|
+
// ): ITextTransformer
|
|
93
|
+
|
|
94
|
+
const transform = composeTextTransformers(toTrim, toKebabCase)
|
|
95
|
+
const text: string = transform(' TeSt_StrinG ')
|
|
96
|
+
// => 'test-string'
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
[homepage]: https://github.com/guanghechen/sora/tree/@guanghechen/string@1.0.1/packages/string#readme
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
|
|
4
|
+
const SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
|
|
5
|
+
const SPLIT_NUMBER_LOWER_RE = /(\d)(\p{Ll})/gu;
|
|
6
|
+
const SPLIT_LETTER_NUMBER_RE = /(\p{L})(\d)/gu;
|
|
7
|
+
const DEFAULT_STRIP_REGEXP = /[^\p{L}\d]+/giu;
|
|
8
|
+
const SPLIT_REPLACE_VALUE = '$1\0$2';
|
|
9
|
+
function split(input, options = {}) {
|
|
10
|
+
let result = input
|
|
11
|
+
.replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE)
|
|
12
|
+
.replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);
|
|
13
|
+
if (options.separateNumbers) {
|
|
14
|
+
result = result
|
|
15
|
+
.replace(SPLIT_NUMBER_LOWER_RE, SPLIT_REPLACE_VALUE)
|
|
16
|
+
.replace(SPLIT_LETTER_NUMBER_RE, SPLIT_REPLACE_VALUE);
|
|
17
|
+
}
|
|
18
|
+
result = result.replace(DEFAULT_STRIP_REGEXP, '\0');
|
|
19
|
+
let start = 0;
|
|
20
|
+
let end = result.length;
|
|
21
|
+
while (result.charAt(start) === '\0')
|
|
22
|
+
start += 1;
|
|
23
|
+
if (start === end)
|
|
24
|
+
return [];
|
|
25
|
+
while (result.charAt(end - 1) === '\0')
|
|
26
|
+
end -= 1;
|
|
27
|
+
return result.slice(start, end).split(/\0/g);
|
|
28
|
+
}
|
|
29
|
+
function camelCase(input, options) {
|
|
30
|
+
const lower = lowerFactory(options?.locale);
|
|
31
|
+
const upper = upperFactory(options?.locale);
|
|
32
|
+
const transform = pascalCaseTransformFactory(lower, upper);
|
|
33
|
+
return split(input, options)
|
|
34
|
+
.map((word, index) => {
|
|
35
|
+
if (index === 0)
|
|
36
|
+
return lower(word);
|
|
37
|
+
return transform(word, index);
|
|
38
|
+
})
|
|
39
|
+
.join('');
|
|
40
|
+
}
|
|
41
|
+
function pascalCase(input, options) {
|
|
42
|
+
const lower = lowerFactory(options?.locale);
|
|
43
|
+
const upper = upperFactory(options?.locale);
|
|
44
|
+
return split(input, options).map(pascalCaseTransformFactory(lower, upper)).join('');
|
|
45
|
+
}
|
|
46
|
+
function capitalCase(input, options) {
|
|
47
|
+
const lower = lowerFactory(options?.locale);
|
|
48
|
+
const upper = upperFactory(options?.locale);
|
|
49
|
+
return split(input, options).map(capitalCaseTransformFactory(lower, upper)).join(' ');
|
|
50
|
+
}
|
|
51
|
+
function constantCase(input, options) {
|
|
52
|
+
const upper = upperFactory(options?.locale);
|
|
53
|
+
return split(input, options).map(upper).join('_');
|
|
54
|
+
}
|
|
55
|
+
function dotCase(input, options) {
|
|
56
|
+
const lower = lowerFactory(options?.locale);
|
|
57
|
+
return split(input, options).map(lower).join('.');
|
|
58
|
+
}
|
|
59
|
+
function kebabCase(input, options) {
|
|
60
|
+
const lower = lowerFactory(options?.locale);
|
|
61
|
+
return split(input, options).map(lower).join('-');
|
|
62
|
+
}
|
|
63
|
+
function pathCase(input, options) {
|
|
64
|
+
const lower = lowerFactory(options?.locale);
|
|
65
|
+
return split(input, options).map(lower).join('/');
|
|
66
|
+
}
|
|
67
|
+
function sentenceCase(input, options) {
|
|
68
|
+
const lower = lowerFactory(options?.locale);
|
|
69
|
+
const upper = upperFactory(options?.locale);
|
|
70
|
+
const transform = capitalCaseTransformFactory(lower, upper);
|
|
71
|
+
return split(input, options)
|
|
72
|
+
.map((word, index) => {
|
|
73
|
+
if (index === 0)
|
|
74
|
+
return transform(word, index);
|
|
75
|
+
return lower(word);
|
|
76
|
+
})
|
|
77
|
+
.join(' ');
|
|
78
|
+
}
|
|
79
|
+
function snakeCase(input, options) {
|
|
80
|
+
const lower = lowerFactory(options?.locale);
|
|
81
|
+
return split(input, options).map(lower).join('_');
|
|
82
|
+
}
|
|
83
|
+
function lowerFactory(locale) {
|
|
84
|
+
return (input) => input.toLocaleLowerCase(locale);
|
|
85
|
+
}
|
|
86
|
+
function upperFactory(locale) {
|
|
87
|
+
return (input) => input.toLocaleUpperCase(locale);
|
|
88
|
+
}
|
|
89
|
+
const capitalCaseTransformFactory = (lower, upper) => {
|
|
90
|
+
return (word) => `${upper(word[0])}${lower(word.slice(1))}`;
|
|
91
|
+
};
|
|
92
|
+
const pascalCaseTransformFactory = (lower, upper) => {
|
|
93
|
+
return (word, index) => {
|
|
94
|
+
const char0 = word[0];
|
|
95
|
+
const initial = index > 0 && char0 >= '0' && char0 <= '9' ? '_' + char0 : upper(char0);
|
|
96
|
+
return initial + lower(word.slice(1));
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const TOKENS = /\S+|./g;
|
|
101
|
+
const IS_MANUAL_CASE = /\p{Ll}(?=[\p{Lu}])|\.\p{L}/u;
|
|
102
|
+
const ALPHANUMERIC_PATTERN = /[\p{L}\d]+/gu;
|
|
103
|
+
const WORD_SEPARATORS = new Set(['—', '–', '-', '―', '/']);
|
|
104
|
+
const SMALL_WORDS = new Set([
|
|
105
|
+
'an',
|
|
106
|
+
'and',
|
|
107
|
+
'as',
|
|
108
|
+
'at',
|
|
109
|
+
'because',
|
|
110
|
+
'but',
|
|
111
|
+
'by',
|
|
112
|
+
'en',
|
|
113
|
+
'for',
|
|
114
|
+
'if',
|
|
115
|
+
'in',
|
|
116
|
+
'neither',
|
|
117
|
+
'nor',
|
|
118
|
+
'of',
|
|
119
|
+
'on',
|
|
120
|
+
'or',
|
|
121
|
+
'only',
|
|
122
|
+
'over',
|
|
123
|
+
'per',
|
|
124
|
+
'so',
|
|
125
|
+
'some',
|
|
126
|
+
'that',
|
|
127
|
+
'than',
|
|
128
|
+
'the',
|
|
129
|
+
'to',
|
|
130
|
+
'up',
|
|
131
|
+
'upon',
|
|
132
|
+
'v',
|
|
133
|
+
'vs',
|
|
134
|
+
'versus',
|
|
135
|
+
'via',
|
|
136
|
+
'when',
|
|
137
|
+
'with',
|
|
138
|
+
'without',
|
|
139
|
+
'yet',
|
|
140
|
+
]);
|
|
141
|
+
function titleCase(input, options = {}) {
|
|
142
|
+
let result = '';
|
|
143
|
+
let m;
|
|
144
|
+
const { smallWords = SMALL_WORDS, locale } = typeof options === 'string' || Array.isArray(options) ? { locale: options } : options;
|
|
145
|
+
while ((m = TOKENS.exec(input)) !== null) {
|
|
146
|
+
const { 0: token, index } = m;
|
|
147
|
+
if (IS_MANUAL_CASE.test(token)) {
|
|
148
|
+
result += token;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
result += token.replace(ALPHANUMERIC_PATTERN, (m, i) => {
|
|
152
|
+
if (index > 0 && index + token.length < input.length && smallWords.has(m)) {
|
|
153
|
+
return m;
|
|
154
|
+
}
|
|
155
|
+
if (i > 1 && !WORD_SEPARATORS.has(input.charAt(index + i - 1))) {
|
|
156
|
+
return m;
|
|
157
|
+
}
|
|
158
|
+
return m.charAt(0).toLocaleUpperCase(locale) + m.slice(1);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function composeTextTransformers(...transformers) {
|
|
166
|
+
return text => {
|
|
167
|
+
let result = text;
|
|
168
|
+
for (const transformer of transformers) {
|
|
169
|
+
result = transformer(result);
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const toCamelCase = text => camelCase(text);
|
|
175
|
+
const toCapitalCase = text => capitalCase(text);
|
|
176
|
+
const toConstantCase = text => constantCase(text);
|
|
177
|
+
const toDotCase = text => dotCase(text);
|
|
178
|
+
const toKebabCase = text => kebabCase(text);
|
|
179
|
+
const toLowerCase = text => text.toLocaleLowerCase();
|
|
180
|
+
const toPascalCase = text => pascalCase(text);
|
|
181
|
+
const toPathCase = text => pathCase(text);
|
|
182
|
+
const toSentenceCase = text => sentenceCase(text);
|
|
183
|
+
const toSnakeCase = text => snakeCase(text);
|
|
184
|
+
const toTitleCase = text => titleCase(text);
|
|
185
|
+
const toTrim = text => text.trim();
|
|
186
|
+
const toUpperCase = text => text.toLocaleUpperCase();
|
|
187
|
+
|
|
188
|
+
exports.composeTextTransformers = composeTextTransformers;
|
|
189
|
+
exports.toCamelCase = toCamelCase;
|
|
190
|
+
exports.toCapitalCase = toCapitalCase;
|
|
191
|
+
exports.toConstantCase = toConstantCase;
|
|
192
|
+
exports.toDotCase = toDotCase;
|
|
193
|
+
exports.toKebabCase = toKebabCase;
|
|
194
|
+
exports.toLowerCase = toLowerCase;
|
|
195
|
+
exports.toPascalCase = toPascalCase;
|
|
196
|
+
exports.toPathCase = toPathCase;
|
|
197
|
+
exports.toSentenceCase = toSentenceCase;
|
|
198
|
+
exports.toSnakeCase = toSnakeCase;
|
|
199
|
+
exports.toTitleCase = toTitleCase;
|
|
200
|
+
exports.toTrim = toTrim;
|
|
201
|
+
exports.toUpperCase = toUpperCase;
|
|
202
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const SPLIT_LOWER_UPPER_RE = /([\p{Ll}\d])(\p{Lu})/gu;
|
|
2
|
+
const SPLIT_UPPER_UPPER_RE = /(\p{Lu})([\p{Lu}][\p{Ll}])/gu;
|
|
3
|
+
const SPLIT_NUMBER_LOWER_RE = /(\d)(\p{Ll})/gu;
|
|
4
|
+
const SPLIT_LETTER_NUMBER_RE = /(\p{L})(\d)/gu;
|
|
5
|
+
const DEFAULT_STRIP_REGEXP = /[^\p{L}\d]+/giu;
|
|
6
|
+
const SPLIT_REPLACE_VALUE = '$1\0$2';
|
|
7
|
+
function split(input, options = {}) {
|
|
8
|
+
let result = input
|
|
9
|
+
.replace(SPLIT_LOWER_UPPER_RE, SPLIT_REPLACE_VALUE)
|
|
10
|
+
.replace(SPLIT_UPPER_UPPER_RE, SPLIT_REPLACE_VALUE);
|
|
11
|
+
if (options.separateNumbers) {
|
|
12
|
+
result = result
|
|
13
|
+
.replace(SPLIT_NUMBER_LOWER_RE, SPLIT_REPLACE_VALUE)
|
|
14
|
+
.replace(SPLIT_LETTER_NUMBER_RE, SPLIT_REPLACE_VALUE);
|
|
15
|
+
}
|
|
16
|
+
result = result.replace(DEFAULT_STRIP_REGEXP, '\0');
|
|
17
|
+
let start = 0;
|
|
18
|
+
let end = result.length;
|
|
19
|
+
while (result.charAt(start) === '\0')
|
|
20
|
+
start += 1;
|
|
21
|
+
if (start === end)
|
|
22
|
+
return [];
|
|
23
|
+
while (result.charAt(end - 1) === '\0')
|
|
24
|
+
end -= 1;
|
|
25
|
+
return result.slice(start, end).split(/\0/g);
|
|
26
|
+
}
|
|
27
|
+
function camelCase(input, options) {
|
|
28
|
+
const lower = lowerFactory(options?.locale);
|
|
29
|
+
const upper = upperFactory(options?.locale);
|
|
30
|
+
const transform = pascalCaseTransformFactory(lower, upper);
|
|
31
|
+
return split(input, options)
|
|
32
|
+
.map((word, index) => {
|
|
33
|
+
if (index === 0)
|
|
34
|
+
return lower(word);
|
|
35
|
+
return transform(word, index);
|
|
36
|
+
})
|
|
37
|
+
.join('');
|
|
38
|
+
}
|
|
39
|
+
function pascalCase(input, options) {
|
|
40
|
+
const lower = lowerFactory(options?.locale);
|
|
41
|
+
const upper = upperFactory(options?.locale);
|
|
42
|
+
return split(input, options).map(pascalCaseTransformFactory(lower, upper)).join('');
|
|
43
|
+
}
|
|
44
|
+
function capitalCase(input, options) {
|
|
45
|
+
const lower = lowerFactory(options?.locale);
|
|
46
|
+
const upper = upperFactory(options?.locale);
|
|
47
|
+
return split(input, options).map(capitalCaseTransformFactory(lower, upper)).join(' ');
|
|
48
|
+
}
|
|
49
|
+
function constantCase(input, options) {
|
|
50
|
+
const upper = upperFactory(options?.locale);
|
|
51
|
+
return split(input, options).map(upper).join('_');
|
|
52
|
+
}
|
|
53
|
+
function dotCase(input, options) {
|
|
54
|
+
const lower = lowerFactory(options?.locale);
|
|
55
|
+
return split(input, options).map(lower).join('.');
|
|
56
|
+
}
|
|
57
|
+
function kebabCase(input, options) {
|
|
58
|
+
const lower = lowerFactory(options?.locale);
|
|
59
|
+
return split(input, options).map(lower).join('-');
|
|
60
|
+
}
|
|
61
|
+
function pathCase(input, options) {
|
|
62
|
+
const lower = lowerFactory(options?.locale);
|
|
63
|
+
return split(input, options).map(lower).join('/');
|
|
64
|
+
}
|
|
65
|
+
function sentenceCase(input, options) {
|
|
66
|
+
const lower = lowerFactory(options?.locale);
|
|
67
|
+
const upper = upperFactory(options?.locale);
|
|
68
|
+
const transform = capitalCaseTransformFactory(lower, upper);
|
|
69
|
+
return split(input, options)
|
|
70
|
+
.map((word, index) => {
|
|
71
|
+
if (index === 0)
|
|
72
|
+
return transform(word, index);
|
|
73
|
+
return lower(word);
|
|
74
|
+
})
|
|
75
|
+
.join(' ');
|
|
76
|
+
}
|
|
77
|
+
function snakeCase(input, options) {
|
|
78
|
+
const lower = lowerFactory(options?.locale);
|
|
79
|
+
return split(input, options).map(lower).join('_');
|
|
80
|
+
}
|
|
81
|
+
function lowerFactory(locale) {
|
|
82
|
+
return (input) => input.toLocaleLowerCase(locale);
|
|
83
|
+
}
|
|
84
|
+
function upperFactory(locale) {
|
|
85
|
+
return (input) => input.toLocaleUpperCase(locale);
|
|
86
|
+
}
|
|
87
|
+
const capitalCaseTransformFactory = (lower, upper) => {
|
|
88
|
+
return (word) => `${upper(word[0])}${lower(word.slice(1))}`;
|
|
89
|
+
};
|
|
90
|
+
const pascalCaseTransformFactory = (lower, upper) => {
|
|
91
|
+
return (word, index) => {
|
|
92
|
+
const char0 = word[0];
|
|
93
|
+
const initial = index > 0 && char0 >= '0' && char0 <= '9' ? '_' + char0 : upper(char0);
|
|
94
|
+
return initial + lower(word.slice(1));
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const TOKENS = /\S+|./g;
|
|
99
|
+
const IS_MANUAL_CASE = /\p{Ll}(?=[\p{Lu}])|\.\p{L}/u;
|
|
100
|
+
const ALPHANUMERIC_PATTERN = /[\p{L}\d]+/gu;
|
|
101
|
+
const WORD_SEPARATORS = new Set(['—', '–', '-', '―', '/']);
|
|
102
|
+
const SMALL_WORDS = new Set([
|
|
103
|
+
'an',
|
|
104
|
+
'and',
|
|
105
|
+
'as',
|
|
106
|
+
'at',
|
|
107
|
+
'because',
|
|
108
|
+
'but',
|
|
109
|
+
'by',
|
|
110
|
+
'en',
|
|
111
|
+
'for',
|
|
112
|
+
'if',
|
|
113
|
+
'in',
|
|
114
|
+
'neither',
|
|
115
|
+
'nor',
|
|
116
|
+
'of',
|
|
117
|
+
'on',
|
|
118
|
+
'or',
|
|
119
|
+
'only',
|
|
120
|
+
'over',
|
|
121
|
+
'per',
|
|
122
|
+
'so',
|
|
123
|
+
'some',
|
|
124
|
+
'that',
|
|
125
|
+
'than',
|
|
126
|
+
'the',
|
|
127
|
+
'to',
|
|
128
|
+
'up',
|
|
129
|
+
'upon',
|
|
130
|
+
'v',
|
|
131
|
+
'vs',
|
|
132
|
+
'versus',
|
|
133
|
+
'via',
|
|
134
|
+
'when',
|
|
135
|
+
'with',
|
|
136
|
+
'without',
|
|
137
|
+
'yet',
|
|
138
|
+
]);
|
|
139
|
+
function titleCase(input, options = {}) {
|
|
140
|
+
let result = '';
|
|
141
|
+
let m;
|
|
142
|
+
const { smallWords = SMALL_WORDS, locale } = typeof options === 'string' || Array.isArray(options) ? { locale: options } : options;
|
|
143
|
+
while ((m = TOKENS.exec(input)) !== null) {
|
|
144
|
+
const { 0: token, index } = m;
|
|
145
|
+
if (IS_MANUAL_CASE.test(token)) {
|
|
146
|
+
result += token;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
result += token.replace(ALPHANUMERIC_PATTERN, (m, i) => {
|
|
150
|
+
if (index > 0 && index + token.length < input.length && smallWords.has(m)) {
|
|
151
|
+
return m;
|
|
152
|
+
}
|
|
153
|
+
if (i > 1 && !WORD_SEPARATORS.has(input.charAt(index + i - 1))) {
|
|
154
|
+
return m;
|
|
155
|
+
}
|
|
156
|
+
return m.charAt(0).toLocaleUpperCase(locale) + m.slice(1);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function composeTextTransformers(...transformers) {
|
|
164
|
+
return text => {
|
|
165
|
+
let result = text;
|
|
166
|
+
for (const transformer of transformers) {
|
|
167
|
+
result = transformer(result);
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const toCamelCase = text => camelCase(text);
|
|
173
|
+
const toCapitalCase = text => capitalCase(text);
|
|
174
|
+
const toConstantCase = text => constantCase(text);
|
|
175
|
+
const toDotCase = text => dotCase(text);
|
|
176
|
+
const toKebabCase = text => kebabCase(text);
|
|
177
|
+
const toLowerCase = text => text.toLocaleLowerCase();
|
|
178
|
+
const toPascalCase = text => pascalCase(text);
|
|
179
|
+
const toPathCase = text => pathCase(text);
|
|
180
|
+
const toSentenceCase = text => sentenceCase(text);
|
|
181
|
+
const toSnakeCase = text => snakeCase(text);
|
|
182
|
+
const toTitleCase = text => titleCase(text);
|
|
183
|
+
const toTrim = text => text.trim();
|
|
184
|
+
const toUpperCase = text => text.toLocaleUpperCase();
|
|
185
|
+
|
|
186
|
+
export { composeTextTransformers, toCamelCase, toCapitalCase, toConstantCase, toDotCase, toKebabCase, toLowerCase, toPascalCase, toPathCase, toSentenceCase, toSnakeCase, toTitleCase, toTrim, toUpperCase };
|
|
187
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text transformer.
|
|
3
|
+
*/
|
|
4
|
+
type ITextTransformer = (text: string) => string;
|
|
5
|
+
/**
|
|
6
|
+
* Compose multiple ITextTransformer into one.
|
|
7
|
+
* @param transformers
|
|
8
|
+
* @returns
|
|
9
|
+
*/
|
|
10
|
+
declare function composeTextTransformers(...transformers: ReadonlyArray<ITextTransformer>): ITextTransformer;
|
|
11
|
+
/**
|
|
12
|
+
* Transform into a string with the separator
|
|
13
|
+
* denoted by the next word capitalized.
|
|
14
|
+
*
|
|
15
|
+
* 'test string' => 'testString'
|
|
16
|
+
*
|
|
17
|
+
* @param text
|
|
18
|
+
* @see https://github.com/blakeembrey/change-case#camelcase
|
|
19
|
+
*/
|
|
20
|
+
declare const toCamelCase: ITextTransformer;
|
|
21
|
+
/**
|
|
22
|
+
* Transform into a space separated string with each word capitalized.
|
|
23
|
+
*
|
|
24
|
+
* 'test string' => 'Test String'
|
|
25
|
+
*
|
|
26
|
+
* @param text
|
|
27
|
+
* @see https://github.com/blakeembrey/change-case#capitalCase
|
|
28
|
+
*/
|
|
29
|
+
declare const toCapitalCase: ITextTransformer;
|
|
30
|
+
/**
|
|
31
|
+
* Transform into upper case string with an underscore between words.
|
|
32
|
+
*
|
|
33
|
+
* 'test string' => 'TEST_STRING'
|
|
34
|
+
*
|
|
35
|
+
* @param text
|
|
36
|
+
* @see https://github.com/blakeembrey/change-case#constantCase
|
|
37
|
+
*/
|
|
38
|
+
declare const toConstantCase: ITextTransformer;
|
|
39
|
+
/**
|
|
40
|
+
* Transform into a lower case string with a period between words.
|
|
41
|
+
*
|
|
42
|
+
* 'test string' => 'test.string'
|
|
43
|
+
*
|
|
44
|
+
* @param text
|
|
45
|
+
* @see https://github.com/blakeembrey/change-case#dotcase
|
|
46
|
+
*/
|
|
47
|
+
declare const toDotCase: ITextTransformer;
|
|
48
|
+
/**
|
|
49
|
+
* Transform into a lower cased string with dashes between words.
|
|
50
|
+
*
|
|
51
|
+
* 'test string' => 'test-string'
|
|
52
|
+
*
|
|
53
|
+
* @param text
|
|
54
|
+
* @see https://github.com/blakeembrey/change-case#paramcase
|
|
55
|
+
*/
|
|
56
|
+
declare const toKebabCase: ITextTransformer;
|
|
57
|
+
/**
|
|
58
|
+
* Transforms the string to lower case.
|
|
59
|
+
*
|
|
60
|
+
* 'TEST STRING' => 'test string'
|
|
61
|
+
*
|
|
62
|
+
* @param text
|
|
63
|
+
* @see https://github.com/blakeembrey/change-case#lowerCase
|
|
64
|
+
*/
|
|
65
|
+
declare const toLowerCase: ITextTransformer;
|
|
66
|
+
/**
|
|
67
|
+
* Transform into a string of capitalized words without separators.
|
|
68
|
+
*
|
|
69
|
+
* 'test string' => 'TestString'
|
|
70
|
+
*
|
|
71
|
+
* @param text
|
|
72
|
+
* @see https://github.com/blakeembrey/change-case#pascalcase
|
|
73
|
+
*/
|
|
74
|
+
declare const toPascalCase: ITextTransformer;
|
|
75
|
+
/**
|
|
76
|
+
* Transform into a lower case string with slashes between words.
|
|
77
|
+
*
|
|
78
|
+
* 'test string' => 'test/string'
|
|
79
|
+
*
|
|
80
|
+
* @param text
|
|
81
|
+
* @see https://github.com/blakeembrey/change-case#pathcase
|
|
82
|
+
*/
|
|
83
|
+
declare const toPathCase: ITextTransformer;
|
|
84
|
+
/**
|
|
85
|
+
* Transform into a lower case with spaces between words,
|
|
86
|
+
* then capitalize the string.
|
|
87
|
+
*
|
|
88
|
+
* 'testString' => 'Test string'
|
|
89
|
+
*
|
|
90
|
+
* @param text
|
|
91
|
+
* @see https://github.com/blakeembrey/change-case#sentencecase
|
|
92
|
+
*/
|
|
93
|
+
declare const toSentenceCase: ITextTransformer;
|
|
94
|
+
/**
|
|
95
|
+
* Transform into a lower case string with underscores between words.
|
|
96
|
+
*
|
|
97
|
+
* 'test string' => 'test_string'
|
|
98
|
+
*
|
|
99
|
+
* @param text
|
|
100
|
+
* @see https://github.com/blakeembrey/change-case#snakeCase
|
|
101
|
+
*/
|
|
102
|
+
declare const toSnakeCase: ITextTransformer;
|
|
103
|
+
/**
|
|
104
|
+
* Transform a string into title case following English rules.
|
|
105
|
+
*
|
|
106
|
+
* 'a simple test' => 'A Simple Test'
|
|
107
|
+
*
|
|
108
|
+
* @param text
|
|
109
|
+
* @see https://github.com/blakeembrey/change-case#titlecase
|
|
110
|
+
*/
|
|
111
|
+
declare const toTitleCase: ITextTransformer;
|
|
112
|
+
/**
|
|
113
|
+
* Perform trim operation
|
|
114
|
+
*
|
|
115
|
+
* ' a simple test ' => 'a simple test'
|
|
116
|
+
*
|
|
117
|
+
* @param text
|
|
118
|
+
* @returns
|
|
119
|
+
*/
|
|
120
|
+
declare const toTrim: ITextTransformer;
|
|
121
|
+
/**
|
|
122
|
+
* Transforms the string to upper case.
|
|
123
|
+
*
|
|
124
|
+
* 'test string' => 'TEST STRING'
|
|
125
|
+
*
|
|
126
|
+
* @param text
|
|
127
|
+
* @see https://github.com/blakeembrey/change-case#upperCase
|
|
128
|
+
*/
|
|
129
|
+
declare const toUpperCase: ITextTransformer;
|
|
130
|
+
|
|
131
|
+
export { type ITextTransformer, composeTextTransformers, toCamelCase, toCapitalCase, toConstantCase, toDotCase, toKebabCase, toLowerCase, toPascalCase, toPathCase, toSentenceCase, toSnakeCase, toTitleCase, toTrim, toUpperCase };
|
|
132
|
+
//# sourceMappingURL=index.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guanghechen/string",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Utilities for processing strings or stringify other type data.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "guanghechen",
|
|
7
|
+
"url": "https://github.com/guanghechen/"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "https://github.com/guanghechen/sora/tree/@guanghechen/string@1.0.0",
|
|
12
|
+
"directory": "packages/string"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/guanghechen/sora/tree/@guanghechen/string@1.0.0/packages/string#readme",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"string",
|
|
17
|
+
"string transformer",
|
|
18
|
+
"string utils"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"source": "./src/index.ts",
|
|
24
|
+
"import": "./lib/esm/index.mjs",
|
|
25
|
+
"require": "./lib/cjs/index.cjs",
|
|
26
|
+
"types": "./lib/types/index.d.ts"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"source": "./src/index.ts",
|
|
30
|
+
"main": "./lib/cjs/index.cjs",
|
|
31
|
+
"module": "./lib/esm/index.mjs",
|
|
32
|
+
"types": "./lib/types/index.d.ts",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">= 18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"lib/",
|
|
39
|
+
"!lib/**/*.map",
|
|
40
|
+
"package.json",
|
|
41
|
+
"CHANGELOG.md",
|
|
42
|
+
"LICENSE",
|
|
43
|
+
"README.md"
|
|
44
|
+
],
|
|
45
|
+
"gitHead": "2723aaa31e8ac85afed5b25760875db429d88563"
|
|
46
|
+
}
|