@synstack/str 1.0.1-alpha.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +1 -0
- package/dist/str.index.cjs +441 -0
- package/dist/str.index.cjs.map +1 -0
- package/dist/str.index.d.cts +261 -0
- package/dist/str.index.d.ts +261 -0
- package/dist/str.index.js +384 -0
- package/dist/str.index.js.map +1 -0
- package/package.json +66 -0
- package/src/str.bundle.ts +16 -0
- package/src/str.chainable.ts +291 -0
- package/src/str.index.ts +2 -0
- package/src/str.lib.ts +186 -0
@@ -0,0 +1,291 @@
|
|
1
|
+
import { Pipeable } from "@synstack/pipe";
|
2
|
+
import * as changeCase from "change-case";
|
3
|
+
import * as lib from "./str.lib";
|
4
|
+
|
5
|
+
export type Stringable = {
|
6
|
+
toString: () => string;
|
7
|
+
};
|
8
|
+
|
9
|
+
export class Str extends Pipeable<Str, string> {
|
10
|
+
public constructor(private readonly text: string) {
|
11
|
+
super();
|
12
|
+
}
|
13
|
+
|
14
|
+
public valueOf(): string {
|
15
|
+
return this.text;
|
16
|
+
}
|
17
|
+
|
18
|
+
public toString() {
|
19
|
+
return this.text;
|
20
|
+
}
|
21
|
+
|
22
|
+
public instanceOf(): Str {
|
23
|
+
return this;
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Remove empty lines at the start of the text but leave whitespace on the first line with content
|
28
|
+
*/
|
29
|
+
public chopEmptyLinesStart() {
|
30
|
+
return new Str(lib.chopEmptyLinesStart(this.text));
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Remove empty lines at the end of the text but leave whitespace on the last line with content
|
35
|
+
*/
|
36
|
+
public chopEmptyLinesEnd() {
|
37
|
+
return new Str(lib.chopEmptyLinesEnd(this.text));
|
38
|
+
}
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Remove all space (\s) characters in lines without content
|
42
|
+
*/
|
43
|
+
public trimEmptyLines() {
|
44
|
+
return new Str(lib.trimEmptyLines(this.text));
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* Remove all spaces (\s) characters at the end of lines
|
49
|
+
*/
|
50
|
+
public trimLinesTrailingSpaces() {
|
51
|
+
return new Str(lib.trimLinesTrailingSpaces(this.text));
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Removes the leading and trailing white space and line terminator characters
|
56
|
+
*/
|
57
|
+
public trim() {
|
58
|
+
return new Str(lib.trim(this.text));
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Removes the leading white space and line terminator characters
|
63
|
+
*/
|
64
|
+
public trimStart() {
|
65
|
+
return new Str(lib.trimStart(this.text));
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Removes the trailing white space and line terminator characters
|
70
|
+
*/
|
71
|
+
public trimEnd() {
|
72
|
+
return new Str(lib.trimEnd(this.text));
|
73
|
+
}
|
74
|
+
|
75
|
+
/**
|
76
|
+
* Split a string into substrings using the specified separator and return them as an array
|
77
|
+
*/
|
78
|
+
public split(separator: string | RegExp, limit?: number) {
|
79
|
+
return lib.split(this.text, separator, limit).map((v) => new Str(v));
|
80
|
+
}
|
81
|
+
|
82
|
+
/**
|
83
|
+
* Add line numbers to a string
|
84
|
+
* @param separator The separator to use between the line number and the line content.
|
85
|
+
* Defaults to ":"
|
86
|
+
*/
|
87
|
+
public addLineNumbers(separator: string = ":") {
|
88
|
+
return new Str(lib.addLineNumbers(this.text, separator));
|
89
|
+
}
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Returns the character at the specified index
|
93
|
+
* @return string or undefined if the index is out of bounds
|
94
|
+
*/
|
95
|
+
public at(index: number) {
|
96
|
+
return this.text.at(index);
|
97
|
+
}
|
98
|
+
|
99
|
+
/**
|
100
|
+
* Returns the length of the string
|
101
|
+
*/
|
102
|
+
public length() {
|
103
|
+
return this.text.length;
|
104
|
+
}
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Indent the string by the specified number of spaces
|
108
|
+
* @param size The number of spaces to indent by
|
109
|
+
* @param char The character to use for indentation. Defaults to " "
|
110
|
+
*/
|
111
|
+
public indent(size: number, char: string = " ") {
|
112
|
+
return new Str(lib.indent(this.text, size, char));
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* Dedent the string by the specified number of spaces
|
117
|
+
* @param indentation The number of spaces to dedent by.
|
118
|
+
* If not provided, it will be calculated automatically based on the maximum indentation in the string.
|
119
|
+
*/
|
120
|
+
public dedent(indentation?: number) {
|
121
|
+
return new Str(lib.dedent(this.text, indentation));
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Chop the string at the start by the specified number of characters
|
126
|
+
*/
|
127
|
+
public chopStart(count: number) {
|
128
|
+
return new Str(lib.chopStart(this.text, count));
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Chop the string at the end by the specified number of characters
|
133
|
+
*/
|
134
|
+
public chopEnd(count: number) {
|
135
|
+
if (count === 0) return this;
|
136
|
+
return new Str(lib.chopEnd(this.text, count));
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Remove successive newlines of the specified repetition or more
|
141
|
+
* @param maxRepeat the maximum number of newlines to allow
|
142
|
+
*/
|
143
|
+
public chopRepeatNewlines(maxRepeat: number) {
|
144
|
+
if (maxRepeat === 0) return this;
|
145
|
+
return new Str(lib.chopRepeatNewlines(this.text, maxRepeat));
|
146
|
+
}
|
147
|
+
|
148
|
+
/**
|
149
|
+
* Take the first n characters of the string
|
150
|
+
*/
|
151
|
+
public takeStart(count: number) {
|
152
|
+
return new Str(lib.takeStart(this.text, count));
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* Take the last n characters of the string
|
157
|
+
*/
|
158
|
+
public takeEnd(count: number) {
|
159
|
+
return new Str(lib.takeEnd(this.text, count));
|
160
|
+
}
|
161
|
+
|
162
|
+
/**
|
163
|
+
* Returns the last line of the string
|
164
|
+
*/
|
165
|
+
public lastLine() {
|
166
|
+
return new Str(lib.lastLine(this.text));
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Returns the first line of the string
|
171
|
+
*/
|
172
|
+
public firstLine() {
|
173
|
+
return new Str(lib.firstLine(this.text));
|
174
|
+
}
|
175
|
+
|
176
|
+
/**
|
177
|
+
* Returns the number of leading spaces in the string
|
178
|
+
*/
|
179
|
+
public leadingSpacesCount() {
|
180
|
+
return lib.leadingSpacesCount(this.text);
|
181
|
+
}
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Returns the indentation level of the string skipping empty lines in the process
|
185
|
+
*/
|
186
|
+
public indentation() {
|
187
|
+
return lib.indentation(this.text);
|
188
|
+
}
|
189
|
+
|
190
|
+
/**
|
191
|
+
* Returns true if the string is empty or contains only whitespace
|
192
|
+
*/
|
193
|
+
public isEmpty() {
|
194
|
+
return lib.isEmpty(this.text);
|
195
|
+
}
|
196
|
+
|
197
|
+
/**
|
198
|
+
* Converts the string to camel case
|
199
|
+
*/
|
200
|
+
public camelCase() {
|
201
|
+
return new Str(changeCase.camelCase(this.text));
|
202
|
+
}
|
203
|
+
|
204
|
+
/**
|
205
|
+
* Converts the string to capital case
|
206
|
+
*/
|
207
|
+
public capitalCase() {
|
208
|
+
return new Str(changeCase.capitalCase(this.text));
|
209
|
+
}
|
210
|
+
|
211
|
+
/**
|
212
|
+
* Converts the string to constant case
|
213
|
+
*/
|
214
|
+
public constantCase() {
|
215
|
+
return new Str(changeCase.constantCase(this.text));
|
216
|
+
}
|
217
|
+
|
218
|
+
/**
|
219
|
+
* Converts the string to dot case
|
220
|
+
*/
|
221
|
+
public dotCase() {
|
222
|
+
return new Str(changeCase.dotCase(this.text));
|
223
|
+
}
|
224
|
+
|
225
|
+
/**
|
226
|
+
* Converts the string to kebab case
|
227
|
+
*/
|
228
|
+
public kebabCase() {
|
229
|
+
return new Str(changeCase.kebabCase(this.text));
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* Converts the string to no case
|
234
|
+
*/
|
235
|
+
public noCase() {
|
236
|
+
return new Str(changeCase.noCase(this.text));
|
237
|
+
}
|
238
|
+
|
239
|
+
/**
|
240
|
+
* Converts the string to pascal case
|
241
|
+
*/
|
242
|
+
public pascalCase() {
|
243
|
+
return new Str(changeCase.pascalCase(this.text));
|
244
|
+
}
|
245
|
+
|
246
|
+
/**
|
247
|
+
* Converts the string to pascal snake case
|
248
|
+
*/
|
249
|
+
public pascalSnakeCase() {
|
250
|
+
return new Str(changeCase.pascalSnakeCase(this.text));
|
251
|
+
}
|
252
|
+
|
253
|
+
/**
|
254
|
+
* Converts the string to path case
|
255
|
+
*/
|
256
|
+
public pathCase() {
|
257
|
+
return new Str(changeCase.pathCase(this.text));
|
258
|
+
}
|
259
|
+
|
260
|
+
/**
|
261
|
+
* Converts the string to sentence case
|
262
|
+
*/
|
263
|
+
public sentenceCase() {
|
264
|
+
return new Str(changeCase.sentenceCase(this.text));
|
265
|
+
}
|
266
|
+
|
267
|
+
/**
|
268
|
+
* Converts the string to snake case
|
269
|
+
*/
|
270
|
+
public snakeCase() {
|
271
|
+
return new Str(changeCase.snakeCase(this.text));
|
272
|
+
}
|
273
|
+
|
274
|
+
/**
|
275
|
+
* Converts the string to train case
|
276
|
+
*/
|
277
|
+
public trainCase() {
|
278
|
+
return new Str(changeCase.trainCase(this.text));
|
279
|
+
}
|
280
|
+
|
281
|
+
/**
|
282
|
+
* Shorthand for `.toString()`
|
283
|
+
*/
|
284
|
+
public get str() {
|
285
|
+
return this.toString();
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
export const str = (text: Stringable) => {
|
290
|
+
return new Str(text.toString());
|
291
|
+
};
|
package/src/str.index.ts
ADDED
package/src/str.lib.ts
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
/**
|
2
|
+
* Remove empty lines at the start of the text but leave whitespace on the first line with content
|
3
|
+
*/
|
4
|
+
export const chopEmptyLinesStart = (text: string) => {
|
5
|
+
return text.replace(/^(\s*\n)+/, "");
|
6
|
+
};
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Remove empty lines at the end of the text but leave whitespace on the last line with content
|
10
|
+
*/
|
11
|
+
export const chopEmptyLinesEnd = (text: string) => {
|
12
|
+
return text.replace(/(\n\s*)+$/, "");
|
13
|
+
};
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Remove all space (\s) characters in lines without content
|
17
|
+
*/
|
18
|
+
export const trimEmptyLines = (text: string) => {
|
19
|
+
return text.replace(/(^|\n)\s+(\n|$)/g, "$1$2");
|
20
|
+
};
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Remove all space (\s) characters at the end of lines
|
24
|
+
*/
|
25
|
+
export const trimLinesTrailingSpaces = (text: string) => {
|
26
|
+
return text.replace(/ +(\n|$)/g, "$1");
|
27
|
+
};
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Removes the leading and trailing white space and line terminator characters
|
31
|
+
*/
|
32
|
+
export const trim = (text: string) => {
|
33
|
+
return text.trim();
|
34
|
+
};
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Removes the leading white space and line terminator characters
|
38
|
+
*/
|
39
|
+
export const trimStart = (text: string) => {
|
40
|
+
return text.trimStart();
|
41
|
+
};
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Removes the trailing white space and line terminator characters
|
45
|
+
*/
|
46
|
+
export const trimEnd = (text: string) => {
|
47
|
+
return text.trimEnd();
|
48
|
+
};
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Split a string into substrings using the specified separator and return them as an array
|
52
|
+
*/
|
53
|
+
export const split = (
|
54
|
+
text: string,
|
55
|
+
separator: string | RegExp,
|
56
|
+
limit?: number,
|
57
|
+
) => {
|
58
|
+
return text.split(separator, limit);
|
59
|
+
};
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Add line numbers to a string
|
63
|
+
* @param text The string to add line numbers to
|
64
|
+
* @param separator The separator to use between the line number and the line content.
|
65
|
+
* Defaults to ":"
|
66
|
+
*/
|
67
|
+
export const addLineNumbers = (text: string, separator: string = ":") => {
|
68
|
+
return text
|
69
|
+
.split("\n")
|
70
|
+
.map((line, index) => `${index}${separator}${line}`)
|
71
|
+
.join("\n");
|
72
|
+
};
|
73
|
+
|
74
|
+
/**
|
75
|
+
* Returns the indentation level of the string skipping empty lines in the process
|
76
|
+
*/
|
77
|
+
export const indentation = (text: string) => {
|
78
|
+
return (
|
79
|
+
text.split("\n").reduce((acc: number | null, line) => {
|
80
|
+
if (line.trim() === "") return acc;
|
81
|
+
const indentation = leadingSpacesCount(line);
|
82
|
+
if (acc === null) return indentation;
|
83
|
+
return Math.min(acc, indentation);
|
84
|
+
}, null) ?? 0
|
85
|
+
);
|
86
|
+
};
|
87
|
+
|
88
|
+
/**
|
89
|
+
* Indent the string by the specified number of spaces
|
90
|
+
* @param size The number of spaces to indent by
|
91
|
+
* @param char The character to use for indentation. Defaults to " "
|
92
|
+
*/
|
93
|
+
export const indent = (text: string, size: number, char: string = " ") => {
|
94
|
+
if (size === 0) return text;
|
95
|
+
|
96
|
+
const indentStr = char.repeat(size);
|
97
|
+
return text
|
98
|
+
.split("\n")
|
99
|
+
.map((line) => indentStr + line)
|
100
|
+
.join("\n");
|
101
|
+
};
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Dedent the string by the specified number of spaces
|
105
|
+
* @param indentation The number of spaces to dedent by.
|
106
|
+
* If not provided, it will be calculated automatically based on the maximum indentation in the string.
|
107
|
+
*/
|
108
|
+
export const dedent = (text: string, size?: number) => {
|
109
|
+
const _size = size ?? indentation(text);
|
110
|
+
if (_size === 0) return text;
|
111
|
+
const regex = new RegExp(`^\\s{1,${_size}}`);
|
112
|
+
return text
|
113
|
+
.split("\n")
|
114
|
+
.map((line) => line.replace(regex, ""))
|
115
|
+
.join("\n");
|
116
|
+
};
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Chop the string at the end by the specified number of characters
|
120
|
+
*/
|
121
|
+
export const chopEnd = (text: string, count: number) => {
|
122
|
+
if (count === 0) return text;
|
123
|
+
return text.slice(0, -count);
|
124
|
+
};
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Chop the string at the start by the specified number of characters
|
128
|
+
*/
|
129
|
+
export const chopStart = (text: string, count: number) => {
|
130
|
+
if (count === 0) return text;
|
131
|
+
return text.slice(count);
|
132
|
+
};
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Remove successive newlines of the specified repetition or more
|
136
|
+
* @param maxRepeat the maximum number of newlines to allow
|
137
|
+
*/
|
138
|
+
export const chopRepeatNewlines = (text: string, maxRepeat: number) => {
|
139
|
+
if (maxRepeat === 0) return text;
|
140
|
+
return text.replace(
|
141
|
+
new RegExp(`\n{${maxRepeat + 1},}`, "g"),
|
142
|
+
"\n".repeat(maxRepeat),
|
143
|
+
);
|
144
|
+
};
|
145
|
+
|
146
|
+
/**
|
147
|
+
* Take the first n characters of the string
|
148
|
+
*/
|
149
|
+
export const takeStart = (text: string, count: number) => {
|
150
|
+
return text.slice(0, count);
|
151
|
+
};
|
152
|
+
|
153
|
+
/**
|
154
|
+
* Take the last n characters of the string
|
155
|
+
*/
|
156
|
+
export const takeEnd = (text: string, count: number) => {
|
157
|
+
return text.slice(-count);
|
158
|
+
};
|
159
|
+
|
160
|
+
/**
|
161
|
+
* Returns the last line of the string
|
162
|
+
*/
|
163
|
+
export const lastLine = (text: string) => {
|
164
|
+
return text.split("\n").at(-1) ?? "";
|
165
|
+
};
|
166
|
+
|
167
|
+
/**
|
168
|
+
* Returns the first line of the string
|
169
|
+
*/
|
170
|
+
export const firstLine = (text: string) => {
|
171
|
+
return text.split("\n").at(0) ?? "";
|
172
|
+
};
|
173
|
+
|
174
|
+
/**
|
175
|
+
* Returns the number of leading spaces in the string
|
176
|
+
*/
|
177
|
+
export const leadingSpacesCount = (text: string) => {
|
178
|
+
return text.match(/^\s+/)?.at(0)?.length ?? 0;
|
179
|
+
};
|
180
|
+
|
181
|
+
/**
|
182
|
+
* Returns true if the string is empty or contains only whitespace
|
183
|
+
*/
|
184
|
+
export const isEmpty = (text: string) => {
|
185
|
+
return text.trim() === "";
|
186
|
+
};
|