complete-common 1.0.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/LICENSE +9 -0
- package/README.md +7 -0
- package/dist/index.cjs +535 -0
- package/dist/index.d.cts +705 -0
- package/dist/index.d.mts +705 -0
- package/dist/index.d.ts +705 -0
- package/dist/index.mjs +463 -0
- package/package.json +36 -0
- package/src/constants.ts +3 -0
- package/src/functions/array.ts +209 -0
- package/src/functions/enums.ts +105 -0
- package/src/functions/map.ts +90 -0
- package/src/functions/math.ts +9 -0
- package/src/functions/object.ts +27 -0
- package/src/functions/random.ts +43 -0
- package/src/functions/set.ts +131 -0
- package/src/functions/sort.ts +18 -0
- package/src/functions/string.test.ts +42 -0
- package/src/functions/string.ts +304 -0
- package/src/functions/tuple.ts +31 -0
- package/src/functions/types.ts +15 -0
- package/src/functions/utils.test.ts +910 -0
- package/src/functions/utils.ts +238 -0
- package/src/index.ts +27 -0
- package/src/types/AddSubtract.ts +19 -0
- package/src/types/CompositionTypeSatisfiesEnum.ts +67 -0
- package/src/types/ERange.ts +15 -0
- package/src/types/IRange.ts +16 -0
- package/src/types/Immutable.ts +28 -0
- package/src/types/NaturalNumbersLessThan.ts +12 -0
- package/src/types/NaturalNumbersLessThanOrEqualTo.ts +14 -0
- package/src/types/ObjectValues.ts +1 -0
- package/src/types/ReadonlyMap.ts +12 -0
- package/src/types/ReadonlyRecord.ts +3 -0
- package/src/types/ReadonlySet.ts +9 -0
- package/src/types/Tuple.ts +14 -0
- package/src/types/WidenLiteral.ts +11 -0
- package/src/types/Writeable.ts +6 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright The Complete Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# complete-common
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/complete-common)
|
|
4
|
+
|
|
5
|
+
This package contains helper functions for a typical TypeScript project, such as [`iRange`](TODO).
|
|
6
|
+
|
|
7
|
+
For more information about `complete`, see the [official website](https://complete-ts.github.io/).
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const SECOND_IN_MILLISECONDS = 1e3;
|
|
4
|
+
const MINUTE_IN_MILLISECONDS = 60 * SECOND_IN_MILLISECONDS;
|
|
5
|
+
const HOUR_IN_MILLISECONDS = 60 * MINUTE_IN_MILLISECONDS;
|
|
6
|
+
|
|
7
|
+
const ReadonlySet = Set;
|
|
8
|
+
|
|
9
|
+
function getRandomInt(min, max, exceptions = []) {
|
|
10
|
+
min = Math.ceil(min);
|
|
11
|
+
max = Math.floor(max);
|
|
12
|
+
if (min > max) {
|
|
13
|
+
const oldMin = min;
|
|
14
|
+
const oldMax = max;
|
|
15
|
+
min = oldMax;
|
|
16
|
+
max = oldMin;
|
|
17
|
+
}
|
|
18
|
+
const exceptionsSet = new ReadonlySet(exceptions);
|
|
19
|
+
let randomInt;
|
|
20
|
+
do {
|
|
21
|
+
randomInt = Math.floor(Math.random() * (max - min + 1)) + min;
|
|
22
|
+
} while (exceptionsSet.has(randomInt));
|
|
23
|
+
return randomInt;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const FLOAT_REGEX = /^-?\d*\.?\d+$/;
|
|
27
|
+
const INTEGER_REGEX = /^-?\d+$/;
|
|
28
|
+
function assertDefined(value, ...[msg]) {
|
|
29
|
+
if (value === void 0) {
|
|
30
|
+
throw new TypeError(msg);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function assertNotNull(value, ...[msg]) {
|
|
34
|
+
if (value === null) {
|
|
35
|
+
throw new TypeError(msg);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function* eRange(start, end, increment = 1) {
|
|
39
|
+
if (end === void 0) {
|
|
40
|
+
yield* eRange(0, start, increment);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
for (let i = start; i < end; i += increment) {
|
|
44
|
+
yield i;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function* iRange(start, end, increment = 1) {
|
|
48
|
+
if (end === void 0) {
|
|
49
|
+
yield* iRange(0, start, increment);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const exclusiveEnd = end + 1;
|
|
53
|
+
yield* eRange(start, exclusiveEnd, increment);
|
|
54
|
+
}
|
|
55
|
+
function isKeyOf(key, target) {
|
|
56
|
+
return key in target;
|
|
57
|
+
}
|
|
58
|
+
function noop() {
|
|
59
|
+
}
|
|
60
|
+
function parseFloatSafe(string) {
|
|
61
|
+
if (typeof string !== "string") {
|
|
62
|
+
return void 0;
|
|
63
|
+
}
|
|
64
|
+
const trimmedString = string.trim();
|
|
65
|
+
if (FLOAT_REGEX.exec(trimmedString) === null) {
|
|
66
|
+
return void 0;
|
|
67
|
+
}
|
|
68
|
+
const number = Number.parseFloat(trimmedString);
|
|
69
|
+
return Number.isNaN(number) ? void 0 : number;
|
|
70
|
+
}
|
|
71
|
+
function parseIntSafe(string) {
|
|
72
|
+
if (typeof string !== "string") {
|
|
73
|
+
return void 0;
|
|
74
|
+
}
|
|
75
|
+
const trimmedString = string.trim();
|
|
76
|
+
if (INTEGER_REGEX.exec(trimmedString) === null) {
|
|
77
|
+
return void 0;
|
|
78
|
+
}
|
|
79
|
+
const number = Number.parseInt(trimmedString, 10);
|
|
80
|
+
return Number.isNaN(number) ? void 0 : number;
|
|
81
|
+
}
|
|
82
|
+
function repeat(num, func) {
|
|
83
|
+
for (let i = 0; i < num; i++) {
|
|
84
|
+
func(i);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function todo(...args) {
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function arrayCopyTwoDimensional(array) {
|
|
91
|
+
const copiedArray = [];
|
|
92
|
+
for (const subArray of array) {
|
|
93
|
+
copiedArray.push([...subArray]);
|
|
94
|
+
}
|
|
95
|
+
return copiedArray;
|
|
96
|
+
}
|
|
97
|
+
function arrayEquals(array1, array2) {
|
|
98
|
+
if (array1.length !== array2.length) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return array1.every((array1Element, i) => {
|
|
102
|
+
const array2Element = array2[i];
|
|
103
|
+
return array1Element === array2Element;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
function arrayRemove(originalArray, ...elementsToRemove) {
|
|
107
|
+
const elementsToRemoveSet = new ReadonlySet(elementsToRemove);
|
|
108
|
+
const array = [];
|
|
109
|
+
for (const element of originalArray) {
|
|
110
|
+
if (!elementsToRemoveSet.has(element)) {
|
|
111
|
+
array.push(element);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return array;
|
|
115
|
+
}
|
|
116
|
+
function arrayRemoveInPlace(array, ...elementsToRemove) {
|
|
117
|
+
const removedElements = [];
|
|
118
|
+
for (const element of elementsToRemove) {
|
|
119
|
+
const index = array.indexOf(element);
|
|
120
|
+
if (index > -1) {
|
|
121
|
+
const removedElement = array.splice(index, 1);
|
|
122
|
+
removedElements.push(...removedElement);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return removedElements;
|
|
126
|
+
}
|
|
127
|
+
function emptyArray(array) {
|
|
128
|
+
array.splice(0, array.length);
|
|
129
|
+
}
|
|
130
|
+
function filterMap(array, func) {
|
|
131
|
+
const filteredArray = [];
|
|
132
|
+
for (const element of array) {
|
|
133
|
+
const newElement = func(element);
|
|
134
|
+
if (newElement !== void 0) {
|
|
135
|
+
filteredArray.push(newElement);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return filteredArray;
|
|
139
|
+
}
|
|
140
|
+
function getRandomArrayElement(array, exceptions = []) {
|
|
141
|
+
if (array.length === 0) {
|
|
142
|
+
throw new Error(
|
|
143
|
+
"Failed to get a random array element since the provided array is empty."
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
const arrayToUse = exceptions.length > 0 ? arrayRemove(array, ...exceptions) : array;
|
|
147
|
+
const randomIndex = getRandomArrayIndex(arrayToUse);
|
|
148
|
+
const randomElement = arrayToUse[randomIndex];
|
|
149
|
+
assertDefined(
|
|
150
|
+
randomElement,
|
|
151
|
+
`Failed to get a random array element since the random index of ${randomIndex} was not valid.`
|
|
152
|
+
);
|
|
153
|
+
return randomElement;
|
|
154
|
+
}
|
|
155
|
+
function getRandomArrayIndex(array, exceptions = []) {
|
|
156
|
+
if (array.length === 0) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
"Failed to get a random array index since the provided array is empty."
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
return getRandomInt(0, array.length - 1, exceptions);
|
|
162
|
+
}
|
|
163
|
+
function includes(array, searchElement) {
|
|
164
|
+
const widenedArray = array;
|
|
165
|
+
return widenedArray.includes(searchElement);
|
|
166
|
+
}
|
|
167
|
+
function isArray(arg) {
|
|
168
|
+
return Array.isArray(arg);
|
|
169
|
+
}
|
|
170
|
+
function newArray(length, value) {
|
|
171
|
+
return Array.from({ length }, () => value);
|
|
172
|
+
}
|
|
173
|
+
function sumArray(array) {
|
|
174
|
+
return array.reduce((accumulator, element) => accumulator + element, 0);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function getEnumEntries(transpiledEnum) {
|
|
178
|
+
const entries = Object.entries(transpiledEnum);
|
|
179
|
+
const numberEntries = entries.filter(
|
|
180
|
+
([_key, value]) => typeof value === "number"
|
|
181
|
+
);
|
|
182
|
+
const entriesToReturn = numberEntries.length > 0 ? numberEntries : entries;
|
|
183
|
+
return entriesToReturn;
|
|
184
|
+
}
|
|
185
|
+
function getEnumKeys(transpiledEnum) {
|
|
186
|
+
const enumEntries = getEnumEntries(transpiledEnum);
|
|
187
|
+
return enumEntries.map(([key, _value]) => key);
|
|
188
|
+
}
|
|
189
|
+
function getEnumValues(transpiledEnum) {
|
|
190
|
+
const enumEntries = getEnumEntries(transpiledEnum);
|
|
191
|
+
return enumEntries.map(([_key, value]) => value);
|
|
192
|
+
}
|
|
193
|
+
function interfaceSatisfiesEnum() {
|
|
194
|
+
}
|
|
195
|
+
function isEnumValue(value, transpiledEnum, set) {
|
|
196
|
+
if (set !== void 0) {
|
|
197
|
+
return set.has(value);
|
|
198
|
+
}
|
|
199
|
+
const enumValues = getEnumValues(transpiledEnum);
|
|
200
|
+
return enumValues.includes(value);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function mapFilter(map, predicate) {
|
|
204
|
+
const array = [];
|
|
205
|
+
for (const value of map.values()) {
|
|
206
|
+
const match = predicate(value);
|
|
207
|
+
if (match) {
|
|
208
|
+
array.push(value);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return array;
|
|
212
|
+
}
|
|
213
|
+
function mapFind(map, predicate) {
|
|
214
|
+
for (const value of map.values()) {
|
|
215
|
+
const match = predicate(value);
|
|
216
|
+
if (match) {
|
|
217
|
+
return value;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return void 0;
|
|
221
|
+
}
|
|
222
|
+
function objectToMap(object) {
|
|
223
|
+
const map = /* @__PURE__ */ new Map();
|
|
224
|
+
for (const [key, value] of Object.entries(object)) {
|
|
225
|
+
map.set(key, value);
|
|
226
|
+
}
|
|
227
|
+
return map;
|
|
228
|
+
}
|
|
229
|
+
function objectToReadonlyMap(object) {
|
|
230
|
+
return objectToMap(object);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function clamp(num, min, max) {
|
|
234
|
+
return Math.max(min, Math.min(num, max));
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function objectFilter(object, predicate) {
|
|
238
|
+
const array = [];
|
|
239
|
+
for (const key in object) {
|
|
240
|
+
const value = object[key];
|
|
241
|
+
const match = predicate(value);
|
|
242
|
+
if (match) {
|
|
243
|
+
array.push(value);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return array;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function addSetsToSet(mainSet, ...setsToAdd) {
|
|
250
|
+
for (const set of setsToAdd) {
|
|
251
|
+
for (const value of set) {
|
|
252
|
+
mainSet.add(value);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function combineSets(...sets) {
|
|
257
|
+
const newSet = /* @__PURE__ */ new Set();
|
|
258
|
+
for (const set of sets) {
|
|
259
|
+
for (const value of set) {
|
|
260
|
+
newSet.add(value);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return newSet;
|
|
264
|
+
}
|
|
265
|
+
function copySet(oldSet) {
|
|
266
|
+
const newSet = /* @__PURE__ */ new Set();
|
|
267
|
+
for (const value of oldSet) {
|
|
268
|
+
newSet.add(value);
|
|
269
|
+
}
|
|
270
|
+
return newSet;
|
|
271
|
+
}
|
|
272
|
+
function objectKeysToReadonlySet(object) {
|
|
273
|
+
return objectKeysToSet(object);
|
|
274
|
+
}
|
|
275
|
+
function objectKeysToSet(object) {
|
|
276
|
+
const set = /* @__PURE__ */ new Set();
|
|
277
|
+
for (const key of Object.keys(object)) {
|
|
278
|
+
set.add(key);
|
|
279
|
+
}
|
|
280
|
+
return set;
|
|
281
|
+
}
|
|
282
|
+
function objectValuesToReadonlySet(object) {
|
|
283
|
+
return objectValuesToSet(object);
|
|
284
|
+
}
|
|
285
|
+
function objectValuesToSet(object) {
|
|
286
|
+
const set = /* @__PURE__ */ new Set();
|
|
287
|
+
for (const key of Object.values(object)) {
|
|
288
|
+
set.add(key);
|
|
289
|
+
}
|
|
290
|
+
return set;
|
|
291
|
+
}
|
|
292
|
+
function setAdd(set, ...elements) {
|
|
293
|
+
for (const element of elements) {
|
|
294
|
+
set.add(element);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function setHas(set, ...elements) {
|
|
298
|
+
return elements.some((element) => set.has(element));
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function sortCaseInsensitive(array) {
|
|
302
|
+
const newArray = [...array];
|
|
303
|
+
newArray.sort(
|
|
304
|
+
(a, b) => a.localeCompare(b, void 0, {
|
|
305
|
+
sensitivity: "base"
|
|
306
|
+
})
|
|
307
|
+
);
|
|
308
|
+
return newArray;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const DIACRITIC_REGEX = /\p{Diacritic}/u;
|
|
312
|
+
const EMOJI_REGEX = /(\p{Extended_Pictographic}|\p{Emoji_Component})/u;
|
|
313
|
+
const FIRST_LETTER_CAPITALIZED_REGEX = /^\p{Lu}/u;
|
|
314
|
+
const KEBAB_CASE_REGEX = /^([a-z](?!\d)|\d(?![a-z]))+(-?([a-z](?!\d)|\d(?![a-z])))*$|^$/;
|
|
315
|
+
const SEMANTIC_VERSION_REGEX = /^v*(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)/;
|
|
316
|
+
const WHITESPACE_REGEX = /\s/g;
|
|
317
|
+
function capitalizeFirstLetter(string) {
|
|
318
|
+
if (string === "") {
|
|
319
|
+
return string;
|
|
320
|
+
}
|
|
321
|
+
const firstCharacter = string.charAt(0);
|
|
322
|
+
const capitalizedFirstLetter = firstCharacter.toUpperCase();
|
|
323
|
+
const restOfString = string.slice(1);
|
|
324
|
+
return `${capitalizedFirstLetter}${restOfString}`;
|
|
325
|
+
}
|
|
326
|
+
function escapeHTMLCharacters(string) {
|
|
327
|
+
return string.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
328
|
+
}
|
|
329
|
+
function getNumConsecutiveDiacritics(string) {
|
|
330
|
+
const normalizedString = string.normalize("NFD");
|
|
331
|
+
let numConsecutiveDiacritic = 0;
|
|
332
|
+
let maxConsecutiveDiacritic = 0;
|
|
333
|
+
for (const character of normalizedString) {
|
|
334
|
+
if (hasDiacritic(character)) {
|
|
335
|
+
numConsecutiveDiacritic++;
|
|
336
|
+
if (numConsecutiveDiacritic > maxConsecutiveDiacritic) {
|
|
337
|
+
maxConsecutiveDiacritic = numConsecutiveDiacritic;
|
|
338
|
+
}
|
|
339
|
+
} else {
|
|
340
|
+
numConsecutiveDiacritic = 0;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return maxConsecutiveDiacritic;
|
|
344
|
+
}
|
|
345
|
+
function hasDiacritic(string) {
|
|
346
|
+
const normalizedString = string.normalize("NFD");
|
|
347
|
+
return DIACRITIC_REGEX.test(normalizedString);
|
|
348
|
+
}
|
|
349
|
+
function hasEmoji(string) {
|
|
350
|
+
return EMOJI_REGEX.test(string);
|
|
351
|
+
}
|
|
352
|
+
function hasWhitespace(string) {
|
|
353
|
+
return WHITESPACE_REGEX.test(string);
|
|
354
|
+
}
|
|
355
|
+
function isFirstLetterCapitalized(string) {
|
|
356
|
+
return FIRST_LETTER_CAPITALIZED_REGEX.test(string);
|
|
357
|
+
}
|
|
358
|
+
function isKebabCase(string) {
|
|
359
|
+
return KEBAB_CASE_REGEX.test(string);
|
|
360
|
+
}
|
|
361
|
+
function isSemanticVersion(versionString) {
|
|
362
|
+
const match = versionString.match(SEMANTIC_VERSION_REGEX);
|
|
363
|
+
return match !== null;
|
|
364
|
+
}
|
|
365
|
+
function kebabCaseToCamelCase(string) {
|
|
366
|
+
return string.replaceAll(/-./g, (match) => {
|
|
367
|
+
const firstLetterOfWord = match[1];
|
|
368
|
+
return firstLetterOfWord === void 0 ? "" : firstLetterOfWord.toUpperCase();
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
function normalizeString(string) {
|
|
372
|
+
let sanitizedString = string;
|
|
373
|
+
sanitizedString = removeNonPrintableCharacters(sanitizedString);
|
|
374
|
+
sanitizedString = sanitizedString.replaceAll("\n\r", "\n");
|
|
375
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zl}/gu, "\n");
|
|
376
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zp}/gu, "\n");
|
|
377
|
+
sanitizedString = sanitizedString.replaceAll(/\p{Zs}/gu, " ");
|
|
378
|
+
sanitizedString = sanitizedString.trim();
|
|
379
|
+
return sanitizedString;
|
|
380
|
+
}
|
|
381
|
+
function parseSemanticVersion(versionString) {
|
|
382
|
+
const match = versionString.match(SEMANTIC_VERSION_REGEX);
|
|
383
|
+
if (match === null || match.groups === void 0) {
|
|
384
|
+
return void 0;
|
|
385
|
+
}
|
|
386
|
+
const { major, minor, patch } = match.groups;
|
|
387
|
+
if (major === void 0 || minor === void 0 || patch === void 0) {
|
|
388
|
+
return void 0;
|
|
389
|
+
}
|
|
390
|
+
const majorVersion = parseIntSafe(major);
|
|
391
|
+
const minorVersion = parseIntSafe(minor);
|
|
392
|
+
const patchVersion = parseIntSafe(patch);
|
|
393
|
+
if (majorVersion === void 0 || minorVersion === void 0 || patchVersion === void 0) {
|
|
394
|
+
return void 0;
|
|
395
|
+
}
|
|
396
|
+
return { majorVersion, minorVersion, patchVersion };
|
|
397
|
+
}
|
|
398
|
+
function removeLinesBetweenMarkers(string, marker) {
|
|
399
|
+
const lines = string.split("\n");
|
|
400
|
+
const newLines = [];
|
|
401
|
+
let skippingLines = false;
|
|
402
|
+
for (const line of lines) {
|
|
403
|
+
if (line.includes(`${marker}-start`)) {
|
|
404
|
+
skippingLines = true;
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
if (line.includes(`${marker}-end`)) {
|
|
408
|
+
skippingLines = false;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (!skippingLines) {
|
|
412
|
+
newLines.push(line);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return newLines.join("\n");
|
|
416
|
+
}
|
|
417
|
+
function removeLinesMatching(string, match) {
|
|
418
|
+
const lines = string.split("\n");
|
|
419
|
+
const newLines = lines.filter((line) => !line.includes(match));
|
|
420
|
+
return newLines.join("\n");
|
|
421
|
+
}
|
|
422
|
+
function removeNonPrintableCharacters(string) {
|
|
423
|
+
return string.replaceAll(/\p{C}/gu, "");
|
|
424
|
+
}
|
|
425
|
+
function removeWhitespace(string) {
|
|
426
|
+
return string.replaceAll(WHITESPACE_REGEX, "");
|
|
427
|
+
}
|
|
428
|
+
function trimPrefix(string, prefix, trimAll = false) {
|
|
429
|
+
if (trimAll) {
|
|
430
|
+
const regExp = new RegExp(`^${prefix}+`, "g");
|
|
431
|
+
return string.replaceAll(regExp, "");
|
|
432
|
+
}
|
|
433
|
+
if (!string.startsWith(prefix)) {
|
|
434
|
+
return string;
|
|
435
|
+
}
|
|
436
|
+
return string.slice(prefix.length);
|
|
437
|
+
}
|
|
438
|
+
function trimSuffix(string, prefix) {
|
|
439
|
+
if (!string.endsWith(prefix)) {
|
|
440
|
+
return string;
|
|
441
|
+
}
|
|
442
|
+
const endCharacter = string.length - prefix.length;
|
|
443
|
+
return string.slice(0, endCharacter);
|
|
444
|
+
}
|
|
445
|
+
function truncateString(string, maxLength) {
|
|
446
|
+
if (string.length <= maxLength) {
|
|
447
|
+
return string;
|
|
448
|
+
}
|
|
449
|
+
return string.slice(0, maxLength);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function* tupleEntries(tuple) {
|
|
453
|
+
yield* tuple.entries();
|
|
454
|
+
}
|
|
455
|
+
function* tupleKeys(tuple) {
|
|
456
|
+
yield* tuple.keys();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function isObject(variable) {
|
|
460
|
+
return typeof variable === "object" && variable !== null && !Array.isArray(variable);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const ReadonlyMap = Map;
|
|
464
|
+
|
|
465
|
+
exports.HOUR_IN_MILLISECONDS = HOUR_IN_MILLISECONDS;
|
|
466
|
+
exports.MINUTE_IN_MILLISECONDS = MINUTE_IN_MILLISECONDS;
|
|
467
|
+
exports.ReadonlyMap = ReadonlyMap;
|
|
468
|
+
exports.ReadonlySet = ReadonlySet;
|
|
469
|
+
exports.SECOND_IN_MILLISECONDS = SECOND_IN_MILLISECONDS;
|
|
470
|
+
exports.addSetsToSet = addSetsToSet;
|
|
471
|
+
exports.arrayCopyTwoDimensional = arrayCopyTwoDimensional;
|
|
472
|
+
exports.arrayEquals = arrayEquals;
|
|
473
|
+
exports.arrayRemove = arrayRemove;
|
|
474
|
+
exports.arrayRemoveInPlace = arrayRemoveInPlace;
|
|
475
|
+
exports.assertDefined = assertDefined;
|
|
476
|
+
exports.assertNotNull = assertNotNull;
|
|
477
|
+
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
478
|
+
exports.clamp = clamp;
|
|
479
|
+
exports.combineSets = combineSets;
|
|
480
|
+
exports.copySet = copySet;
|
|
481
|
+
exports.eRange = eRange;
|
|
482
|
+
exports.emptyArray = emptyArray;
|
|
483
|
+
exports.escapeHTMLCharacters = escapeHTMLCharacters;
|
|
484
|
+
exports.filterMap = filterMap;
|
|
485
|
+
exports.getEnumEntries = getEnumEntries;
|
|
486
|
+
exports.getEnumKeys = getEnumKeys;
|
|
487
|
+
exports.getEnumValues = getEnumValues;
|
|
488
|
+
exports.getNumConsecutiveDiacritics = getNumConsecutiveDiacritics;
|
|
489
|
+
exports.getRandomArrayElement = getRandomArrayElement;
|
|
490
|
+
exports.getRandomArrayIndex = getRandomArrayIndex;
|
|
491
|
+
exports.getRandomInt = getRandomInt;
|
|
492
|
+
exports.hasDiacritic = hasDiacritic;
|
|
493
|
+
exports.hasEmoji = hasEmoji;
|
|
494
|
+
exports.hasWhitespace = hasWhitespace;
|
|
495
|
+
exports.iRange = iRange;
|
|
496
|
+
exports.includes = includes;
|
|
497
|
+
exports.interfaceSatisfiesEnum = interfaceSatisfiesEnum;
|
|
498
|
+
exports.isArray = isArray;
|
|
499
|
+
exports.isEnumValue = isEnumValue;
|
|
500
|
+
exports.isFirstLetterCapitalized = isFirstLetterCapitalized;
|
|
501
|
+
exports.isKebabCase = isKebabCase;
|
|
502
|
+
exports.isKeyOf = isKeyOf;
|
|
503
|
+
exports.isObject = isObject;
|
|
504
|
+
exports.isSemanticVersion = isSemanticVersion;
|
|
505
|
+
exports.kebabCaseToCamelCase = kebabCaseToCamelCase;
|
|
506
|
+
exports.mapFilter = mapFilter;
|
|
507
|
+
exports.mapFind = mapFind;
|
|
508
|
+
exports.newArray = newArray;
|
|
509
|
+
exports.noop = noop;
|
|
510
|
+
exports.normalizeString = normalizeString;
|
|
511
|
+
exports.objectFilter = objectFilter;
|
|
512
|
+
exports.objectKeysToReadonlySet = objectKeysToReadonlySet;
|
|
513
|
+
exports.objectKeysToSet = objectKeysToSet;
|
|
514
|
+
exports.objectToMap = objectToMap;
|
|
515
|
+
exports.objectToReadonlyMap = objectToReadonlyMap;
|
|
516
|
+
exports.objectValuesToReadonlySet = objectValuesToReadonlySet;
|
|
517
|
+
exports.objectValuesToSet = objectValuesToSet;
|
|
518
|
+
exports.parseFloatSafe = parseFloatSafe;
|
|
519
|
+
exports.parseIntSafe = parseIntSafe;
|
|
520
|
+
exports.parseSemanticVersion = parseSemanticVersion;
|
|
521
|
+
exports.removeLinesBetweenMarkers = removeLinesBetweenMarkers;
|
|
522
|
+
exports.removeLinesMatching = removeLinesMatching;
|
|
523
|
+
exports.removeNonPrintableCharacters = removeNonPrintableCharacters;
|
|
524
|
+
exports.removeWhitespace = removeWhitespace;
|
|
525
|
+
exports.repeat = repeat;
|
|
526
|
+
exports.setAdd = setAdd;
|
|
527
|
+
exports.setHas = setHas;
|
|
528
|
+
exports.sortCaseInsensitive = sortCaseInsensitive;
|
|
529
|
+
exports.sumArray = sumArray;
|
|
530
|
+
exports.todo = todo;
|
|
531
|
+
exports.trimPrefix = trimPrefix;
|
|
532
|
+
exports.trimSuffix = trimSuffix;
|
|
533
|
+
exports.truncateString = truncateString;
|
|
534
|
+
exports.tupleEntries = tupleEntries;
|
|
535
|
+
exports.tupleKeys = tupleKeys;
|