inibase 1.0.0-rc.9 → 1.0.0-rc.91
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 +1 -1
- package/README.md +410 -100
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +272 -0
- package/dist/file.d.ts +148 -0
- package/dist/file.js +597 -0
- package/dist/index.d.ts +192 -0
- package/dist/index.js +1376 -0
- package/dist/utils.d.ts +205 -0
- package/dist/utils.js +509 -0
- package/dist/utils.server.d.ts +83 -0
- package/dist/utils.server.js +248 -0
- package/package.json +66 -19
- package/file.ts +0 -501
- package/index.test.ts +0 -210
- package/index.ts +0 -1488
- package/tsconfig.json +0 -7
- package/utils.server.ts +0 -79
- package/utils.ts +0 -212
package/dist/utils.js
ADDED
|
@@ -0,0 +1,509 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guard function to check if the input is an array of objects.
|
|
3
|
+
*
|
|
4
|
+
* @param input - The value to be checked.
|
|
5
|
+
* @returns boolean - True if the input is an array of objects, false otherwise.
|
|
6
|
+
*
|
|
7
|
+
* Note: Considers empty arrays and arrays where every element is an object.
|
|
8
|
+
*/
|
|
9
|
+
export const isArrayOfObjects = (input) => Array.isArray(input) && (input.length === 0 || input.every(isObject));
|
|
10
|
+
/**
|
|
11
|
+
* Type guard function to check if the input is an array of arrays.
|
|
12
|
+
*
|
|
13
|
+
* @param input - The value to be checked.
|
|
14
|
+
* @returns boolean - True if the input is an array of arrays, false otherwise.
|
|
15
|
+
*
|
|
16
|
+
* Note: Considers empty arrays and arrays where every element is also an array.
|
|
17
|
+
*/
|
|
18
|
+
export const isArrayOfArrays = (input) => Array.isArray(input) && (input.length === 0 || input.every(Array.isArray));
|
|
19
|
+
/**
|
|
20
|
+
* Type guard function to check if the input is an array of nulls or an array of arrays of nulls.
|
|
21
|
+
*
|
|
22
|
+
* @param input - The value to be checked.
|
|
23
|
+
* @returns boolean - True if the input is an array consisting entirely of nulls or arrays of nulls, false otherwise.
|
|
24
|
+
*
|
|
25
|
+
* Note: Recursively checks each element, allowing for nested arrays of nulls.
|
|
26
|
+
*/
|
|
27
|
+
export const isArrayOfNulls = (input) => input.every((_input) => Array.isArray(_input) ? isArrayOfNulls(_input) : _input === null);
|
|
28
|
+
/**
|
|
29
|
+
* Type guard function to check if the input is an object.
|
|
30
|
+
*
|
|
31
|
+
* @param obj - The value to be checked.
|
|
32
|
+
* @returns boolean - True if the input is an object (excluding arrays), false otherwise.
|
|
33
|
+
*
|
|
34
|
+
* Note: Checks if the input is non-null and either has 'Object' as its constructor name or is of type 'object' without being an array.
|
|
35
|
+
*/
|
|
36
|
+
export const isObject = (obj) => obj != null &&
|
|
37
|
+
(obj.constructor.name === "Object" ||
|
|
38
|
+
(typeof obj === "object" && !Array.isArray(obj)));
|
|
39
|
+
/**
|
|
40
|
+
* Recursively merges properties from a source object into a target object. If a property exists in both, the source's value overwrites the target's.
|
|
41
|
+
*
|
|
42
|
+
* @param target - The target object to merge properties into.
|
|
43
|
+
* @param source - The source object from which properties are merged.
|
|
44
|
+
* @returns any - The modified target object with merged properties.
|
|
45
|
+
*
|
|
46
|
+
* Note: Performs a deep merge for nested objects. Non-object properties are directly overwritten.
|
|
47
|
+
*/
|
|
48
|
+
export const deepMerge = (target, source) => {
|
|
49
|
+
for (const key in source) {
|
|
50
|
+
if (Object.hasOwn(source, key)) {
|
|
51
|
+
if (isObject(source[key]) && isObject(target[key]))
|
|
52
|
+
target[key] = deepMerge(target[key], source[key]);
|
|
53
|
+
else if (source[key] !== null)
|
|
54
|
+
target[key] = source[key];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return target;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Type guard function to check if the input is a number.
|
|
61
|
+
*
|
|
62
|
+
* @param input - The value to be checked.
|
|
63
|
+
* @returns boolean - True if the input is a number, false otherwise.
|
|
64
|
+
*
|
|
65
|
+
* Note: Validates that the input can be parsed as a float and that subtracting zero results in a number, ensuring it's a numeric value.
|
|
66
|
+
*/
|
|
67
|
+
export const isNumber = (input) => !Number.isNaN(Number.parseFloat(input)) && !Number.isNaN(input - 0);
|
|
68
|
+
/**
|
|
69
|
+
* Checks if the input is a valid email format.
|
|
70
|
+
*
|
|
71
|
+
* @param input - The value to be checked.
|
|
72
|
+
* @returns boolean - True if the input matches the email format, false otherwise.
|
|
73
|
+
*
|
|
74
|
+
* Note: Uses a regular expression to validate the email format, ensuring it has parts separated by '@' and contains a domain with a period.
|
|
75
|
+
*/
|
|
76
|
+
export const isEmail = (input) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(input));
|
|
77
|
+
/**
|
|
78
|
+
* Checks if the input is a valid URL format.
|
|
79
|
+
*
|
|
80
|
+
* @param input - The value to be checked.
|
|
81
|
+
* @returns boolean - True if the input matches the URL format, false otherwise.
|
|
82
|
+
*
|
|
83
|
+
* Note: Validates URLs including protocols (http/https), domain names, IP addresses, ports, paths, query strings, and fragments.
|
|
84
|
+
* Also recognizes 'tel:' and 'mailto:' as valid URL formats, as well as strings starting with '#' without spaces.
|
|
85
|
+
*/
|
|
86
|
+
export const isURL = (input) => {
|
|
87
|
+
if (typeof input !== "string")
|
|
88
|
+
return false;
|
|
89
|
+
if ((input[0] === "#" && !input.includes(" ")) ||
|
|
90
|
+
input.startsWith("tel:") ||
|
|
91
|
+
input.startsWith("mailto:"))
|
|
92
|
+
return true;
|
|
93
|
+
const pattern = new RegExp("^(https?:\\/\\/)?" + // protocol
|
|
94
|
+
"((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name
|
|
95
|
+
"localhost|" + // OR localhost
|
|
96
|
+
"((\\d{1,3}\\.){3}\\d{1,3}))" + // OR ip (v4) address
|
|
97
|
+
"(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // port and path
|
|
98
|
+
"(\\?[;&a-z\\d%_.~+=-]*)?" + // query string
|
|
99
|
+
"(\\#[-a-z\\d_]*)?$", "i"); // fragment locator
|
|
100
|
+
return !!pattern.test(input);
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Checks if the input contains HTML tags or entities.
|
|
104
|
+
*
|
|
105
|
+
* @param input - The value to be checked.
|
|
106
|
+
* @returns boolean - True if the input contains HTML tags or entities, false otherwise.
|
|
107
|
+
*
|
|
108
|
+
* Note: Uses a regular expression to detect HTML tags (like <tag>) and entities (like &entity;).
|
|
109
|
+
* Recognizes both opening and closing tags, as well as self-closing tags.
|
|
110
|
+
*/
|
|
111
|
+
export const isHTML = (input) => /<\/?\s*[a-z-][^>]*\s*>|(\&(?:[\w\d]+|#\d+|#x[a-f\d]+);)/g.test(input);
|
|
112
|
+
/**
|
|
113
|
+
* Type guard function to check if the input is a string, excluding strings that match specific formats (number, boolean, email, URL, IP).
|
|
114
|
+
*
|
|
115
|
+
* @param input - The value to be checked.
|
|
116
|
+
* @returns boolean - True if the input is a string that doesn't match the specific formats, false otherwise.
|
|
117
|
+
*
|
|
118
|
+
* Note: Validates the input against being a number, boolean, email, URL, or IP address to ensure it's a general string.
|
|
119
|
+
*/
|
|
120
|
+
export const isString = (input) => Object.prototype.toString.call(input) === "[object String]" &&
|
|
121
|
+
(!isNumber(input) || String(input).at(0) === "0");
|
|
122
|
+
/**
|
|
123
|
+
* Checks if the input is a valid IP address format.
|
|
124
|
+
*
|
|
125
|
+
* @param input - The value to be checked.
|
|
126
|
+
* @returns boolean - True if the input matches the IP address format, false otherwise.
|
|
127
|
+
*
|
|
128
|
+
* Note: Uses a regular expression to validate IP addresses, ensuring they consist of four octets, each ranging from 0 to 255.
|
|
129
|
+
*/
|
|
130
|
+
export const isIP = (input) => /^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$/.test(input);
|
|
131
|
+
/**
|
|
132
|
+
* Type guard function to check if the input is a boolean or a string representation of a boolean.
|
|
133
|
+
*
|
|
134
|
+
* @param input - The value to be checked.
|
|
135
|
+
* @returns boolean - True if the input is a boolean value or 'true'/'false' strings, false otherwise.
|
|
136
|
+
*
|
|
137
|
+
* Note: Recognizes both boolean literals (true, false) and their string representations ("true", "false").
|
|
138
|
+
*/
|
|
139
|
+
export const isBoolean = (input) => typeof input === "boolean" || input === "true" || input === "false";
|
|
140
|
+
/**
|
|
141
|
+
* Type guard function to check if the input is a password based on a specific length criterion.
|
|
142
|
+
*
|
|
143
|
+
* @param input - The value to be checked.
|
|
144
|
+
* @returns boolean - True if the input is a string with a length of 161 characters, false otherwise.
|
|
145
|
+
*
|
|
146
|
+
* Note: Specifically checks for string length to determine if it matches the defined password length criterion.
|
|
147
|
+
*/
|
|
148
|
+
export const isPassword = (input) => typeof input === "string" && input.length === 97;
|
|
149
|
+
/**
|
|
150
|
+
* Checks if the input can be converted to a valid date.
|
|
151
|
+
*
|
|
152
|
+
* @param input - The input to be checked, can be of any type.
|
|
153
|
+
* @returns A boolean indicating whether the input is a valid date.
|
|
154
|
+
*/
|
|
155
|
+
export const isDate = (input) => !Number.isNaN(new Date(input).getTime()) ||
|
|
156
|
+
!Number.isNaN(Date.parse(input)) ||
|
|
157
|
+
!!input.match(/\b\d{2}[/.-]\d{2}[/.-]\d{4}\b/);
|
|
158
|
+
/**
|
|
159
|
+
* Checks if the input is a valid ID.
|
|
160
|
+
*
|
|
161
|
+
* @param input - The input to be checked, can be of any type.
|
|
162
|
+
* @returns A boolean indicating whether the input is a string representing a valid ID of length 32.
|
|
163
|
+
*/
|
|
164
|
+
export const isValidID = (input) => {
|
|
165
|
+
return typeof input === "string" && input.length === 32;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Checks if a given string is a valid JSON.
|
|
169
|
+
*
|
|
170
|
+
* @param {string} str - The string to be checked.
|
|
171
|
+
* @returns {boolean} Returns true if the string is valid JSON, otherwise false.
|
|
172
|
+
*/
|
|
173
|
+
export const isJSON = (str) => str === "null" || str === "undefined" || str[0] === "{" || str[0] === "[";
|
|
174
|
+
/**
|
|
175
|
+
* Identifies and returns properties that have changed between two objects.
|
|
176
|
+
*
|
|
177
|
+
* @param obj1 - The first object for comparison, with string keys and values.
|
|
178
|
+
* @param obj2 - The second object for comparison, with string keys and values.
|
|
179
|
+
* @returns A record of changed properties with original values from obj1 and new values from obj2, or null if no changes are found.
|
|
180
|
+
*/
|
|
181
|
+
export const findChangedProperties = (obj1, obj2) => {
|
|
182
|
+
const result = {};
|
|
183
|
+
for (const key1 in obj1)
|
|
184
|
+
if (Object.hasOwn(obj2, key1) && obj1[key1] !== obj2[key1])
|
|
185
|
+
result[obj1[key1]] = obj2[key1];
|
|
186
|
+
return Object.keys(result).length ? result : null;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Detects the field type of an input based on available types.
|
|
190
|
+
*
|
|
191
|
+
* @param input - The input whose field type is to be detected.
|
|
192
|
+
* @param availableTypes - An array of potential field types to consider.
|
|
193
|
+
* @returns The detected field type as a string, or undefined if no matching type is found.
|
|
194
|
+
*/
|
|
195
|
+
export const detectFieldType = (input, availableTypes) => {
|
|
196
|
+
if (input !== null && input !== undefined)
|
|
197
|
+
if (!Array.isArray(input)) {
|
|
198
|
+
if ((input === "0" ||
|
|
199
|
+
input === "1" ||
|
|
200
|
+
input === "true" ||
|
|
201
|
+
input === "false") &&
|
|
202
|
+
availableTypes.includes("boolean"))
|
|
203
|
+
return "boolean";
|
|
204
|
+
if (isNumber(input)) {
|
|
205
|
+
if (availableTypes.includes("table"))
|
|
206
|
+
return "table";
|
|
207
|
+
if (availableTypes.includes("date"))
|
|
208
|
+
return "date";
|
|
209
|
+
if (availableTypes.includes("number"))
|
|
210
|
+
return "number";
|
|
211
|
+
if (availableTypes.includes("string") && String(input).at(0) === "0")
|
|
212
|
+
return "string";
|
|
213
|
+
}
|
|
214
|
+
else if (typeof input === "string") {
|
|
215
|
+
if (availableTypes.includes("table") && isValidID(input))
|
|
216
|
+
return "table";
|
|
217
|
+
if (input.startsWith("[") && availableTypes.includes("array"))
|
|
218
|
+
return "array";
|
|
219
|
+
if (availableTypes.includes("email") && isEmail(input))
|
|
220
|
+
return "email";
|
|
221
|
+
if (availableTypes.includes("url") && isURL(input))
|
|
222
|
+
return "url";
|
|
223
|
+
if (availableTypes.includes("password") && isPassword(input))
|
|
224
|
+
return "password";
|
|
225
|
+
if (availableTypes.includes("json") && isJSON(input))
|
|
226
|
+
return "json";
|
|
227
|
+
if (availableTypes.includes("json") && isDate(input))
|
|
228
|
+
return "json";
|
|
229
|
+
if (availableTypes.includes("string") && isString(input))
|
|
230
|
+
return "string";
|
|
231
|
+
if (availableTypes.includes("ip") && isIP(input))
|
|
232
|
+
return "ip";
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
else
|
|
236
|
+
return "array";
|
|
237
|
+
return undefined;
|
|
238
|
+
};
|
|
239
|
+
export const isFieldType = (compareAtType, fieldType, fieldChildrenType) => {
|
|
240
|
+
if (fieldType) {
|
|
241
|
+
if (Array.isArray(fieldType)) {
|
|
242
|
+
if (fieldType.some((type) => Array.isArray(compareAtType)
|
|
243
|
+
? compareAtType.includes(type)
|
|
244
|
+
: compareAtType === type))
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
else if ((Array.isArray(compareAtType) && compareAtType.includes(fieldType)) ||
|
|
248
|
+
compareAtType === fieldType)
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
if (fieldChildrenType) {
|
|
252
|
+
if (Array.isArray(fieldChildrenType)) {
|
|
253
|
+
if (!isArrayOfObjects(fieldChildrenType)) {
|
|
254
|
+
if (fieldChildrenType.some((type) => Array.isArray(compareAtType)
|
|
255
|
+
? compareAtType.includes(type)
|
|
256
|
+
: compareAtType === type))
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if ((Array.isArray(compareAtType) &&
|
|
261
|
+
compareAtType.includes(fieldChildrenType)) ||
|
|
262
|
+
compareAtType === fieldChildrenType)
|
|
263
|
+
return true;
|
|
264
|
+
}
|
|
265
|
+
return false;
|
|
266
|
+
};
|
|
267
|
+
// Function to recursively flatten an array of objects and their nested children
|
|
268
|
+
export const flattenSchema = (schema, keepParents = false) => {
|
|
269
|
+
const result = [];
|
|
270
|
+
function _flattenHelper(item, parentKey) {
|
|
271
|
+
if (item.children && isArrayOfObjects(item.children)) {
|
|
272
|
+
if (keepParents)
|
|
273
|
+
result.push((({ children, ...rest }) => rest)(item));
|
|
274
|
+
for (const child of item.children)
|
|
275
|
+
_flattenHelper(child, item.key);
|
|
276
|
+
}
|
|
277
|
+
else
|
|
278
|
+
result.push({
|
|
279
|
+
...item,
|
|
280
|
+
key: parentKey ? `${parentKey}.${item.key}` : item.key,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
for (const item of schema)
|
|
284
|
+
_flattenHelper(item, "");
|
|
285
|
+
return result;
|
|
286
|
+
};
|
|
287
|
+
export const filterSchema = (schema, callback) => schema.filter((field) => {
|
|
288
|
+
if (field.children && isArrayOfObjects(field.children))
|
|
289
|
+
field.children = filterSchema(field.children, callback);
|
|
290
|
+
return callback(field);
|
|
291
|
+
});
|
|
292
|
+
/**
|
|
293
|
+
* Validates if the given value matches the specified field type(s).
|
|
294
|
+
*
|
|
295
|
+
* @param value - The value to be validated.
|
|
296
|
+
* @param fieldType - The expected field type or an array of possible field types.
|
|
297
|
+
* @param fieldChildrenType - Optional; the expected type(s) of children elements, used if the field type is an array.
|
|
298
|
+
* @returns A boolean indicating whether the value matches the specified field type(s).
|
|
299
|
+
*/
|
|
300
|
+
export const validateFieldType = (value, fieldType, fieldChildrenType) => {
|
|
301
|
+
if (value === null)
|
|
302
|
+
return true;
|
|
303
|
+
if (Array.isArray(fieldType)) {
|
|
304
|
+
const detectedFieldType = detectFieldType(value, fieldType);
|
|
305
|
+
if (!detectedFieldType)
|
|
306
|
+
return false;
|
|
307
|
+
fieldType = detectedFieldType;
|
|
308
|
+
}
|
|
309
|
+
if (fieldType === "array" && fieldChildrenType)
|
|
310
|
+
return value.every((v) => {
|
|
311
|
+
let _fieldChildrenType = fieldChildrenType;
|
|
312
|
+
if (Array.isArray(_fieldChildrenType)) {
|
|
313
|
+
const detectedFieldType = detectFieldType(v, _fieldChildrenType);
|
|
314
|
+
if (!detectedFieldType)
|
|
315
|
+
return false;
|
|
316
|
+
_fieldChildrenType = detectedFieldType;
|
|
317
|
+
}
|
|
318
|
+
return validateFieldType(v, _fieldChildrenType);
|
|
319
|
+
});
|
|
320
|
+
switch (fieldType) {
|
|
321
|
+
case "string":
|
|
322
|
+
return isString(value);
|
|
323
|
+
case "password":
|
|
324
|
+
return !Array.isArray(value) && !isObject(value); // accept
|
|
325
|
+
case "number":
|
|
326
|
+
return isNumber(value);
|
|
327
|
+
case "html":
|
|
328
|
+
return isHTML(value);
|
|
329
|
+
case "ip":
|
|
330
|
+
return isIP(value);
|
|
331
|
+
case "boolean":
|
|
332
|
+
return isBoolean(value);
|
|
333
|
+
case "date":
|
|
334
|
+
return isDate(value);
|
|
335
|
+
case "object":
|
|
336
|
+
return isObject(value);
|
|
337
|
+
case "array":
|
|
338
|
+
return Array.isArray(value);
|
|
339
|
+
case "email":
|
|
340
|
+
return isEmail(value);
|
|
341
|
+
case "url":
|
|
342
|
+
return isURL(value);
|
|
343
|
+
case "table":
|
|
344
|
+
// feat: check if id exists
|
|
345
|
+
if (Array.isArray(value))
|
|
346
|
+
return ((isArrayOfObjects(value) &&
|
|
347
|
+
value.every((element) => Object.hasOwn(element, "id") &&
|
|
348
|
+
(isValidID(element.id) || isNumber(element.id)))) ||
|
|
349
|
+
value.every(isNumber) ||
|
|
350
|
+
isValidID(value));
|
|
351
|
+
if (isObject(value))
|
|
352
|
+
return (Object.hasOwn(value, "id") &&
|
|
353
|
+
(isValidID(value.id) || isNumber(value.id)));
|
|
354
|
+
return isNumber(value) || isValidID(value);
|
|
355
|
+
case "id":
|
|
356
|
+
return isNumber(value) || isValidID(value);
|
|
357
|
+
case "json":
|
|
358
|
+
return isJSON(value) || Array.isArray(value) || isObject(value);
|
|
359
|
+
default:
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
export function FormatObjectCriteriaValue(value) {
|
|
364
|
+
switch (value[0]) {
|
|
365
|
+
case ">":
|
|
366
|
+
case "<":
|
|
367
|
+
return value[1] === "="
|
|
368
|
+
? [
|
|
369
|
+
value.slice(0, 2),
|
|
370
|
+
value.slice(2),
|
|
371
|
+
]
|
|
372
|
+
: [
|
|
373
|
+
value.slice(0, 1),
|
|
374
|
+
value.slice(1),
|
|
375
|
+
];
|
|
376
|
+
case "[":
|
|
377
|
+
return value[1] === "]"
|
|
378
|
+
? [
|
|
379
|
+
value.slice(0, 2),
|
|
380
|
+
value.slice(2).toString().split(","),
|
|
381
|
+
]
|
|
382
|
+
: ["[]", value.slice(1)];
|
|
383
|
+
case "!":
|
|
384
|
+
return ["=", "*"].includes(value[1])
|
|
385
|
+
? [
|
|
386
|
+
value.slice(0, 2),
|
|
387
|
+
value.slice(2),
|
|
388
|
+
]
|
|
389
|
+
: value[1] === "["
|
|
390
|
+
? [
|
|
391
|
+
value.slice(0, 3),
|
|
392
|
+
value.slice(3),
|
|
393
|
+
]
|
|
394
|
+
: [
|
|
395
|
+
`${value.slice(0, 1)}=`,
|
|
396
|
+
value.slice(1),
|
|
397
|
+
];
|
|
398
|
+
case "=":
|
|
399
|
+
return [
|
|
400
|
+
value.slice(0, 1),
|
|
401
|
+
value.slice(1),
|
|
402
|
+
];
|
|
403
|
+
case "*":
|
|
404
|
+
return [
|
|
405
|
+
value.slice(0, 1),
|
|
406
|
+
value.slice(1),
|
|
407
|
+
];
|
|
408
|
+
default:
|
|
409
|
+
return ["=", value];
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Get field from schema
|
|
414
|
+
*
|
|
415
|
+
* @export
|
|
416
|
+
* @param {string} keyPath Support dot notation path
|
|
417
|
+
* @param {Schema} schema
|
|
418
|
+
*/
|
|
419
|
+
export function getField(keyPath, schema) {
|
|
420
|
+
let RETURN = schema;
|
|
421
|
+
const keyPathSplited = keyPath.split(".");
|
|
422
|
+
for (const [index, key] of keyPathSplited.entries()) {
|
|
423
|
+
if (!isArrayOfObjects(RETURN))
|
|
424
|
+
return null;
|
|
425
|
+
const foundItem = RETURN.find((item) => item.key === key);
|
|
426
|
+
if (!foundItem)
|
|
427
|
+
return null;
|
|
428
|
+
if (index === keyPathSplited.length - 1)
|
|
429
|
+
RETURN = foundItem;
|
|
430
|
+
if ((foundItem.type === "array" || foundItem.type === "object") &&
|
|
431
|
+
foundItem.children &&
|
|
432
|
+
isArrayOfObjects(foundItem.children))
|
|
433
|
+
RETURN = foundItem.children;
|
|
434
|
+
}
|
|
435
|
+
if (!RETURN)
|
|
436
|
+
return null;
|
|
437
|
+
return isArrayOfObjects(RETURN) ? RETURN[0] : RETURN;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Override a schema field, key, type or other properties
|
|
441
|
+
*
|
|
442
|
+
* @export
|
|
443
|
+
* @param {string} keyPath Support dot notation path
|
|
444
|
+
* @param {Schema} schema
|
|
445
|
+
* @param {(Omit<Field, "key" | "type"> & {
|
|
446
|
+
* key?: string;
|
|
447
|
+
* type?: FieldType | FieldType[];
|
|
448
|
+
* })} field
|
|
449
|
+
*/
|
|
450
|
+
export function setField(keyPath, schema, field) {
|
|
451
|
+
const keyPathSplited = keyPath.split(".");
|
|
452
|
+
for (const [index, key] of keyPathSplited.entries()) {
|
|
453
|
+
const foundItem = schema.find((item) => item.key === key);
|
|
454
|
+
if (!foundItem)
|
|
455
|
+
return null;
|
|
456
|
+
if (index === keyPathSplited.length - 1) {
|
|
457
|
+
Object.assign(foundItem, field);
|
|
458
|
+
return foundItem;
|
|
459
|
+
}
|
|
460
|
+
if ((foundItem.type === "array" || foundItem.type === "object") &&
|
|
461
|
+
foundItem.children &&
|
|
462
|
+
isArrayOfObjects(foundItem.children))
|
|
463
|
+
schema = foundItem.children;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Remove field from schema
|
|
468
|
+
*
|
|
469
|
+
* @export
|
|
470
|
+
* @param {string} keyPath Support dot notation path
|
|
471
|
+
* @param {Schema} schema
|
|
472
|
+
*/
|
|
473
|
+
export function unsetField(keyPath, schema) {
|
|
474
|
+
const keyPathSplited = keyPath.split(".");
|
|
475
|
+
let parent = null;
|
|
476
|
+
let targetIndex;
|
|
477
|
+
for (const [index, key] of keyPathSplited.entries()) {
|
|
478
|
+
const foundItem = schema.find((item) => item.key === key);
|
|
479
|
+
if (!foundItem)
|
|
480
|
+
return null;
|
|
481
|
+
if (index === keyPathSplited.length - 1) {
|
|
482
|
+
if (parent) {
|
|
483
|
+
if (Array.isArray(parent)) {
|
|
484
|
+
if (targetIndex !== undefined)
|
|
485
|
+
parent.splice(targetIndex, 1);
|
|
486
|
+
}
|
|
487
|
+
else
|
|
488
|
+
delete parent[key];
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
const indexToRemove = schema.indexOf(foundItem);
|
|
492
|
+
if (indexToRemove !== -1)
|
|
493
|
+
schema.splice(indexToRemove, 1);
|
|
494
|
+
}
|
|
495
|
+
return foundItem;
|
|
496
|
+
}
|
|
497
|
+
if ((foundItem.type === "array" || foundItem.type === "object") &&
|
|
498
|
+
foundItem.children &&
|
|
499
|
+
isArrayOfObjects(foundItem.children)) {
|
|
500
|
+
parent = foundItem.children;
|
|
501
|
+
targetIndex = schema.indexOf(foundItem);
|
|
502
|
+
schema = foundItem.children;
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
parent = foundItem;
|
|
506
|
+
targetIndex = undefined;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { exec as execSync, execFile as execFileSync } from "node:child_process";
|
|
2
|
+
import { gunzip as gunzipSync, gzip as gzipSync } from "node:zlib";
|
|
3
|
+
import type { ComparisonOperator, Field, FieldType, Schema } from "./index.js";
|
|
4
|
+
export declare const exec: typeof execSync.__promisify__;
|
|
5
|
+
export declare const execFile: typeof execFileSync.__promisify__;
|
|
6
|
+
export declare const gzip: typeof gzipSync.__promisify__;
|
|
7
|
+
export declare const gunzip: typeof gunzipSync.__promisify__;
|
|
8
|
+
/**
|
|
9
|
+
* Generates a hashed password using SHA-256.
|
|
10
|
+
*
|
|
11
|
+
* @param password - The plain text password to hash.
|
|
12
|
+
* @returns A string containing the salt and the hashed password, separated by a colon.
|
|
13
|
+
*/
|
|
14
|
+
export declare const hashPassword: (password: string) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Compares a hashed password with an input password to verify a match.
|
|
17
|
+
*
|
|
18
|
+
* @param hashedPassword - The hashed password, containing both the salt and the hash, separated by a colon.
|
|
19
|
+
* @param inputPassword - The plain text input password to compare against the hashed password.
|
|
20
|
+
* @returns A boolean indicating whether the input password matches the hashed password.
|
|
21
|
+
*/
|
|
22
|
+
export declare const comparePassword: (hash: string, password: string) => boolean;
|
|
23
|
+
export declare const encodeID: (id: number | string, secretKeyOrSalt: string | number | Buffer) => string;
|
|
24
|
+
export declare const decodeID: (input: string, secretKeyOrSalt: string | number | Buffer) => number;
|
|
25
|
+
export declare const extractIdsFromSchema: (schema: Schema, secretKeyOrSalt: string | number | Buffer) => number[];
|
|
26
|
+
/**
|
|
27
|
+
* Finds the last ID number in a schema, potentially decoding it if encrypted.
|
|
28
|
+
*
|
|
29
|
+
* @param schema - The schema to search, defined as an array of schema objects.
|
|
30
|
+
* @param secretKeyOrSalt - The secret key or salt for decoding an encrypted ID, can be a string, number, or Buffer.
|
|
31
|
+
* @returns The last ID number in the schema, decoded if necessary.
|
|
32
|
+
*/
|
|
33
|
+
export declare const findLastIdNumber: (schema: Schema, secretKeyOrSalt: string | number | Buffer) => number;
|
|
34
|
+
/**
|
|
35
|
+
* Adds or updates IDs in a schema, encoding them using a provided secret key or salt.
|
|
36
|
+
*
|
|
37
|
+
* @param schema - The schema to update, defined as an array of schema objects.
|
|
38
|
+
* @param oldIndex - The starting index for generating new IDs, defaults to 0.
|
|
39
|
+
* @param secretKeyOrSalt - The secret key or salt for encoding IDs, can be a string, number, or Buffer.
|
|
40
|
+
* @param encodeIDs - If true, IDs will be encoded, else they will remain as numbers.
|
|
41
|
+
* @returns The updated schema with encoded IDs.
|
|
42
|
+
*/
|
|
43
|
+
export declare const addIdToSchema: (schema: Schema, startWithID: number, secretKeyOrSalt: string | number | Buffer, encodeIDs?: boolean) => Field[];
|
|
44
|
+
export declare const encodeSchemaID: (schema: Schema, secretKeyOrSalt: string | number | Buffer) => Schema;
|
|
45
|
+
export declare const hashString: (str: string) => string;
|
|
46
|
+
/**
|
|
47
|
+
* Evaluates a comparison between two values based on a specified operator and field types.
|
|
48
|
+
*
|
|
49
|
+
* @param operator - The comparison operator (e.g., '=', '!=', '>', '<', '>=', '<=', '[]', '![]', '*', '!*').
|
|
50
|
+
* @param originalValue - The value to compare, can be a single value or an array of values.
|
|
51
|
+
* @param comparedValue - The value or values to compare against.
|
|
52
|
+
* @param fieldType - Optional type of the field to guide comparison (e.g., 'password', 'boolean').
|
|
53
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
54
|
+
* @returns boolean - Result of the comparison operation.
|
|
55
|
+
*
|
|
56
|
+
* Note: Handles various data types and comparison logic, including special handling for passwords and regex patterns.
|
|
57
|
+
*/
|
|
58
|
+
export declare const compare: (operator: ComparisonOperator, originalValue: string | number | boolean | null | (string | number | boolean | null)[], comparedValue: string | number | boolean | null | (string | number | boolean | null)[], fieldType?: FieldType | FieldType[]) => boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Helper function to check equality based on the field type.
|
|
61
|
+
*
|
|
62
|
+
* @param originalValue - The original value.
|
|
63
|
+
* @param comparedValue - The value to compare against.
|
|
64
|
+
* @param fieldType - Type of the field.
|
|
65
|
+
* @returns boolean - Result of the equality check.
|
|
66
|
+
*/
|
|
67
|
+
export declare const isEqual: (originalValue: string | number | boolean | null | (string | number | boolean | null)[], comparedValue: string | number | boolean | null | (string | number | boolean | null)[], fieldType?: FieldType) => boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Helper function to check array equality.
|
|
70
|
+
*
|
|
71
|
+
* @param originalValue - The original value.
|
|
72
|
+
* @param comparedValue - The value to compare against.
|
|
73
|
+
* @returns boolean - Result of the array equality check.
|
|
74
|
+
*/
|
|
75
|
+
export declare const isArrayEqual: (originalValue: string | number | boolean | null | (string | number | boolean | null)[], comparedValue: string | number | boolean | null | (string | number | boolean | null)[]) => boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Helper function to check wildcard pattern matching using regex.
|
|
78
|
+
*
|
|
79
|
+
* @param originalValue - The original value.
|
|
80
|
+
* @param comparedValue - The value with wildcard pattern.
|
|
81
|
+
* @returns boolean - Result of the wildcard pattern matching.
|
|
82
|
+
*/
|
|
83
|
+
export declare const isWildcardMatch: (originalValue: string | number | boolean | null | (string | number | boolean | null)[], comparedValue: string | number | boolean | null | (string | number | boolean | null)[]) => boolean;
|