@controlium/utils 0.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 +661 -0
- package/README.md +10 -0
- package/dist/cjs/detokeniser/detokeniser.js +1135 -0
- package/dist/cjs/index.js +14 -0
- package/dist/cjs/jsonUtils/jsonUtils.js +460 -0
- package/dist/cjs/logger/logger.js +863 -0
- package/dist/cjs/logger/logger.spec.js +875 -0
- package/dist/cjs/logger/types.js +2 -0
- package/dist/cjs/stringUtils/stringUtils.js +294 -0
- package/dist/cjs/utils/utils.js +1050 -0
- package/dist/esm/detokeniser/detokeniser.js +1131 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/jsonUtils/jsonUtils.js +420 -0
- package/dist/esm/logger/logger.js +859 -0
- package/dist/esm/logger/logger.spec.js +873 -0
- package/dist/esm/logger/types.js +1 -0
- package/dist/esm/stringUtils/stringUtils.js +290 -0
- package/dist/esm/utils/utils.js +1043 -0
- package/dist/types/detokeniser/detokeniser.d.ts +402 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/jsonUtils/jsonUtils.d.ts +196 -0
- package/dist/types/logger/logger.d.ts +388 -0
- package/dist/types/logger/logger.spec.d.ts +1 -0
- package/dist/types/logger/types.d.ts +235 -0
- package/dist/types/stringUtils/stringUtils.d.ts +129 -0
- package/dist/types/utils/utils.d.ts +450 -0
- package/package.json +110 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { JsonUtils, Log, LogLevels } from "../index";
|
|
2
|
+
import { Utils } from "../utils/utils";
|
|
3
|
+
/**
|
|
4
|
+
* General String related test-related utilities.
|
|
5
|
+
* @note
|
|
6
|
+
* Originally written as String extensions, re-written as static functions for broader compatibility.
|
|
7
|
+
*/
|
|
8
|
+
export class StringUtils {
|
|
9
|
+
/**
|
|
10
|
+
* Removes leading and trailing instances of given character from a string
|
|
11
|
+
* @param originalString
|
|
12
|
+
* String to be trimmed
|
|
13
|
+
* @param characterToTrim
|
|
14
|
+
* Character to be removed from start and end of string, if present
|
|
15
|
+
*/
|
|
16
|
+
static trimChar(originalString, characterToTrim) {
|
|
17
|
+
Utils.assertType(originalString, "string", "trimChar", "originalString");
|
|
18
|
+
Utils.assertType(characterToTrim, "string", "trimChar", "characterToTrim");
|
|
19
|
+
// Check we have only been given a single char to trim. Bomb if not.
|
|
20
|
+
if (characterToTrim.length !== 1) {
|
|
21
|
+
const error = `characterToTrim (${characterToTrim}) must be a single character!`;
|
|
22
|
+
Log.writeLine(LogLevels.Error, ` ${error}`);
|
|
23
|
+
throw new Error(error);
|
|
24
|
+
}
|
|
25
|
+
let normalizedCharToTrim = characterToTrim === "]" ? "\\]" : characterToTrim;
|
|
26
|
+
normalizedCharToTrim = normalizedCharToTrim === "^" ? "\\^" : normalizedCharToTrim;
|
|
27
|
+
normalizedCharToTrim = normalizedCharToTrim === "\\" ? "\\\\" : normalizedCharToTrim;
|
|
28
|
+
return originalString.replace(new RegExp("^[" + normalizedCharToTrim + "]+|[" + normalizedCharToTrim + "]+$", "g"), "");
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Trims single or double quotes from string if string starts AND ends in same quote character
|
|
32
|
+
* @param originalString
|
|
33
|
+
* String to be trimmed
|
|
34
|
+
*/
|
|
35
|
+
static trimQuotes(originalString) {
|
|
36
|
+
Utils.assertType(originalString, "string", "trimQuotes", "originalString");
|
|
37
|
+
let trimmedString = originalString;
|
|
38
|
+
if ((trimmedString.startsWith("'") && trimmedString.endsWith("'")) || (trimmedString.startsWith('"') && trimmedString.endsWith('"'))) {
|
|
39
|
+
trimmedString = trimmedString.substring(1, trimmedString.length - 1);
|
|
40
|
+
}
|
|
41
|
+
return trimmedString;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Checks if character at index is an Alpha character
|
|
45
|
+
* @param stringToCheck
|
|
46
|
+
* String containing character to check
|
|
47
|
+
* @param indexZeroBased - default 0
|
|
48
|
+
* Index of character to check
|
|
49
|
+
* @returns
|
|
50
|
+
* Boolean true is alpha, otherwise false
|
|
51
|
+
*/
|
|
52
|
+
static isAlpha(stringToCheck, indexZeroBased = 0) {
|
|
53
|
+
Utils.assertType(stringToCheck, "string", "isAlpha", "stringToCheck");
|
|
54
|
+
Utils.assertType(indexZeroBased, "number", "isAlpha", "indexZeroBased");
|
|
55
|
+
if (stringToCheck.length - 1 < indexZeroBased) {
|
|
56
|
+
const errorText = `Cannot check if char [${indexZeroBased} (Zero based)] isAlpha as length of stringToCheck is only ${stringToCheck.length} characters long!`;
|
|
57
|
+
Log.writeLine(LogLevels.Error, errorText);
|
|
58
|
+
throw new Error(errorText);
|
|
59
|
+
}
|
|
60
|
+
return stringToCheck.charAt(indexZeroBased).toLowerCase() !== stringToCheck.charAt(indexZeroBased).toUpperCase();
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Set first character of string to Capital (if Alpha)
|
|
64
|
+
* @param originalString
|
|
65
|
+
* String to set first character
|
|
66
|
+
* @returns
|
|
67
|
+
* originalString with first character capitalised
|
|
68
|
+
*/
|
|
69
|
+
static capitaliseFirstCharacter(originalString, searchFirstAlpha = false) {
|
|
70
|
+
Utils.assertType(originalString, "string", "capitaliseFirstCharacter", "originalString");
|
|
71
|
+
if (searchFirstAlpha) {
|
|
72
|
+
const asArray = originalString.split("");
|
|
73
|
+
asArray.find((item, index) => {
|
|
74
|
+
if (this.isAlpha(item)) {
|
|
75
|
+
asArray[index] = item.toUpperCase();
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return asArray.join("");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
return originalString.charAt(0).toUpperCase() + originalString.slice(1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Splits a string upto substrings a maximum number of times using the specified separator and return then as an array
|
|
90
|
+
* @param originalString
|
|
91
|
+
* String to be split
|
|
92
|
+
* @param separator
|
|
93
|
+
* Character to use as seperator. If more than one character, function will error.
|
|
94
|
+
* @param limit
|
|
95
|
+
* A value used to limit the number of elements returned in the array. Last element contains rest of string.
|
|
96
|
+
*/
|
|
97
|
+
static splitRemaining(originalString, separator, limit, doNotSeparateInQuotes = false) {
|
|
98
|
+
Utils.assertType(originalString, "string", "splitRemaining", "originalString");
|
|
99
|
+
Utils.assertType(separator, "string", "splitRemaining", "separator");
|
|
100
|
+
Utils.assertType(limit, "number", "splitRemaining", "limit");
|
|
101
|
+
if (separator.length === 1 && limit > 0) {
|
|
102
|
+
const allParts = StringUtils.split(originalString, separator, doNotSeparateInQuotes);
|
|
103
|
+
const partsToMax = allParts.slice(0, limit - 1);
|
|
104
|
+
const partsAfterMax = allParts.slice(limit - 1);
|
|
105
|
+
return partsAfterMax.length > 0 ? partsToMax.concat([partsAfterMax.join(separator)]) : partsToMax;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
const error = `Seperator [Length was ${separator.length}] must be single character and limit [Limit was ${limit}] greater than 0.`;
|
|
109
|
+
Log.writeLine(LogLevels.Error, error);
|
|
110
|
+
throw new Error(error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Splits a string upto substrings a maximum number of times using the specified separator and return then as an array
|
|
115
|
+
* @param originalString
|
|
116
|
+
* String to be split
|
|
117
|
+
* @param separator
|
|
118
|
+
* A string that identifies character or characters to use in separating the string.
|
|
119
|
+
* @param limit
|
|
120
|
+
* A value used to limit the number of elements returned in the array. First element contains start of string.
|
|
121
|
+
*/
|
|
122
|
+
static splitLeading(originalString, separator, limit, doNotSeparateInQuotes = false) {
|
|
123
|
+
Utils.assertType(originalString, "string", "splitLeading", "originalString");
|
|
124
|
+
Utils.assertType(separator, "string", "splitLeading", "separator");
|
|
125
|
+
Utils.assertType(limit, "number", "splitLeading", "limit");
|
|
126
|
+
const realLimit = limit > originalString.length ? originalString.length : limit;
|
|
127
|
+
if (separator.length === 1 && limit > 0) {
|
|
128
|
+
const allParts = StringUtils.split(originalString, separator, doNotSeparateInQuotes);
|
|
129
|
+
const partsToMax = allParts.slice(0, allParts.length - realLimit + 1);
|
|
130
|
+
const partsAfterMax = allParts.slice(allParts.length - realLimit + 1, allParts.length);
|
|
131
|
+
return partsToMax.length > 0 ? [partsToMax.join(separator)].concat(partsAfterMax) : partsAfterMax;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const error = `Seperator [Length was ${separator.length}] must be single character and limit [Limit was ${limit}] greater than 0.`;
|
|
135
|
+
Log.writeLine(LogLevels.Error, error);
|
|
136
|
+
throw new Error(error);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Splits a string into parts, optionally ignoring slips with quotes
|
|
141
|
+
* @param originalString
|
|
142
|
+
* String to be split
|
|
143
|
+
* @param separator
|
|
144
|
+
* Character to use as seperator. If more than one character, function will error.
|
|
145
|
+
* @param doNotSeparateInQuotes (default true)
|
|
146
|
+
* If true, separator char is ignored within single or double quotes (matching)
|
|
147
|
+
* @returns
|
|
148
|
+
* Array of original string
|
|
149
|
+
*/
|
|
150
|
+
static split(originalString, separator, doNotSeparateInQuotes = true) {
|
|
151
|
+
Utils.assertType(originalString, "string", "split", "originalString");
|
|
152
|
+
Utils.assertType(separator, "string", "split", "separator");
|
|
153
|
+
if (separator.length === 1) {
|
|
154
|
+
if (doNotSeparateInQuotes) {
|
|
155
|
+
const result = originalString.match(/\\?.|^$/g)?.reduce((workingObject, currentChar) => {
|
|
156
|
+
if (['"', "'"].includes(currentChar)) {
|
|
157
|
+
if (workingObject.inQuote === "") {
|
|
158
|
+
workingObject.inQuote = currentChar;
|
|
159
|
+
}
|
|
160
|
+
else if (workingObject.inQuote === currentChar) {
|
|
161
|
+
workingObject.inQuote = "";
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (workingObject.inQuote === "" && currentChar === separator) {
|
|
165
|
+
workingObject.array[workingObject.array.length - 1] = StringUtils.trimQuotes(workingObject.array[workingObject.array.length - 1]);
|
|
166
|
+
workingObject.array.push("");
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
workingObject.array[workingObject.array.length - 1] += currentChar.replace(/\\(.)/, "$1");
|
|
170
|
+
}
|
|
171
|
+
return workingObject;
|
|
172
|
+
}, { array: [""], inQuote: "" }).array ?? [originalString];
|
|
173
|
+
result[result.length - 1] = StringUtils.trimQuotes(result[result.length - 1]);
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
return originalString.split(separator);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
const error = `Seperator [Length was ${separator.length}] must be single character.`;
|
|
182
|
+
Log.writeLine(LogLevels.Error, error);
|
|
183
|
+
throw new Error(error);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Splits a string into verb and paremeters. Parameters are part enclosed in trailing brackets.
|
|
188
|
+
* @param rawCommand
|
|
189
|
+
* String containing command verb and, optionally, braces enclosing parameters
|
|
190
|
+
* @returns
|
|
191
|
+
* Object with verb and parameters properties
|
|
192
|
+
* @example
|
|
193
|
+
* "hello"
|
|
194
|
+
* results in verb: "hello", parameters: ''
|
|
195
|
+
* "hello(this is, good)"
|
|
196
|
+
* results in verb: "hello", parameters: 'this is, good'
|
|
197
|
+
* @throws
|
|
198
|
+
* Error if badly formed (no trailing close braces etc....)
|
|
199
|
+
*/
|
|
200
|
+
static splitVerbAndParameters(rawCommand) {
|
|
201
|
+
Log.writeLine(LogLevels.FrameworkDebug, `Got string [${rawCommand}]`);
|
|
202
|
+
if (rawCommand.includes("(")) {
|
|
203
|
+
if (rawCommand.endsWith(")")) {
|
|
204
|
+
let paramsPart = StringUtils.splitRemaining(rawCommand, '(', 2)[1];
|
|
205
|
+
paramsPart = paramsPart.substring(0, paramsPart.length - 1);
|
|
206
|
+
Log.writeLine(LogLevels.FrameworkDebug, `Parameters are: [${paramsPart}]`);
|
|
207
|
+
return {
|
|
208
|
+
verb: rawCommand.split("(")[0],
|
|
209
|
+
parameters: paramsPart,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const errText = `Object <${rawCommand}> has no closing brackets! If has opening brackets then must have closing brackets`;
|
|
214
|
+
Log.writeLine(LogLevels.Error, errText);
|
|
215
|
+
throw new Error(errText);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
return {
|
|
220
|
+
verb: rawCommand,
|
|
221
|
+
parameters: "",
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Removes all non-alphanumerics from string
|
|
227
|
+
* @param originalString
|
|
228
|
+
* String to remove non-alphanumerics from
|
|
229
|
+
*/
|
|
230
|
+
static removeNonAlphaNumeric(originalString) {
|
|
231
|
+
Utils.assertType(originalString, "string", "removeNonAlphaNumeric", "originalString");
|
|
232
|
+
return originalString.replace(/[^a-zA-Z0-9]+/g, "");
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Removes all whitespace from string
|
|
236
|
+
* @param originalString
|
|
237
|
+
* String to remove whitespace from
|
|
238
|
+
*/
|
|
239
|
+
static removeWhitespace(originalString) {
|
|
240
|
+
Utils.assertType(originalString, "string", "removeWhitespace", "originalString");
|
|
241
|
+
return originalString.replace(/\s+/g, "");
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Encode given string to enable use within HTML
|
|
245
|
+
* @param originalString
|
|
246
|
+
* Non-encoded string to be HTML encoded
|
|
247
|
+
* @returns
|
|
248
|
+
* Original string HTML encoded.
|
|
249
|
+
*/
|
|
250
|
+
static encodeHTML(originalString) {
|
|
251
|
+
Utils.assertType(originalString, "string", "encodeHTML", "originalString");
|
|
252
|
+
return originalString.replace(/[&<>'"]/g, (tag) => ({
|
|
253
|
+
"&": "&",
|
|
254
|
+
"<": "<",
|
|
255
|
+
">": ">",
|
|
256
|
+
"'": "'",
|
|
257
|
+
'"': """,
|
|
258
|
+
}[tag] ?? ""));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Replace all matching instances with replacement
|
|
262
|
+
* @param original
|
|
263
|
+
* String to replace values in
|
|
264
|
+
* @param searchValue
|
|
265
|
+
* Value to replace
|
|
266
|
+
* @param replaceValue
|
|
267
|
+
* Value to replace mathes with
|
|
268
|
+
* @returns
|
|
269
|
+
* Original string with all matching occuranced replaced
|
|
270
|
+
*/
|
|
271
|
+
static replaceAll(original, searchValue, replaceValue) {
|
|
272
|
+
if (Utils.isNullOrUndefined(original)) {
|
|
273
|
+
const errText = `Cannot replace [${searchValue}] with [${replaceValue}] Original is null or undefined!`;
|
|
274
|
+
Log.writeLine(LogLevels.Error, errText);
|
|
275
|
+
throw new Error(errText);
|
|
276
|
+
}
|
|
277
|
+
const escapedRegExp = new RegExp(JsonUtils.escapeRegExp(searchValue), 'g');
|
|
278
|
+
return original.replace(escapedRegExp, replaceValue);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Checks if a string is blank
|
|
282
|
+
* @param text
|
|
283
|
+
* String to be verified for blank
|
|
284
|
+
* @returns
|
|
285
|
+
* Boolean true is empty or with blankspaces, otherwise false
|
|
286
|
+
*/
|
|
287
|
+
static isBlank(text) {
|
|
288
|
+
return Utils.isNullOrUndefined(text) || text.trim().length === 0;
|
|
289
|
+
}
|
|
290
|
+
}
|