inibase 1.1.5 → 1.1.7
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/dist/index.d.ts +2 -2
- package/dist/index.js +5 -2
- package/dist/utils.d.ts +31 -34
- package/dist/utils.js +85 -52
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "dotenv/config";
|
|
2
2
|
export interface Data {
|
|
3
|
-
id?:
|
|
3
|
+
id?: string;
|
|
4
4
|
[key: string]: any;
|
|
5
5
|
createdAt?: number;
|
|
6
6
|
updatedAt?: number;
|
|
@@ -40,7 +40,7 @@ export type pageInfo = {
|
|
|
40
40
|
export type Criteria = ({
|
|
41
41
|
[logic in "and" | "or"]?: Criteria | (string | number | boolean | null)[];
|
|
42
42
|
} & {
|
|
43
|
-
[key: string]: string | number | boolean | undefined | Criteria;
|
|
43
|
+
[key: string]: string | number | boolean | undefined | Criteria | (string | number | boolean)[];
|
|
44
44
|
}) | null;
|
|
45
45
|
type Entries<T> = {
|
|
46
46
|
[K in keyof T]: [K, T[K]];
|
package/dist/index.js
CHANGED
|
@@ -987,11 +987,14 @@ export default class Inibase {
|
|
|
987
987
|
}
|
|
988
988
|
const [searchResult, totalLines, linesNumbers] = await File.search(join(tablePath, `${key}${this.getFileExtension(tableName)}`), searchOperator ?? "=", searchComparedAtValue ?? null, searchLogicalOperator, allTrue ? searchIn : undefined, field?.type, field?.children, options.perPage, (options.page - 1) * options.perPage + 1, true, this.salt);
|
|
989
989
|
if (searchResult) {
|
|
990
|
-
|
|
990
|
+
const formatedSearchResult = Object.fromEntries(Object.entries(searchResult).map(([id, value]) => {
|
|
991
991
|
const nestedObj = {};
|
|
992
992
|
this._setNestedKey(nestedObj, key, value);
|
|
993
993
|
return [id, nestedObj];
|
|
994
|
-
}))
|
|
994
|
+
}));
|
|
995
|
+
RETURN = allTrue
|
|
996
|
+
? formatedSearchResult
|
|
997
|
+
: Utils.deepMerge(RETURN, formatedSearchResult);
|
|
995
998
|
this.totalItems.set(`${tableName}-${key}`, totalLines);
|
|
996
999
|
if (linesNumbers?.size) {
|
|
997
1000
|
if (searchIn) {
|
package/dist/utils.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type { ComparisonOperator, Field, FieldType, Schema } from "./index.js";
|
|
|
7
7
|
*
|
|
8
8
|
* Note: Considers empty arrays and arrays where every element is an object.
|
|
9
9
|
*/
|
|
10
|
-
export declare const isArrayOfObjects: (input:
|
|
10
|
+
export declare const isArrayOfObjects: (input: unknown) => input is Record<any, any>[];
|
|
11
11
|
/**
|
|
12
12
|
* Type guard function to check if the input is an array of arrays.
|
|
13
13
|
*
|
|
@@ -16,7 +16,7 @@ export declare const isArrayOfObjects: (input: any) => input is Record<any, any>
|
|
|
16
16
|
*
|
|
17
17
|
* Note: Considers empty arrays and arrays where every element is also an array.
|
|
18
18
|
*/
|
|
19
|
-
export declare const isArrayOfArrays: (input:
|
|
19
|
+
export declare const isArrayOfArrays: (input: unknown) => input is any[][];
|
|
20
20
|
/**
|
|
21
21
|
* Type guard function to check if the input is an array of nulls or an array of arrays of nulls.
|
|
22
22
|
*
|
|
@@ -25,7 +25,7 @@ export declare const isArrayOfArrays: (input: any) => input is any[][];
|
|
|
25
25
|
*
|
|
26
26
|
* Note: Recursively checks each element, allowing for nested arrays of nulls.
|
|
27
27
|
*/
|
|
28
|
-
export declare const isArrayOfNulls: (input:
|
|
28
|
+
export declare const isArrayOfNulls: (input: unknown) => input is null[] | null[][];
|
|
29
29
|
/**
|
|
30
30
|
* Type guard function to check if the input is an object.
|
|
31
31
|
*
|
|
@@ -34,17 +34,7 @@ export declare const isArrayOfNulls: (input: any) => input is null[] | null[][];
|
|
|
34
34
|
*
|
|
35
35
|
* 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.
|
|
36
36
|
*/
|
|
37
|
-
export declare const isObject: (
|
|
38
|
-
/**
|
|
39
|
-
* 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.
|
|
40
|
-
*
|
|
41
|
-
* @param target - The target object to merge properties into.
|
|
42
|
-
* @param source - The source object from which properties are merged.
|
|
43
|
-
* @returns any - The modified target object with merged properties.
|
|
44
|
-
*
|
|
45
|
-
* Note: Performs a deep merge for nested objects. Non-object properties are directly overwritten.
|
|
46
|
-
*/
|
|
47
|
-
export declare const deepMerge: (target: any, source: any) => any;
|
|
37
|
+
export declare const isObject: (object: unknown) => object is Record<any, any>;
|
|
48
38
|
/**
|
|
49
39
|
* Type guard function to check if the input is a number.
|
|
50
40
|
*
|
|
@@ -53,7 +43,7 @@ export declare const deepMerge: (target: any, source: any) => any;
|
|
|
53
43
|
*
|
|
54
44
|
* 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.
|
|
55
45
|
*/
|
|
56
|
-
export declare const isNumber: (input:
|
|
46
|
+
export declare const isNumber: (input: unknown) => input is number;
|
|
57
47
|
/**
|
|
58
48
|
* Checks if the input is a valid email format.
|
|
59
49
|
*
|
|
@@ -62,7 +52,7 @@ export declare const isNumber: (input: any) => input is number;
|
|
|
62
52
|
*
|
|
63
53
|
* Note: Uses a regular expression to validate the email format, ensuring it has parts separated by '@' and contains a domain with a period.
|
|
64
54
|
*/
|
|
65
|
-
export declare const isEmail: (input:
|
|
55
|
+
export declare const isEmail: (input: unknown) => boolean;
|
|
66
56
|
/**
|
|
67
57
|
* Checks if the input is a valid URL format.
|
|
68
58
|
*
|
|
@@ -72,7 +62,7 @@ export declare const isEmail: (input: any) => boolean;
|
|
|
72
62
|
* Note: Validates URLs including protocols (http/https), domain names, IP addresses, ports, paths, query strings, and fragments.
|
|
73
63
|
* Also recognizes 'tel:' and 'mailto:' as valid URL formats, as well as strings starting with '#' without spaces.
|
|
74
64
|
*/
|
|
75
|
-
export declare const isURL: (input:
|
|
65
|
+
export declare const isURL: (input: unknown) => boolean;
|
|
76
66
|
/**
|
|
77
67
|
* Checks if the input contains HTML tags or entities.
|
|
78
68
|
*
|
|
@@ -82,7 +72,7 @@ export declare const isURL: (input: any) => boolean;
|
|
|
82
72
|
* Note: Uses a regular expression to detect HTML tags (like <tag>) and entities (like &entity;).
|
|
83
73
|
* Recognizes both opening and closing tags, as well as self-closing tags.
|
|
84
74
|
*/
|
|
85
|
-
export declare const isHTML: (input:
|
|
75
|
+
export declare const isHTML: (input: unknown) => boolean;
|
|
86
76
|
/**
|
|
87
77
|
* Type guard function to check if the input is a string, excluding strings that match specific formats (number, boolean, email, URL, IP).
|
|
88
78
|
*
|
|
@@ -91,7 +81,7 @@ export declare const isHTML: (input: any) => boolean;
|
|
|
91
81
|
*
|
|
92
82
|
* Note: Validates the input against being a number, boolean, email, URL, or IP address to ensure it's a general string.
|
|
93
83
|
*/
|
|
94
|
-
export declare const isString: (input:
|
|
84
|
+
export declare const isString: (input: unknown) => input is string;
|
|
95
85
|
/**
|
|
96
86
|
* Checks if the input is a valid IP address format.
|
|
97
87
|
*
|
|
@@ -100,7 +90,7 @@ export declare const isString: (input: any) => input is string;
|
|
|
100
90
|
*
|
|
101
91
|
* Note: Uses a regular expression to validate IP addresses, ensuring they consist of four octets, each ranging from 0 to 255.
|
|
102
92
|
*/
|
|
103
|
-
export declare const isIP: (input:
|
|
93
|
+
export declare const isIP: (input: unknown) => input is string;
|
|
104
94
|
/**
|
|
105
95
|
* Type guard function to check if the input is a boolean or a string representation of a boolean.
|
|
106
96
|
*
|
|
@@ -109,7 +99,7 @@ export declare const isIP: (input: any) => boolean;
|
|
|
109
99
|
*
|
|
110
100
|
* Note: Recognizes both boolean literals (true, false) and their string representations ("true", "false").
|
|
111
101
|
*/
|
|
112
|
-
export declare const isBoolean: (input:
|
|
102
|
+
export declare const isBoolean: (input: unknown) => input is boolean;
|
|
113
103
|
/**
|
|
114
104
|
* Type guard function to check if the input is a password based on a specific length criterion.
|
|
115
105
|
*
|
|
@@ -118,28 +108,38 @@ export declare const isBoolean: (input: any) => input is boolean;
|
|
|
118
108
|
*
|
|
119
109
|
* Note: Specifically checks for string length to determine if it matches the defined password length criterion.
|
|
120
110
|
*/
|
|
121
|
-
export declare const isPassword: (input:
|
|
111
|
+
export declare const isPassword: (input: unknown) => input is string;
|
|
122
112
|
/**
|
|
123
113
|
* Checks if the input can be converted to a valid date.
|
|
124
114
|
*
|
|
125
115
|
* @param input - The input to be checked, can be of any type.
|
|
126
116
|
* @returns A boolean indicating whether the input is a valid date.
|
|
127
117
|
*/
|
|
128
|
-
export declare
|
|
118
|
+
export declare const isDate: (input: unknown) => input is Date | number;
|
|
129
119
|
/**
|
|
130
120
|
* Checks if the input is a valid ID.
|
|
131
121
|
*
|
|
132
122
|
* @param input - The input to be checked, can be of any type.
|
|
133
123
|
* @returns A boolean indicating whether the input is a string representing a valid ID of length 32.
|
|
134
124
|
*/
|
|
135
|
-
export declare const isValidID: (input:
|
|
125
|
+
export declare const isValidID: (input: unknown) => input is string;
|
|
136
126
|
/**
|
|
137
127
|
* Checks if a given string is a valid JSON.
|
|
138
128
|
*
|
|
139
|
-
* @param {string}
|
|
129
|
+
* @param {string} input - The string to be checked.
|
|
140
130
|
* @returns {boolean} Returns true if the string is valid JSON, otherwise false.
|
|
141
131
|
*/
|
|
142
|
-
export declare const isStringified: (
|
|
132
|
+
export declare const isStringified: (input: unknown) => boolean;
|
|
133
|
+
/**
|
|
134
|
+
* 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.
|
|
135
|
+
*
|
|
136
|
+
* @param target - The target object to merge properties into.
|
|
137
|
+
* @param source - The source object from which properties are merged.
|
|
138
|
+
* @returns any - The modified target object with merged properties.
|
|
139
|
+
*
|
|
140
|
+
* Note: Performs a deep merge for nested objects. Non-object properties are directly overwritten.
|
|
141
|
+
*/
|
|
142
|
+
export declare const deepMerge: (target: any, source: any) => any;
|
|
143
143
|
/**
|
|
144
144
|
* Identifies and returns properties that have changed between two objects.
|
|
145
145
|
*
|
|
@@ -168,10 +168,7 @@ export declare const filterSchema: (schema: Schema, callback: (arg0: Field) => b
|
|
|
168
168
|
* @returns A boolean indicating whether the value matches the specified field type(s).
|
|
169
169
|
*/
|
|
170
170
|
export declare const validateFieldType: (value: any, fieldType: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[]) => boolean;
|
|
171
|
-
export declare
|
|
172
|
-
ComparisonOperator,
|
|
173
|
-
string | number | boolean | null | (string | number | null)[]
|
|
174
|
-
];
|
|
171
|
+
export declare const FormatObjectCriteriaValue: (value: string) => [ComparisonOperator, string | number | boolean | null | (string | number | null)[]];
|
|
175
172
|
/**
|
|
176
173
|
* Get field from schema
|
|
177
174
|
*
|
|
@@ -179,7 +176,7 @@ export declare function FormatObjectCriteriaValue(value: string): [
|
|
|
179
176
|
* @param {string} keyPath Support dot notation path
|
|
180
177
|
* @param {Schema} schema
|
|
181
178
|
*/
|
|
182
|
-
export declare
|
|
179
|
+
export declare const getField: (keyPath: string, schema: Schema) => Field;
|
|
183
180
|
/**
|
|
184
181
|
* Override a schema field, key, type or other properties
|
|
185
182
|
*
|
|
@@ -191,10 +188,10 @@ export declare function getField(keyPath: string, schema: Schema): Field;
|
|
|
191
188
|
* type?: FieldType | FieldType[];
|
|
192
189
|
* })} field
|
|
193
190
|
*/
|
|
194
|
-
export declare
|
|
191
|
+
export declare const setField: (keyPath: string, schema: Schema, field: Omit<Field, "key" | "type"> & {
|
|
195
192
|
key?: string;
|
|
196
193
|
type?: FieldType | FieldType[];
|
|
197
|
-
})
|
|
194
|
+
}) => Field;
|
|
198
195
|
/**
|
|
199
196
|
* Remove field from schema
|
|
200
197
|
*
|
|
@@ -202,4 +199,4 @@ export declare function setField(keyPath: string, schema: Schema, field: Omit<Fi
|
|
|
202
199
|
* @param {string} keyPath Support dot notation path
|
|
203
200
|
* @param {Schema} schema
|
|
204
201
|
*/
|
|
205
|
-
export declare
|
|
202
|
+
export declare const unsetField: (keyPath: string, schema: Schema) => Field;
|
package/dist/utils.js
CHANGED
|
@@ -15,7 +15,7 @@ export const isArrayOfObjects = (input) => Array.isArray(input) && (input.length
|
|
|
15
15
|
*
|
|
16
16
|
* Note: Considers empty arrays and arrays where every element is also an array.
|
|
17
17
|
*/
|
|
18
|
-
export const isArrayOfArrays = (input) => Array.isArray(input) &&
|
|
18
|
+
export const isArrayOfArrays = (input) => Array.isArray(input) && input.length > 0 && input.every(Array.isArray);
|
|
19
19
|
/**
|
|
20
20
|
* Type guard function to check if the input is an array of nulls or an array of arrays of nulls.
|
|
21
21
|
*
|
|
@@ -24,7 +24,8 @@ export const isArrayOfArrays = (input) => Array.isArray(input) && (input.length
|
|
|
24
24
|
*
|
|
25
25
|
* Note: Recursively checks each element, allowing for nested arrays of nulls.
|
|
26
26
|
*/
|
|
27
|
-
export const isArrayOfNulls = (input) =>
|
|
27
|
+
export const isArrayOfNulls = (input) => Array.isArray(input) &&
|
|
28
|
+
input.every((_input) => Array.isArray(_input) ? isArrayOfNulls(_input) : _input === null);
|
|
28
29
|
/**
|
|
29
30
|
* Type guard function to check if the input is an object.
|
|
30
31
|
*
|
|
@@ -33,29 +34,9 @@ export const isArrayOfNulls = (input) => input.every((_input) => Array.isArray(_
|
|
|
33
34
|
*
|
|
34
35
|
* 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
|
*/
|
|
36
|
-
export const isObject = (
|
|
37
|
-
((typeof
|
|
38
|
-
|
|
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
|
-
};
|
|
37
|
+
export const isObject = (object) => object != null &&
|
|
38
|
+
((typeof object === "object" && !Array.isArray(object)) ||
|
|
39
|
+
object.constructor?.name === "Object");
|
|
59
40
|
/**
|
|
60
41
|
* Type guard function to check if the input is a number.
|
|
61
42
|
*
|
|
@@ -64,7 +45,24 @@ export const deepMerge = (target, source) => {
|
|
|
64
45
|
*
|
|
65
46
|
* 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
47
|
*/
|
|
67
|
-
export const isNumber = (input) =>
|
|
48
|
+
export const isNumber = (input) => {
|
|
49
|
+
// Case 1: It's already a number (and not NaN/Infinity).
|
|
50
|
+
if (typeof input === "number")
|
|
51
|
+
return !Number.isNaN(input) && Number.isFinite(input);
|
|
52
|
+
// Case 2: It's a string that can parse to a finite number.
|
|
53
|
+
if (typeof input === "string") {
|
|
54
|
+
const trimmed = input.trim();
|
|
55
|
+
// Empty string or whitespace-only => not numeric
|
|
56
|
+
if (!trimmed)
|
|
57
|
+
return false;
|
|
58
|
+
const parsed = Number(trimmed); // or parseFloat(trimmed)
|
|
59
|
+
return !Number.isNaN(parsed) && Number.isFinite(parsed);
|
|
60
|
+
}
|
|
61
|
+
// Otherwise, not a numeric string or number
|
|
62
|
+
return false;
|
|
63
|
+
};
|
|
64
|
+
// As a literal (no double-escaping).
|
|
65
|
+
const emailPattern = /^[A-Za-z0-9!#%&'*+\/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#%&'*+\/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?$/;
|
|
68
66
|
/**
|
|
69
67
|
* Checks if the input is a valid email format.
|
|
70
68
|
*
|
|
@@ -73,7 +71,22 @@ export const isNumber = (input) => !Number.isNaN(Number.parseFloat(input)) && !N
|
|
|
73
71
|
*
|
|
74
72
|
* Note: Uses a regular expression to validate the email format, ensuring it has parts separated by '@' and contains a domain with a period.
|
|
75
73
|
*/
|
|
76
|
-
export const isEmail = (input) =>
|
|
74
|
+
export const isEmail = (input) => typeof input === "string" && emailPattern.test(String(input));
|
|
75
|
+
const urlPattern = new RegExp("^" +
|
|
76
|
+
// Optional protocol
|
|
77
|
+
"(https?:\\/\\/)?" +
|
|
78
|
+
// domain name (with underscore allowed), localhost, or ipv4
|
|
79
|
+
"((([a-z\\d_]([a-z\\d_\\-]*[a-z\\d_])*)\\.)+[a-z]{2,}|" +
|
|
80
|
+
"localhost|" +
|
|
81
|
+
"((\\d{1,3}\\.){3}\\d{1,3}))" +
|
|
82
|
+
// optional port
|
|
83
|
+
"(\\:\\d+)?" +
|
|
84
|
+
// path
|
|
85
|
+
"(\\/[-a-z\\d%_.~+]*)*" +
|
|
86
|
+
// query string
|
|
87
|
+
"(\\?[;&a-z\\d%_.~+=-]*)?" +
|
|
88
|
+
// fragment
|
|
89
|
+
"(\\#[-a-z\\d_]*)?$", "i");
|
|
77
90
|
/**
|
|
78
91
|
* Checks if the input is a valid URL format.
|
|
79
92
|
*
|
|
@@ -88,17 +101,12 @@ export const isURL = (input) => {
|
|
|
88
101
|
return false;
|
|
89
102
|
if ((input[0] === "#" && !input.includes(" ")) ||
|
|
90
103
|
input.startsWith("tel:") ||
|
|
91
|
-
input.startsWith("mailto:")
|
|
104
|
+
input.startsWith("mailto:") ||
|
|
105
|
+
URL.canParse(input))
|
|
92
106
|
return true;
|
|
93
|
-
|
|
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);
|
|
107
|
+
return urlPattern.test(input);
|
|
101
108
|
};
|
|
109
|
+
const htmlPattern = /<([A-Za-z][A-Za-z0-9-]*)(\s+[A-Za-z-]+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)*\s*>/;
|
|
102
110
|
/**
|
|
103
111
|
* Checks if the input contains HTML tags or entities.
|
|
104
112
|
*
|
|
@@ -108,7 +116,7 @@ export const isURL = (input) => {
|
|
|
108
116
|
* Note: Uses a regular expression to detect HTML tags (like <tag>) and entities (like &entity;).
|
|
109
117
|
* Recognizes both opening and closing tags, as well as self-closing tags.
|
|
110
118
|
*/
|
|
111
|
-
export const isHTML = (input) =>
|
|
119
|
+
export const isHTML = (input) => typeof input === "string" && htmlPattern.test(input);
|
|
112
120
|
/**
|
|
113
121
|
* Type guard function to check if the input is a string, excluding strings that match specific formats (number, boolean, email, URL, IP).
|
|
114
122
|
*
|
|
@@ -119,6 +127,7 @@ export const isHTML = (input) => /<\/?\s*[a-z-][^>]*\s*>|(\&(?:[\w\d]+|#\d+|#x[a
|
|
|
119
127
|
*/
|
|
120
128
|
export const isString = (input) => Object.prototype.toString.call(input) === "[object String]" &&
|
|
121
129
|
(!isNumber(input) || String(input).at(0) === "0");
|
|
130
|
+
const ipPattern = /^(?:(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)\.){3}(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)$/;
|
|
122
131
|
/**
|
|
123
132
|
* Checks if the input is a valid IP address format.
|
|
124
133
|
*
|
|
@@ -127,7 +136,7 @@ export const isString = (input) => Object.prototype.toString.call(input) === "[o
|
|
|
127
136
|
*
|
|
128
137
|
* Note: Uses a regular expression to validate IP addresses, ensuring they consist of four octets, each ranging from 0 to 255.
|
|
129
138
|
*/
|
|
130
|
-
export const isIP = (input) =>
|
|
139
|
+
export const isIP = (input) => typeof input === "string" && ipPattern.test(input);
|
|
131
140
|
/**
|
|
132
141
|
* Type guard function to check if the input is a boolean or a string representation of a boolean.
|
|
133
142
|
*
|
|
@@ -152,7 +161,7 @@ export const isPassword = (input) => typeof input === "string" && input.length =
|
|
|
152
161
|
* @param input - The input to be checked, can be of any type.
|
|
153
162
|
* @returns A boolean indicating whether the input is a valid date.
|
|
154
163
|
*/
|
|
155
|
-
export
|
|
164
|
+
export const isDate = (input) => {
|
|
156
165
|
// Check if the input is null, undefined, or an empty string
|
|
157
166
|
if (input == null || input === "")
|
|
158
167
|
return false;
|
|
@@ -165,7 +174,7 @@ export function isDate(input) {
|
|
|
165
174
|
const date = new Date(numTimestamp);
|
|
166
175
|
// Check if the date is valid
|
|
167
176
|
return date.getTime() === numTimestamp;
|
|
168
|
-
}
|
|
177
|
+
};
|
|
169
178
|
/**
|
|
170
179
|
* Checks if the input is a valid ID.
|
|
171
180
|
*
|
|
@@ -178,10 +187,34 @@ export const isValidID = (input) => {
|
|
|
178
187
|
/**
|
|
179
188
|
* Checks if a given string is a valid JSON.
|
|
180
189
|
*
|
|
181
|
-
* @param {string}
|
|
190
|
+
* @param {string} input - The string to be checked.
|
|
182
191
|
* @returns {boolean} Returns true if the string is valid JSON, otherwise false.
|
|
183
192
|
*/
|
|
184
|
-
export const isStringified = (
|
|
193
|
+
export const isStringified = (input) => typeof input === "string" &&
|
|
194
|
+
(input === "null" ||
|
|
195
|
+
input === "undefined" ||
|
|
196
|
+
input[0] === "{" ||
|
|
197
|
+
input[0] === "[");
|
|
198
|
+
/**
|
|
199
|
+
* 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.
|
|
200
|
+
*
|
|
201
|
+
* @param target - The target object to merge properties into.
|
|
202
|
+
* @param source - The source object from which properties are merged.
|
|
203
|
+
* @returns any - The modified target object with merged properties.
|
|
204
|
+
*
|
|
205
|
+
* Note: Performs a deep merge for nested objects. Non-object properties are directly overwritten.
|
|
206
|
+
*/
|
|
207
|
+
export const deepMerge = (target, source) => {
|
|
208
|
+
for (const key in source) {
|
|
209
|
+
if (Object.hasOwn(source, key)) {
|
|
210
|
+
if (isObject(source[key]) && isObject(target[key]))
|
|
211
|
+
target[key] = deepMerge(target[key], source[key]);
|
|
212
|
+
else if (source[key] !== null)
|
|
213
|
+
target[key] = source[key];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return target;
|
|
217
|
+
};
|
|
185
218
|
/**
|
|
186
219
|
* Identifies and returns properties that have changed between two objects.
|
|
187
220
|
*
|
|
@@ -278,7 +311,7 @@ export const isFieldType = (compareAtType, fieldType, fieldChildrenType) => {
|
|
|
278
311
|
// Function to recursively flatten an array of objects and their nested children
|
|
279
312
|
export const flattenSchema = (schema, keepParents = false) => {
|
|
280
313
|
const result = [];
|
|
281
|
-
|
|
314
|
+
const _flattenHelper = (item, parentKey) => {
|
|
282
315
|
if (item.children && isArrayOfObjects(item.children)) {
|
|
283
316
|
if (keepParents)
|
|
284
317
|
result.push((({ children, ...rest }) => rest)(item));
|
|
@@ -290,7 +323,7 @@ export const flattenSchema = (schema, keepParents = false) => {
|
|
|
290
323
|
...item,
|
|
291
324
|
key: parentKey ? `${parentKey}.${item.key}` : item.key,
|
|
292
325
|
});
|
|
293
|
-
}
|
|
326
|
+
};
|
|
294
327
|
for (const item of schema)
|
|
295
328
|
_flattenHelper(item, "");
|
|
296
329
|
return result;
|
|
@@ -372,7 +405,7 @@ export const validateFieldType = (value, fieldType, fieldChildrenType) => {
|
|
|
372
405
|
return false;
|
|
373
406
|
}
|
|
374
407
|
};
|
|
375
|
-
export
|
|
408
|
+
export const FormatObjectCriteriaValue = (value) => {
|
|
376
409
|
switch (value[0]) {
|
|
377
410
|
case ">":
|
|
378
411
|
case "<":
|
|
@@ -420,7 +453,7 @@ export function FormatObjectCriteriaValue(value) {
|
|
|
420
453
|
default:
|
|
421
454
|
return ["=", value];
|
|
422
455
|
}
|
|
423
|
-
}
|
|
456
|
+
};
|
|
424
457
|
/**
|
|
425
458
|
* Get field from schema
|
|
426
459
|
*
|
|
@@ -428,7 +461,7 @@ export function FormatObjectCriteriaValue(value) {
|
|
|
428
461
|
* @param {string} keyPath Support dot notation path
|
|
429
462
|
* @param {Schema} schema
|
|
430
463
|
*/
|
|
431
|
-
export
|
|
464
|
+
export const getField = (keyPath, schema) => {
|
|
432
465
|
let RETURN = schema;
|
|
433
466
|
const keyPathSplited = keyPath.split(".");
|
|
434
467
|
for (const [index, key] of keyPathSplited.entries()) {
|
|
@@ -447,7 +480,7 @@ export function getField(keyPath, schema) {
|
|
|
447
480
|
if (!RETURN)
|
|
448
481
|
return null;
|
|
449
482
|
return isArrayOfObjects(RETURN) ? RETURN[0] : RETURN;
|
|
450
|
-
}
|
|
483
|
+
};
|
|
451
484
|
/**
|
|
452
485
|
* Override a schema field, key, type or other properties
|
|
453
486
|
*
|
|
@@ -459,7 +492,7 @@ export function getField(keyPath, schema) {
|
|
|
459
492
|
* type?: FieldType | FieldType[];
|
|
460
493
|
* })} field
|
|
461
494
|
*/
|
|
462
|
-
export
|
|
495
|
+
export const setField = (keyPath, schema, field) => {
|
|
463
496
|
const keyPathSplited = keyPath.split(".");
|
|
464
497
|
for (const [index, key] of keyPathSplited.entries()) {
|
|
465
498
|
const foundItem = schema.find((item) => item.key === key);
|
|
@@ -474,7 +507,7 @@ export function setField(keyPath, schema, field) {
|
|
|
474
507
|
isArrayOfObjects(foundItem.children))
|
|
475
508
|
schema = foundItem.children;
|
|
476
509
|
}
|
|
477
|
-
}
|
|
510
|
+
};
|
|
478
511
|
/**
|
|
479
512
|
* Remove field from schema
|
|
480
513
|
*
|
|
@@ -482,7 +515,7 @@ export function setField(keyPath, schema, field) {
|
|
|
482
515
|
* @param {string} keyPath Support dot notation path
|
|
483
516
|
* @param {Schema} schema
|
|
484
517
|
*/
|
|
485
|
-
export
|
|
518
|
+
export const unsetField = (keyPath, schema) => {
|
|
486
519
|
const keyPathSplited = keyPath.split(".");
|
|
487
520
|
let parent = null;
|
|
488
521
|
let targetIndex;
|
|
@@ -518,4 +551,4 @@ export function unsetField(keyPath, schema) {
|
|
|
518
551
|
targetIndex = undefined;
|
|
519
552
|
}
|
|
520
553
|
}
|
|
521
|
-
}
|
|
554
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inibase",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Karim Amahtil",
|
|
@@ -69,9 +69,9 @@
|
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@biomejs/biome": "1.9.4",
|
|
72
|
-
"@evilmartians/lefthook": "^1.10.1",
|
|
73
72
|
"@types/bun": "^1.1.10",
|
|
74
73
|
"@types/node": "^22.7.4",
|
|
74
|
+
"lefthook": "^1.10.1",
|
|
75
75
|
"tinybench": "^3.0.7",
|
|
76
76
|
"typescript": "^5.7.2"
|
|
77
77
|
},
|
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"prepublish": "npx -q tsc",
|
|
85
85
|
"build": "npx -q tsc",
|
|
86
86
|
"benchmark": "./benchmark/run.js",
|
|
87
|
-
"test": "npx -q tsx ./tests/inibase.test.ts"
|
|
87
|
+
"test": "npx -q tsx ./tests/inibase.test.ts",
|
|
88
|
+
"test:utils": "npx -q tsx ./tests/utils.test.ts"
|
|
88
89
|
}
|
|
89
90
|
}
|