@cocreate/utils 1.41.1 → 1.42.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/CHANGELOG.md +14 -0
- package/README.md +40 -5
- package/package.json +129 -3
- package/src/ObjectId.js +41 -0
- package/src/attributes.js +48 -0
- package/src/checkValue.js +4 -0
- package/src/clickedElement.js +28 -0
- package/src/core.js +6 -0
- package/src/createUpdate.js +202 -0
- package/src/cssPath.js +50 -0
- package/src/dataQuery.js +291 -0
- package/src/dom.js +4 -0
- package/src/domParser.js +21 -0
- package/src/dotNotationToObject.js +90 -0
- package/src/escapeHtml.js +8 -0
- package/src/getRelativePath.js +24 -0
- package/src/getValueFromObject.js +25 -0
- package/src/index.js +70 -1365
- package/src/init-browser.js +5 -0
- package/src/isValidDate.js +17 -0
- package/src/objectToDotNotation.js +35 -0
- package/src/objectToSearchParams.js +28 -0
- package/src/operators.js +580 -0
- package/src/parseTextToHtml.js +5 -0
- package/src/queryElements.js +174 -0
- package/src/safeParse.js +171 -0
- package/src/uid.js +16 -0
package/src/dataQuery.js
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { getValueFromObject } from "./getValueFromObject.js";
|
|
2
|
+
import { isValidDate } from "./isValidDate.js";
|
|
3
|
+
|
|
4
|
+
function isEqualArray(arr1, arr2) {
|
|
5
|
+
if (arr1.length !== arr2.length) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
for (let i = 0; i < arr1.length; i++) {
|
|
9
|
+
if (!isEqualObject(arr1[i], arr2[i])) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isEqualObject(obj1, obj2) {
|
|
17
|
+
const keys1 = Object.keys(obj1);
|
|
18
|
+
const keys2 = Object.keys(obj2);
|
|
19
|
+
|
|
20
|
+
if (keys1.length !== keys2.length) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (const key of keys1) {
|
|
25
|
+
if (obj1[key] !== obj2[key]) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function queryMatch(data, query) {
|
|
34
|
+
for (let key of Object.keys(query)) {
|
|
35
|
+
let dataValue;
|
|
36
|
+
try {
|
|
37
|
+
dataValue = getValueFromObject(data, key, true);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (
|
|
43
|
+
typeof query[key] === "string" ||
|
|
44
|
+
typeof query[key] === "number" ||
|
|
45
|
+
typeof query[key] === "boolean"
|
|
46
|
+
) {
|
|
47
|
+
if (Array.isArray(dataValue)) return dataValue.includes(query[key]);
|
|
48
|
+
else return dataValue === query[key];
|
|
49
|
+
} else if (Array.isArray(query[key])) {
|
|
50
|
+
if (Array.isArray(dataValue)) {
|
|
51
|
+
return isEqualArray(dataValue, query[key]);
|
|
52
|
+
} else {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
for (let property of Object.keys(query[key])) {
|
|
57
|
+
if (property === "$options") continue;
|
|
58
|
+
if (!property.startsWith("$")) {
|
|
59
|
+
if (typeof dataValue !== "object") {
|
|
60
|
+
return false;
|
|
61
|
+
} else
|
|
62
|
+
return queryMatch(
|
|
63
|
+
{ [property]: getValueFromObject(dataValue, property) },
|
|
64
|
+
{ [property]: query[key][property] }
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
let queryValue = query[key][property];
|
|
68
|
+
if (isValidDate(queryValue) && isValidDate(dataValue)) {
|
|
69
|
+
queryValue = new Date(queryValue);
|
|
70
|
+
dataValue = new Date(dataValue);
|
|
71
|
+
}
|
|
72
|
+
let queryStatus = false;
|
|
73
|
+
switch (property) {
|
|
74
|
+
case "$eq":
|
|
75
|
+
if (Array.isArray(dataValue) && Array.isArray(queryValue)) {
|
|
76
|
+
queryStatus = isEqualArray(dataValue, queryValue);
|
|
77
|
+
} else {
|
|
78
|
+
queryStatus = dataValue === queryValue;
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
case "$ne":
|
|
82
|
+
if (Array.isArray(dataValue) && Array.isArray(queryValue)) {
|
|
83
|
+
queryStatus = !isEqualArray(dataValue, queryValue);
|
|
84
|
+
} else {
|
|
85
|
+
queryStatus = dataValue !== queryValue;
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
case "$not":
|
|
89
|
+
queryStatus = !queryMatch(data, {
|
|
90
|
+
[key]: query[key]["$not"]
|
|
91
|
+
});
|
|
92
|
+
break;
|
|
93
|
+
case "$lt":
|
|
94
|
+
queryStatus = dataValue < queryValue;
|
|
95
|
+
break;
|
|
96
|
+
case "$lte":
|
|
97
|
+
queryStatus = dataValue <= queryValue;
|
|
98
|
+
break;
|
|
99
|
+
case "$gt":
|
|
100
|
+
queryStatus = dataValue > queryValue;
|
|
101
|
+
break;
|
|
102
|
+
case "$gte":
|
|
103
|
+
queryStatus = dataValue >= queryValue;
|
|
104
|
+
break;
|
|
105
|
+
case "$in":
|
|
106
|
+
if (Array.isArray(dataValue)) {
|
|
107
|
+
queryStatus = dataValue.some((element) =>
|
|
108
|
+
queryValue.includes(element)
|
|
109
|
+
);
|
|
110
|
+
} else {
|
|
111
|
+
queryStatus = queryValue.includes(dataValue);
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
case "$nin":
|
|
115
|
+
if (Array.isArray(dataValue)) {
|
|
116
|
+
queryStatus = !dataValue.some((element) =>
|
|
117
|
+
queryValue.includes(element)
|
|
118
|
+
);
|
|
119
|
+
} else {
|
|
120
|
+
queryStatus = !queryValue.includes(dataValue);
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
case "$all":
|
|
124
|
+
if (Array.isArray(dataValue) && Array.isArray(queryValue)) {
|
|
125
|
+
queryStatus = queryValue.every((element) =>
|
|
126
|
+
dataValue.includes(element)
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
case "$elemMatch":
|
|
131
|
+
if (Array.isArray(data[key])) {
|
|
132
|
+
queryStatus = data[key].some((element) =>
|
|
133
|
+
queryMatch(element, query[key][property])
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
break;
|
|
137
|
+
case "$size":
|
|
138
|
+
if (Array.isArray(dataValue)) {
|
|
139
|
+
queryStatus = dataValue.length === queryValue;
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
case "$exists":
|
|
143
|
+
queryStatus = queryValue
|
|
144
|
+
? data.hasOwnProperty(key)
|
|
145
|
+
: !data.hasOwnProperty(key);
|
|
146
|
+
break;
|
|
147
|
+
case "$regex":
|
|
148
|
+
if (typeof dataValue === "string") {
|
|
149
|
+
let regexFlag = query[key]["$options"] || "";
|
|
150
|
+
let regex = new RegExp(queryValue, regexFlag);
|
|
151
|
+
queryStatus = regex.test(dataValue);
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
case "$type":
|
|
155
|
+
let dataType = typeof dataValue;
|
|
156
|
+
if (Array.isArray(dataValue)) {
|
|
157
|
+
dataType = "array";
|
|
158
|
+
}
|
|
159
|
+
queryStatus = dataType === queryValue;
|
|
160
|
+
break;
|
|
161
|
+
case "$mod":
|
|
162
|
+
if (
|
|
163
|
+
typeof dataValue === "number" &&
|
|
164
|
+
Array.isArray(queryValue) &&
|
|
165
|
+
queryValue.length === 2
|
|
166
|
+
) {
|
|
167
|
+
const [divisor, remainder] = queryValue;
|
|
168
|
+
queryStatus = dataValue % divisor === remainder;
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
case "$where":
|
|
172
|
+
if (typeof queryValue === "function") {
|
|
173
|
+
try {
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error(
|
|
176
|
+
"Error in queryData $where function:",
|
|
177
|
+
error
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
console.log("unknown operator");
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
if (!queryStatus) return false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function queryData(data, query) {
|
|
195
|
+
if (query.$and) {
|
|
196
|
+
for (let i = 0; i < query.$and.length; i++) {
|
|
197
|
+
if (!queryData(data, query.$and[i])) return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (query.$nor) {
|
|
202
|
+
for (let i = 0; i < query.$nor.length; i++) {
|
|
203
|
+
if (queryData(data, query.$nor[i])) return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
for (let key of Object.keys(query)) {
|
|
208
|
+
if (key === "$and" || key === "$or") continue;
|
|
209
|
+
if (!queryMatch(data, { [key]: query[key] })) return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (query.$or) {
|
|
213
|
+
for (let i = 0; i < query.$or.length; i++) {
|
|
214
|
+
if (queryData(data, query.$or[i])) return true;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function searchData(data, search) {
|
|
222
|
+
if (!search) return true;
|
|
223
|
+
if (!Array.isArray(search)) search = [search];
|
|
224
|
+
for (let i = 0; i < search.length; i++) {
|
|
225
|
+
let searchValue = search[i].value;
|
|
226
|
+
if (!Array.isArray(searchValue)) searchValue = [searchValue];
|
|
227
|
+
for (let key in data) {
|
|
228
|
+
let value = data[key];
|
|
229
|
+
let status = false;
|
|
230
|
+
switch (typeof value) {
|
|
231
|
+
case "number":
|
|
232
|
+
value = value.toString();
|
|
233
|
+
break;
|
|
234
|
+
case "object":
|
|
235
|
+
value = JSON.stringify(value);
|
|
236
|
+
break;
|
|
237
|
+
case "function":
|
|
238
|
+
value = value.toString();
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
if (search[i].caseSensitive != "true" || search[i].caseSensitive != true)
|
|
242
|
+
value = value.toLowerCase();
|
|
243
|
+
|
|
244
|
+
for (let i = 0; i < searchValue.length; i++) {
|
|
245
|
+
let searchString = searchValue[i];
|
|
246
|
+
if (
|
|
247
|
+
search[i].caseSensitive != "true" ||
|
|
248
|
+
search[i].caseSensitive != true
|
|
249
|
+
)
|
|
250
|
+
searchString = searchString.toLowerCase();
|
|
251
|
+
|
|
252
|
+
if (searchString === "" && search[i].operator === "and") {
|
|
253
|
+
if (value !== "") return false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (value.indexOf(searchString) > -1) status = true;
|
|
257
|
+
|
|
258
|
+
if (status) return true;
|
|
259
|
+
else if (search[i].operator == "and") return false;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (search[i].value.length && search[i].operator == "or") return false;
|
|
263
|
+
}
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export function sortData(data, sort) {
|
|
268
|
+
return data.sort((a, b) => {
|
|
269
|
+
for (let i = 0; i < sort.length; i++) {
|
|
270
|
+
let key = sort[i].key;
|
|
271
|
+
if (a[key] == null && b[key] == null) continue;
|
|
272
|
+
if (a[key] == null) return sort[i].direction === "desc" ? -1 : 1;
|
|
273
|
+
if (b[key] == null) return sort[i].direction === "desc" ? 1 : -1;
|
|
274
|
+
|
|
275
|
+
if (typeof a[key] !== typeof b[key]) {
|
|
276
|
+
return typeof a[key] < typeof b[key] ? -1 : 1;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (a[key] !== b[key]) {
|
|
280
|
+
if (typeof a[key] === "string") {
|
|
281
|
+
return sort[i].direction === "desc"
|
|
282
|
+
? b[key].localeCompare(a[key])
|
|
283
|
+
: a[key].localeCompare(b[key]);
|
|
284
|
+
} else {
|
|
285
|
+
return sort[i].direction === "desc" ? b[key] - a[key] : a[key] - b[key];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return 0;
|
|
290
|
+
});
|
|
291
|
+
}
|
package/src/dom.js
ADDED
package/src/domParser.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function domParser(str) {
|
|
2
|
+
try {
|
|
3
|
+
var mainTag = str.match(/\<(?<tag>[a-z0-9]+)(.*?)?\>/).groups.tag;
|
|
4
|
+
} catch (e) {}
|
|
5
|
+
let doc;
|
|
6
|
+
switch (mainTag) {
|
|
7
|
+
case "html":
|
|
8
|
+
doc = new DOMParser().parseFromString(str, "text/html");
|
|
9
|
+
return doc.documentElement;
|
|
10
|
+
case "body":
|
|
11
|
+
doc = new DOMParser().parseFromString(str, "text/html");
|
|
12
|
+
return doc.body;
|
|
13
|
+
case "head":
|
|
14
|
+
doc = new DOMParser().parseFromString(str, "text/html");
|
|
15
|
+
return doc.head;
|
|
16
|
+
default:
|
|
17
|
+
let con = document.createElement("dom-parser");
|
|
18
|
+
con.innerHTML = str;
|
|
19
|
+
return con;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export function dotNotationToObject(data, obj = {}) {
|
|
2
|
+
try {
|
|
3
|
+
let arrayGroup = {};
|
|
4
|
+
|
|
5
|
+
for (const key of Object.keys(data)) {
|
|
6
|
+
let value = data[key];
|
|
7
|
+
let newObject = obj;
|
|
8
|
+
let oldObject = new Object(obj);
|
|
9
|
+
let keys = key.split(".");
|
|
10
|
+
let length = keys.length - 1;
|
|
11
|
+
|
|
12
|
+
for (let i = 0; i < keys.length; i++) {
|
|
13
|
+
if (keys[i].endsWith("]")) {
|
|
14
|
+
if (keys[i].endsWith("[]")) {
|
|
15
|
+
let baseKey = keys[i].slice(0, -2);
|
|
16
|
+
|
|
17
|
+
if (!Array.isArray(newObject[baseKey])) {
|
|
18
|
+
newObject[baseKey] = [];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (length == i) {
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
newObject[baseKey].push(...value);
|
|
24
|
+
} else {
|
|
25
|
+
newObject[baseKey].push(value);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} else if (/\[([0-9]+)\]/g.test(keys[i])) {
|
|
29
|
+
let [k, index] = keys[i].split("[");
|
|
30
|
+
index = index.slice(0, -1);
|
|
31
|
+
|
|
32
|
+
if (!Array.isArray(newObject[k])) {
|
|
33
|
+
newObject[k] = [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (length == i) {
|
|
37
|
+
if (value === undefined) {
|
|
38
|
+
newObject[k].splice(index, 1);
|
|
39
|
+
} else {
|
|
40
|
+
newObject[k][index] = value;
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
newObject[k][index] = oldObject[k][index] || {};
|
|
44
|
+
newObject = newObject[k][index];
|
|
45
|
+
oldObject = oldObject[k][index];
|
|
46
|
+
}
|
|
47
|
+
} else if (/\[\w\]/g.test(keys[i])) {
|
|
48
|
+
let [k, group] = keys[i].split("[");
|
|
49
|
+
group = group.slice(0, -1);
|
|
50
|
+
|
|
51
|
+
if (!Array.isArray(newObject[k])) {
|
|
52
|
+
newObject[k] = [];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let index;
|
|
56
|
+
if (arrayGroup[keys.slice(0, i + 1).join(".")]) {
|
|
57
|
+
index = arrayGroup[keys.slice(0, i + 1).join(".")];
|
|
58
|
+
} else {
|
|
59
|
+
index = newObject[k].length;
|
|
60
|
+
arrayGroup[keys.slice(0, i + 1).join(".")] = index;
|
|
61
|
+
newObject[k][index] = {};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (length == i) {
|
|
65
|
+
newObject[k][index] = value;
|
|
66
|
+
} else {
|
|
67
|
+
newObject = newObject[k][index];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
if (length == i) {
|
|
72
|
+
if (value === undefined) {
|
|
73
|
+
delete newObject[keys[i]];
|
|
74
|
+
} else {
|
|
75
|
+
newObject[keys[i]] = value;
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
newObject[keys[i]] = oldObject[keys[i]] || {};
|
|
79
|
+
newObject = newObject[keys[i]];
|
|
80
|
+
oldObject = oldObject[keys[i]];
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return obj;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.log("Error converting dot notation to object", error);
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function getRelativePath(path) {
|
|
2
|
+
const isBrowser = typeof window !== "undefined";
|
|
3
|
+
|
|
4
|
+
if (!path && isBrowser) {
|
|
5
|
+
path = window.location.pathname.replace(/\/[^\/]*$/, "");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (
|
|
9
|
+
isBrowser &&
|
|
10
|
+
(location.hostname === "localhost" ||
|
|
11
|
+
location.hostname === "127.0.0.1")
|
|
12
|
+
) {
|
|
13
|
+
const srcIndex = path.indexOf("/src");
|
|
14
|
+
if (srcIndex !== -1) {
|
|
15
|
+
path = path.slice(srcIndex + 4);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!path.endsWith("/")) {
|
|
20
|
+
path += "/";
|
|
21
|
+
}
|
|
22
|
+
let depth = path.split("/").filter(Boolean).length;
|
|
23
|
+
return depth > 0 ? "../".repeat(depth) : "./";
|
|
24
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function getValueFromObject(object = {}, path = "", throwError = false) {
|
|
2
|
+
try {
|
|
3
|
+
if ((!Array.isArray(object) && !Object.keys(object).length) || !path) {
|
|
4
|
+
if (throwError) throw new Error("Invalid input to getValueFromObject");
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
path = path.replace(/\[(\d+)\]/g, ".$1").replace(/^\./, "");
|
|
9
|
+
|
|
10
|
+
let data = object,
|
|
11
|
+
subpath = path.split(".");
|
|
12
|
+
|
|
13
|
+
for (let i = 0; i < subpath.length; i++) {
|
|
14
|
+
if (throwError && !(subpath[i] in data))
|
|
15
|
+
throw new Error("Key not found in object: " + subpath[i]);
|
|
16
|
+
|
|
17
|
+
data = data[subpath[i]];
|
|
18
|
+
if (!data) break;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return data;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (throwError) throw error;
|
|
24
|
+
}
|
|
25
|
+
}
|