stringweaver 1.2.0 → 1.2.2
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/Bundle/index.min.js +4 -4
- package/Bundle/index.min.js.map +3 -3
- package/README.md +2 -2
- package/package.json +2 -2
- package/src/Factories/interpolateFactory.js +4 -0
- package/src/Factories/randomStringFactory.js +2 -0
- package/src/Factories/regExpFromMultilineStringFactory.js +2 -1
- package/src/extensions.js +2 -1
- package/src/genericMethods.js +74 -70
- package/src/instanceMethods.js +40 -32
- package/tests/UnitTests.js +921 -0
package/src/genericMethods.js
CHANGED
|
@@ -29,20 +29,10 @@ function CustomStringConstructor(str, ...args) {
|
|
|
29
29
|
return Object.freeze(instance);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function clone(instance) {
|
|
33
|
-
const newInstance = CustomStringConstructor(instance.value);
|
|
34
|
-
newInstance.history = [...instance.history];
|
|
35
|
-
return newInstance;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
32
|
function resolveTemplateString(str, ...args) {
|
|
39
33
|
return str?.raw
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getStringValue(string) {
|
|
45
|
-
return string?.value || (string?.constructor === String && string) || ``;
|
|
34
|
+
? String.raw({ raw: str }, ...args)
|
|
35
|
+
: getStringValue(str).length ? str : "";
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
function checkType(type, item, includeInstances) {
|
|
@@ -55,18 +45,44 @@ function isArrayOf(type, value, includeInstances = true) {
|
|
|
55
45
|
return Array.isArray(value) && value.length > 0 && !value.find(v => checkType(type, v, includeInstances));
|
|
56
46
|
}
|
|
57
47
|
|
|
48
|
+
function clone(instance) {
|
|
49
|
+
const newInstance = CustomStringConstructor(instance.value);
|
|
50
|
+
newInstance.history = [...instance.history];
|
|
51
|
+
return newInstance;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getStringValue(string) {
|
|
55
|
+
return string?.value || (string?.constructor === String && string) || ``;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
58
|
function isNumber(value) {
|
|
59
59
|
return value?.constructor === Number && !Number.isNaN(value);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
function escapeRE(reString, modifiers) {
|
|
63
|
+
return new RegExp(reString.replace(/\p{S}|\p{P}/gu, a => `\\${a}`), modifiers);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function escape4RE(reString) {
|
|
67
|
+
return reString.replace(/\p{S}|\p{P}/gu, a => `\\${a}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function infoValue(key, infoValue) {
|
|
71
|
+
return `${key} (${infoValue})`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function getPlainValues() {
|
|
75
|
+
return {
|
|
65
76
|
value: `getter/setter`,
|
|
66
77
|
clone: `chainable getter`,
|
|
67
78
|
notEmpty: `chainable getter|undefined`,
|
|
68
79
|
quote: `Object. See [constructor].quoteInfo`,
|
|
69
80
|
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getSWInformation(notChainable) {
|
|
84
|
+
const firstLines = CustomStringConstructor(decode());
|
|
85
|
+
const plainValues = getPlainValues();
|
|
70
86
|
|
|
71
87
|
return firstLines.split(/\n/)
|
|
72
88
|
.concat(
|
|
@@ -87,18 +103,51 @@ function getSWInformation(notChainable) {
|
|
|
87
103
|
case isPlainValue: return infoValue(key, plainValues[key]);
|
|
88
104
|
case isNative: return infoValue(key, native);
|
|
89
105
|
case isMethod: return infoValue(key, method);
|
|
90
|
-
case isGetter: return infoValue(key, getter);
|
|
91
|
-
|
|
92
|
-
}
|
|
106
|
+
case isGetter: return infoValue(key, getter);
|
|
107
|
+
}
|
|
93
108
|
}
|
|
94
109
|
)
|
|
95
110
|
);
|
|
96
111
|
}
|
|
97
112
|
|
|
98
|
-
function
|
|
99
|
-
return
|
|
113
|
+
function decode() {
|
|
114
|
+
return atob`Rm9yIHRoZSByZWNvcmQ6CltjbV0gY2hhaW5hYmxlIGdldHRlcnMvbWV0aG9kcyBtb2RpZnkgdGhlIGluc3RhbmNlIHN0cmluZwpbY21dIGluZGV4T2Ygb3ZlcnJpZGVzIHJldHVybnMgW3VuZGVmaW5lZF0gaWYgbm90aGluZyB3YXMgZm91bmQgKHNvIG9uZSBjYW4gdXNlIFtsYXN0SV1pbmRleE9mKFtzb21lIHN0cmluZyB2YWx1ZV0pID8/IDAKW2NtXSBpbmNsdWRlcyBpbmZvcm1hdGlvbiBmb3IgY3VzdG9tIG1ldGhvZHMvZ2V0dGVycyBpZiBhcHBsaWNhYmxl`.replace(/\[cm]/g, `\u2714`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function defineQuotingStyles() {
|
|
118
|
+
// see https://en.wikipedia.org/wiki/Quotation_mark
|
|
119
|
+
const quots = {
|
|
120
|
+
backtick: ["`", "`"],
|
|
121
|
+
bracket: [`{`, `}`],
|
|
122
|
+
curlyDoubleInward: [`”`, `“`],
|
|
123
|
+
curlyDouble: [`“`, `”`],
|
|
124
|
+
curlyDoubleEqual: [`“`, `“`],
|
|
125
|
+
curlyLHDouble: [`„`, `”`],
|
|
126
|
+
curlyLHDoubleInward: [`„`, `“`],
|
|
127
|
+
curlyLHSingle: [`‚`, `’`],
|
|
128
|
+
curlyLHSingleInward: [`‚`, `‘`],
|
|
129
|
+
curlySingle: [`‛`, `’`],
|
|
130
|
+
curlySingleEqual: [`‛`, `‛`],
|
|
131
|
+
curlySingleInward: [`’`, `‛`],
|
|
132
|
+
double: [`"`, `"`],
|
|
133
|
+
guillemets: [`«`, `»`],
|
|
134
|
+
guillemetsInward: [`»`, `«`],
|
|
135
|
+
guillemetsSingle: [`‹`, `›`],
|
|
136
|
+
guillemetsSingleInward: [`›`, `‹`],
|
|
137
|
+
single: [`'`, `'`],
|
|
138
|
+
squareBrackets: [`[`, `]`],
|
|
139
|
+
};
|
|
140
|
+
const regExpValues = escape4RE([...new Set(
|
|
141
|
+
Object.values(quots)
|
|
142
|
+
.filter(v => Array.isArray(v))
|
|
143
|
+
.flat())].join(``));
|
|
144
|
+
quots.re = RegExp(`^[${regExpValues}]|[${regExpValues}]$`, "g");
|
|
145
|
+
|
|
146
|
+
return quots;
|
|
100
147
|
}
|
|
101
148
|
|
|
149
|
+
/* this function is not (directly) tested */
|
|
150
|
+
/* node:coverage disable */
|
|
102
151
|
function createExtendedCTOR(ctor, customMethods) {
|
|
103
152
|
Symbol.toSB = Symbol.for(`toStringBuilder`);
|
|
104
153
|
Object.defineProperty(String.prototype, Symbol.toSB, {
|
|
@@ -123,10 +172,13 @@ function createExtendedCTOR(ctor, customMethods) {
|
|
|
123
172
|
addCustom: {
|
|
124
173
|
value( { name, method, enumerable = false, isGetter = false } = {} ) {
|
|
125
174
|
if (CustomStringConstructor``[name]) {
|
|
126
|
-
|
|
175
|
+
console.error(`addCustom: the property "${name}" exists and can not be redefined`);
|
|
176
|
+
return `addCustom: the property "${name}" exists and can not be redefined`;
|
|
127
177
|
}
|
|
178
|
+
|
|
128
179
|
if (name?.constructor === String && method?.constructor === Function && method.length > 0) {
|
|
129
180
|
customMethods[name] = {method, enumerable, isGetter};
|
|
181
|
+
return `addCustom: the ${isGetter ? `getter` : `method`} named "${name}" is added`;
|
|
130
182
|
}
|
|
131
183
|
}
|
|
132
184
|
},
|
|
@@ -164,52 +216,4 @@ function createExtendedCTOR(ctor, customMethods) {
|
|
|
164
216
|
|
|
165
217
|
return ctor;
|
|
166
218
|
}
|
|
167
|
-
|
|
168
|
-
function escapeRE(reString, modifiers) {
|
|
169
|
-
return new RegExp(reString.replace(/\p{S}|\p{P}/gu, a => `\\${a}`), modifiers);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
function escape4RE(reString) {
|
|
173
|
-
return reString.replace(/\p{S}|\p{P}/gu, a => `\\${a}`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function decode() {
|
|
177
|
-
return atob`Rm9yIHRoZSByZWNvcmQ6CltjbV0gY2hhaW5hYmxlIGdldHRlcnMvbWV0aG9kcyBtb2RpZnkgdGhlIGluc3RhbmNlIHN0cmluZwpbY21dIGluZGV4T2Ygb3ZlcnJpZGVzIHJldHVybnMgW3VuZGVmaW5lZF0gaWYgbm90aGluZyB3YXMgZm91bmQgKHNvIG9uZSBjYW4gdXNlIFtsYXN0SV1pbmRleE9mKFtzb21lIHN0cmluZyB2YWx1ZV0pID8/IDAKW2NtXSBpbmNsdWRlcyBpbmZvcm1hdGlvbiBmb3IgY3VzdG9tIG1ldGhvZHMvZ2V0dGVycyBpZiBhcHBsaWNhYmxl`.replace(/\[cm\]/g, `\u2714`);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
function defineQuotingStyles() {
|
|
181
|
-
// see https://en.wikipedia.org/wiki/Quotation_mark
|
|
182
|
-
const custom = (start, end) => {
|
|
183
|
-
start = getStringValue(start);
|
|
184
|
-
end = getStringValue(end);
|
|
185
|
-
return [getStringValue(start), end.length ? end : start];
|
|
186
|
-
}
|
|
187
|
-
const quots = {
|
|
188
|
-
backtick: ["`", "`"],
|
|
189
|
-
bracket: [`{`, `}`],
|
|
190
|
-
curlyDoubleInward: [`”`, `“`],
|
|
191
|
-
curlyDouble: [`“`, `”`],
|
|
192
|
-
curlyDoubleEqual: [`“`, `“`],
|
|
193
|
-
curlyLHDouble: [`„`, `”`],
|
|
194
|
-
curlyLHDoubleInward: [`„`, `“`],
|
|
195
|
-
curlyLHSingle: [`‚`, `’`],
|
|
196
|
-
curlyLHSingleInward: [`‚`, `‘`],
|
|
197
|
-
curlySingle: [`‛`, `’`],
|
|
198
|
-
curlySingleEqual: [`‛`, `‛`],
|
|
199
|
-
curlySingleInward: [`’`, `‛`],
|
|
200
|
-
custom,
|
|
201
|
-
double: [`"`, `"`],
|
|
202
|
-
guillemets: [`«`, `»`],
|
|
203
|
-
guillemetsInward: [`»`, `«`],
|
|
204
|
-
guillemetsSingle: [`‹`, `›`],
|
|
205
|
-
guillemetsSingleInward: [`›`, `‹`],
|
|
206
|
-
single: [`'`, `'`],
|
|
207
|
-
squareBrackets: [`[`, `]`],
|
|
208
|
-
};
|
|
209
|
-
const regExpValues = escape4RE([...new Set(
|
|
210
|
-
Object.values(quots)
|
|
211
|
-
.filter(v => Array.isArray(v))
|
|
212
|
-
.flat())].join(``));
|
|
213
|
-
quots.re = RegExp(`^[${regExpValues}]|[${regExpValues}]$`, "g");
|
|
214
|
-
return quots;
|
|
215
|
-
}
|
|
219
|
+
/* node:coverage enable */
|
package/src/instanceMethods.js
CHANGED
|
@@ -36,12 +36,12 @@ function checkAndRun(string, fn, or) {
|
|
|
36
36
|
return string.length > 0 ? fn(string) : or || string;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
function
|
|
40
|
-
return checkAndRun(string, () => `${
|
|
39
|
+
function ucFirst(string) {
|
|
40
|
+
return checkAndRun(string, () => `${string[0].toUpperCase()}${string.slice(1)}`);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
function
|
|
44
|
-
return checkAndRun(string, () => `${
|
|
43
|
+
function format(string, ...tokens) {
|
|
44
|
+
return checkAndRun(string, () => `${interpolate(string, ...tokens)}`);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
function surroundWith(string, start, end) {
|
|
@@ -53,7 +53,7 @@ function surroundWith(string, start, end) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function toDashedNotation(string) {
|
|
56
|
-
return checkAndRun(string, () =>
|
|
56
|
+
return checkAndRun(string, () =>
|
|
57
57
|
string
|
|
58
58
|
.replace(/\s/g, '')
|
|
59
59
|
.replace(/[A-Z]/g, a => `-${a.toLowerCase()}`)
|
|
@@ -82,7 +82,7 @@ function wordsFirstUp(string) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function toCamelcase(string) {
|
|
85
|
-
return checkAndRun(string, () =>
|
|
85
|
+
return checkAndRun(string, () =>
|
|
86
86
|
string.toLowerCase()
|
|
87
87
|
.trim()
|
|
88
88
|
.split(/[- ]/)
|
|
@@ -92,29 +92,37 @@ function toCamelcase(string) {
|
|
|
92
92
|
);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
function getBoundary(string) {
|
|
96
|
+
const match = [...string.matchAll(/\p{Pe}|\p{Z}/gu)].at(-1);
|
|
97
|
+
return match?.index ?? string.length;
|
|
98
|
+
}
|
|
99
|
+
|
|
95
100
|
function truncate(string, {at, html = false, wordBoundary = false} = {} ) {
|
|
101
|
+
html = html?.constructor === Boolean && html || false;
|
|
102
|
+
wordBoundary = wordBoundary?.constructor === Boolean && wordBoundary || false;
|
|
96
103
|
return checkAndRun(string, () => {
|
|
97
104
|
if (string.length <= at) { return string; }
|
|
98
|
-
|
|
105
|
+
|
|
99
106
|
const subString = string.slice(0, at - 1);
|
|
100
107
|
const endwith = html ? "…" : `...`;
|
|
101
|
-
const boundary = wordBoundary
|
|
102
|
-
?
|
|
108
|
+
const boundary = wordBoundary
|
|
109
|
+
? getBoundary(subString)
|
|
103
110
|
: subString.length;
|
|
104
|
-
|
|
111
|
+
|
|
105
112
|
return (wordBoundary
|
|
106
113
|
? subString.slice(0, boundary+1).trim()
|
|
107
|
-
: subString) + endwith;
|
|
114
|
+
: subString) + endwith;
|
|
108
115
|
}
|
|
109
116
|
);
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
function trimAll(string, keepLines) {
|
|
119
|
+
function trimAll(string, keepLines = false) {
|
|
120
|
+
keepLines = keepLines?.constructor === Boolean && keepLines || false;
|
|
113
121
|
return checkAndRun(string, () => {
|
|
114
122
|
const lines = string.replace(/\n/gm, `#LF#`)
|
|
115
123
|
.split(/#LF#/)
|
|
116
124
|
.map(line => line.trim().replace(/\s{2,}/g, a => a[0]) );
|
|
117
|
-
return keepLines
|
|
125
|
+
return keepLines
|
|
118
126
|
? lines.join(`#LF#`).replace(/#LF#/g, `\n`).trim()
|
|
119
127
|
: lines.filter(l => l.length > 0).join(`\n`);
|
|
120
128
|
});
|
|
@@ -125,10 +133,10 @@ function replaceWords(string, { replacements = {}, caseSensitive = false} = {})
|
|
|
125
133
|
let replacements2Array = Object.entries(replacements).flat();
|
|
126
134
|
const cando = isArrayOf(String, replacements2Array) && caseSensitive?.constructor === Boolean;
|
|
127
135
|
const modifiers = `g${!caseSensitive ? 'i' : ''}`;
|
|
128
|
-
|
|
136
|
+
|
|
129
137
|
if (cando) {
|
|
130
138
|
replacements2Array = replacements2Array.map(v => getStringValue(v)).filter(v => replacements2Array.length > 0);
|
|
131
|
-
|
|
139
|
+
|
|
132
140
|
if (replacements2Array.length) {
|
|
133
141
|
while (replacements2Array.length) {
|
|
134
142
|
const [initial, replacement] = [replacements2Array.shift(), replacements2Array.shift()];
|
|
@@ -137,41 +145,41 @@ function replaceWords(string, { replacements = {}, caseSensitive = false} = {})
|
|
|
137
145
|
}
|
|
138
146
|
}
|
|
139
147
|
}
|
|
140
|
-
|
|
148
|
+
|
|
141
149
|
return string;
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
// SEE https://youtu.be/99Zacm7SsWQ?t=2101
|
|
145
|
-
function indexOf(string, findMe, fromIndex) {
|
|
153
|
+
function indexOf(string, findMe, fromIndex = 0) {
|
|
146
154
|
string = getStringValue(string);
|
|
147
|
-
fromIndex = isNumber(fromIndex)
|
|
155
|
+
fromIndex = isNumber(fromIndex) && fromIndex || 0;
|
|
148
156
|
const index = string.indexOf(findMe, fromIndex || 0);
|
|
149
|
-
return index < 0 ? undefined : index;
|
|
157
|
+
return index < 0 ? undefined : index;
|
|
150
158
|
}
|
|
151
159
|
|
|
152
|
-
function lastIndexOf(string, findMe, beforeIndex) {
|
|
160
|
+
function lastIndexOf(string, findMe, beforeIndex = 0) {
|
|
153
161
|
string = getStringValue(string);
|
|
154
|
-
beforeIndex = isNumber(beforeIndex)
|
|
162
|
+
beforeIndex = isNumber(beforeIndex) && beforeIndex || string.length;
|
|
155
163
|
const index = string.lastIndexOf(findMe, beforeIndex);
|
|
156
164
|
return index < 0 ? undefined : index;
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
function insert(string, { value, values, at = 0 } = {}) {
|
|
160
168
|
string = getStringValue(string);
|
|
161
|
-
at = isNumber(at)
|
|
169
|
+
at = isNumber(at) && at || 0;
|
|
162
170
|
const valuesMaybeValue = getStringValue(values);
|
|
163
|
-
values = getStringValue(value).length
|
|
171
|
+
values = getStringValue(value).length
|
|
164
172
|
? value
|
|
165
173
|
: valuesMaybeValue.length
|
|
166
174
|
? valuesMaybeValue
|
|
167
|
-
: isArrayOf(String, values)
|
|
168
|
-
? values.map(v => getStringValue(v)).join(``)
|
|
175
|
+
: isArrayOf(String, values)
|
|
176
|
+
? values.map(v => getStringValue(v)).join(``)
|
|
169
177
|
: [];
|
|
170
|
-
|
|
178
|
+
|
|
171
179
|
return values.length <= 1
|
|
172
180
|
? string
|
|
173
|
-
: string.length === 0
|
|
174
|
-
? `${values}${string}`
|
|
181
|
+
: string.length === 0
|
|
182
|
+
? `${values}${string}`
|
|
175
183
|
: `${string.slice(0, at)}${values}${string.slice(at)}`;
|
|
176
184
|
}
|
|
177
185
|
|
|
@@ -182,16 +190,16 @@ function prefix(string, ...strings) {
|
|
|
182
190
|
|
|
183
191
|
function append(string, ...strings2Append) {
|
|
184
192
|
strings2Append = isArrayOf(String, strings2Append) && strings2Append;
|
|
185
|
-
|
|
193
|
+
|
|
186
194
|
if (strings2Append && strings2Append.length > 0) {
|
|
187
195
|
return `${getStringValue(string)}`.concat(strings2Append.join(``))
|
|
188
196
|
}
|
|
189
|
-
|
|
197
|
+
|
|
190
198
|
return getStringValue(string);
|
|
191
199
|
}
|
|
192
200
|
|
|
193
201
|
function quotGetters(instance, wrap) {
|
|
194
|
-
return {
|
|
202
|
+
return {
|
|
195
203
|
value: {
|
|
196
204
|
get backtick() { return instance.enclose(...quotingStyles.backtick); },
|
|
197
205
|
get bracket() { return instance.enclose(...quotingStyles.bracket); },
|
|
@@ -213,7 +221,7 @@ function quotGetters(instance, wrap) {
|
|
|
213
221
|
get remove() { return wrap(`${instance.value.replace(quotingStyles.re, ``)}`); },
|
|
214
222
|
get single() { return instance.enclose(...quotingStyles.single); },
|
|
215
223
|
get squareBrackets() { return instance.enclose(...quotingStyles.squareBrackets); },
|
|
216
|
-
},
|
|
224
|
+
},
|
|
217
225
|
enumerable: false,
|
|
218
226
|
configurable: false,
|
|
219
227
|
};
|