inibase 1.0.0-rc.25 → 1.0.0-rc.26
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/file.d.ts +136 -6
- package/dist/file.js +275 -58
- package/dist/index.js +22 -20
- package/dist/utils.d.ts +155 -0
- package/dist/utils.js +155 -0
- package/dist/utils.server.d.ts +42 -0
- package/dist/utils.server.js +42 -0
- package/package.json +1 -1
package/dist/file.d.ts
CHANGED
|
@@ -1,29 +1,159 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import { ComparisonOperator, FieldType } from "./index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Checks if a file or directory exists at the specified path.
|
|
5
|
+
*
|
|
6
|
+
* @param path - The path to the file or directory.
|
|
7
|
+
* @returns A Promise that resolves to true if the file/directory exists, false otherwise.
|
|
8
|
+
*/
|
|
3
9
|
export declare const isExists: (path: string) => Promise<boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* Encodes the input using 'secureString' and 'joinMultidimensionalArray' functions.
|
|
12
|
+
* If the input is an array, it is first secured and then joined into a string.
|
|
13
|
+
* If the input is a single value, it is directly secured.
|
|
14
|
+
*
|
|
15
|
+
* @param input - A value or array of values (string, number, boolean, null).
|
|
16
|
+
* @param secretKey - Optional secret key for encoding, can be a string or Buffer.
|
|
17
|
+
* @returns The secured and/or joined string.
|
|
18
|
+
*/
|
|
4
19
|
export declare const encode: (input: string | number | boolean | null | (string | number | boolean | null)[], secretKey?: string | Buffer) => string | number | boolean | null;
|
|
20
|
+
/**
|
|
21
|
+
* Decodes the input based on the specified field type(s) and an optional secret key.
|
|
22
|
+
* Handles different formats of input, including strings, numbers, and their array representations.
|
|
23
|
+
*
|
|
24
|
+
* @param input - The input to be decoded, can be a string, number, or null.
|
|
25
|
+
* @param fieldType - Optional type of the field to guide decoding (e.g., 'number', 'boolean').
|
|
26
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
27
|
+
* @param secretKey - Optional secret key for decoding, can be a string or Buffer.
|
|
28
|
+
* @returns Decoded value as a string, number, boolean, or array of these, or null if no fieldType or input is null/empty.
|
|
29
|
+
*/
|
|
5
30
|
export declare const decode: (input: string | null | number, fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[], secretKey?: string | Buffer) => string | number | boolean | null | (string | number | null | boolean)[];
|
|
31
|
+
/**
|
|
32
|
+
* Asynchronously reads and decodes data from a file at specified line numbers.
|
|
33
|
+
* Decodes each line based on specified field types and an optional secret key.
|
|
34
|
+
*
|
|
35
|
+
* @param filePath - Path of the file to be read.
|
|
36
|
+
* @param lineNumbers - Optional line number(s) to read from the file. If -1, reads the last line.
|
|
37
|
+
* @param fieldType - Optional type of the field to guide decoding (e.g., 'number', 'boolean').
|
|
38
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
39
|
+
* @param secretKey - Optional secret key for decoding, can be a string or Buffer.
|
|
40
|
+
* @returns Promise resolving to a tuple:
|
|
41
|
+
* 1. Record of line numbers and their decoded content or null if no lines are read.
|
|
42
|
+
* 2. Total count of lines processed.
|
|
43
|
+
*/
|
|
6
44
|
export declare const get: (filePath: string, lineNumbers?: number | number[], fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[], secretKey?: string | Buffer) => Promise<[
|
|
7
45
|
Record<number, string | number | boolean | null | (string | number | boolean | (string | number | boolean)[] | null)[]> | null,
|
|
8
46
|
number
|
|
9
47
|
]>;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Asynchronously replaces specific lines in a file based on the provided replacements map or string.
|
|
50
|
+
*
|
|
51
|
+
* @param filePath - Path of the file to modify.
|
|
52
|
+
* @param replacements - Map of line numbers to replacement values, or a single replacement value for all lines.
|
|
53
|
+
* Can be a string, number, boolean, null, array of these types, or a Record/Map of line numbers to these types.
|
|
54
|
+
* @returns Promise<string[]>
|
|
55
|
+
*
|
|
56
|
+
* Note: If the file doesn't exist and replacements is an object, it creates a new file with the specified replacements.
|
|
57
|
+
*/
|
|
58
|
+
export declare const replace: (filePath: string, replacements: string | number | boolean | null | (string | number | boolean | null)[] | Record<number, string | boolean | number | null | (string | boolean | number | null)[]>) => Promise<string[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Asynchronously appends data to a file.
|
|
61
|
+
*
|
|
62
|
+
* @param filePath - Path of the file to append to.
|
|
63
|
+
* @param data - Data to append. Can be a string, number, or an array of strings/numbers.
|
|
64
|
+
* @returns Promise<string[]>. Modifies the file by appending data.
|
|
65
|
+
*
|
|
66
|
+
*/
|
|
67
|
+
export declare const append: (filePath: string, data: string | number | (string | number)[]) => Promise<string[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Asynchronously removes specified lines from a file.
|
|
70
|
+
*
|
|
71
|
+
* @param filePath - Path of the file from which lines are to be removed.
|
|
72
|
+
* @param linesToDelete - A single line number or an array of line numbers to be deleted.
|
|
73
|
+
* @returns Promise<string[]>. Modifies the file by removing specified lines.
|
|
74
|
+
*
|
|
75
|
+
* Note: Creates a temporary file during the process and replaces the original file with it after removing lines.
|
|
76
|
+
*/
|
|
77
|
+
export declare const remove: (filePath: string, linesToDelete: number | number[]) => Promise<string[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Asynchronously counts the number of lines in a file.
|
|
80
|
+
*
|
|
81
|
+
* @param filePath - Path of the file to count lines in.
|
|
82
|
+
* @returns Promise<number>. The number of lines in the file.
|
|
83
|
+
*
|
|
84
|
+
* Note: Reads through the file line by line to count the total number of lines.
|
|
85
|
+
*/
|
|
13
86
|
export declare const count: (filePath: string) => Promise<number>;
|
|
87
|
+
/**
|
|
88
|
+
* Asynchronously searches a file for lines matching specified criteria, using comparison and logical operators.
|
|
89
|
+
*
|
|
90
|
+
* @param filePath - Path of the file to search.
|
|
91
|
+
* @param operator - Comparison operator(s) for evaluation (e.g., '=', '!=', '>', '<').
|
|
92
|
+
* @param comparedAtValue - Value(s) to compare each line against.
|
|
93
|
+
* @param logicalOperator - Optional logical operator ('and' or 'or') for combining multiple comparisons.
|
|
94
|
+
* @param fieldType - Optional type of the field to guide comparison.
|
|
95
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
96
|
+
* @param limit - Optional limit on the number of results to return.
|
|
97
|
+
* @param offset - Optional offset to start returning results from.
|
|
98
|
+
* @param readWholeFile - Flag to indicate whether to continue reading the file after reaching the limit.
|
|
99
|
+
* @param secretKey - Optional secret key for decoding, can be a string or Buffer.
|
|
100
|
+
* @returns Promise resolving to a tuple:
|
|
101
|
+
* 1. Record of line numbers and their content that match the criteria or null if none.
|
|
102
|
+
* 2. The count of found items or processed items based on the 'readWholeFile' flag.
|
|
103
|
+
*
|
|
104
|
+
* Note: Decodes each line for comparison and can handle complex queries with multiple conditions.
|
|
105
|
+
*/
|
|
14
106
|
export declare const search: (filePath: string, operator: ComparisonOperator | ComparisonOperator[], comparedAtValue: string | number | boolean | null | (string | number | boolean | null)[], logicalOperator?: "and" | "or", fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[], limit?: number, offset?: number, readWholeFile?: boolean, secretKey?: string | Buffer) => Promise<[
|
|
15
107
|
Record<number, string | number | boolean | (string | number | boolean | null)[] | null> | null,
|
|
16
108
|
number
|
|
17
109
|
]>;
|
|
110
|
+
/**
|
|
111
|
+
* Asynchronously calculates the sum of numerical values from specified lines in a file.
|
|
112
|
+
*
|
|
113
|
+
* @param filePath - Path of the file to read.
|
|
114
|
+
* @param lineNumbers - Optional specific line number(s) to include in the sum. If not provided, sums all lines.
|
|
115
|
+
* @returns Promise<number>. The sum of numerical values from the specified lines.
|
|
116
|
+
*
|
|
117
|
+
* Note: Decodes each line as a number using the 'decode' function. Non-numeric lines contribute 0 to the sum.
|
|
118
|
+
*/
|
|
18
119
|
export declare const sum: (filePath: string, lineNumbers?: number | number[]) => Promise<number>;
|
|
120
|
+
/**
|
|
121
|
+
* Asynchronously finds the maximum numerical value from specified lines in a file.
|
|
122
|
+
*
|
|
123
|
+
* @param filePath - Path of the file to read.
|
|
124
|
+
* @param lineNumbers - Optional specific line number(s) to consider for finding the maximum value. If not provided, considers all lines.
|
|
125
|
+
* @returns Promise<number>. The maximum numerical value found in the specified lines.
|
|
126
|
+
*
|
|
127
|
+
* Note: Decodes each line as a number using the 'decode' function. Considers only numerical values for determining the maximum.
|
|
128
|
+
*/
|
|
19
129
|
export declare const max: (filePath: string, lineNumbers?: number | number[]) => Promise<number>;
|
|
130
|
+
/**
|
|
131
|
+
* Asynchronously finds the minimum numerical value from specified lines in a file.
|
|
132
|
+
*
|
|
133
|
+
* @param filePath - Path of the file to read.
|
|
134
|
+
* @param lineNumbers - Optional specific line number(s) to consider for finding the minimum value. If not provided, considers all lines.
|
|
135
|
+
* @returns Promise<number>. The minimum numerical value found in the specified lines.
|
|
136
|
+
*
|
|
137
|
+
* Note: Decodes each line as a number using the 'decode' function. Considers only numerical values for determining the minimum.
|
|
138
|
+
*/
|
|
20
139
|
export declare const min: (filePath: string, lineNumbers?: number | number[]) => Promise<number>;
|
|
140
|
+
/**
|
|
141
|
+
* Asynchronously sorts the lines in a file in the specified direction.
|
|
142
|
+
*
|
|
143
|
+
* @param filePath - Path of the file to be sorted.
|
|
144
|
+
* @param sortDirection - Direction for sorting: 1 or 'asc' for ascending, -1 or 'desc' for descending.
|
|
145
|
+
* @param lineNumbers - Optional specific line numbers to sort. If not provided, sorts all lines.
|
|
146
|
+
* @param _lineNumbersPerChunk - Optional parameter for handling large files, specifying the number of lines per chunk.
|
|
147
|
+
* @returns Promise<void>. Modifies the file by sorting specified lines.
|
|
148
|
+
*
|
|
149
|
+
* Note: The sorting is applied either to the entire file or to the specified lines. Large files are handled in chunks.
|
|
150
|
+
*/
|
|
21
151
|
export declare const sort: (filePath: string, sortDirection: 1 | -1 | "asc" | "desc", lineNumbers?: number | number[], _lineNumbersPerChunk?: number) => Promise<void>;
|
|
22
152
|
export default class File {
|
|
23
153
|
static get: (filePath: string, lineNumbers?: number | number[] | undefined, fieldType?: FieldType | FieldType[] | undefined, fieldChildrenType?: FieldType | FieldType[] | undefined, secretKey?: string | Buffer | undefined) => Promise<[Record<number, string | number | boolean | (string | number | boolean | (string | number | boolean)[] | null)[] | null> | null, number]>;
|
|
24
|
-
static remove: (filePath: string, linesToDelete: number | number[]) => Promise<
|
|
154
|
+
static remove: (filePath: string, linesToDelete: number | number[]) => Promise<string[]>;
|
|
25
155
|
static search: (filePath: string, operator: ComparisonOperator | ComparisonOperator[], comparedAtValue: string | number | boolean | (string | number | boolean | null)[] | null, logicalOperator?: "and" | "or" | undefined, fieldType?: FieldType | FieldType[] | undefined, fieldChildrenType?: FieldType | FieldType[] | undefined, limit?: number | undefined, offset?: number | undefined, readWholeFile?: boolean | undefined, secretKey?: string | Buffer | undefined) => Promise<[Record<number, string | number | boolean | (string | number | boolean | null)[] | null> | null, number]>;
|
|
26
|
-
static replace: (filePath: string, replacements: string | number | boolean | (string | number | boolean | null)[] | Record<number, string | number | boolean | (string | number | boolean | null)[] | null> |
|
|
156
|
+
static replace: (filePath: string, replacements: string | number | boolean | (string | number | boolean | null)[] | Record<number, string | number | boolean | (string | number | boolean | null)[] | null> | null) => Promise<string[]>;
|
|
27
157
|
static count: (filePath: string) => Promise<number>;
|
|
28
158
|
static encode: (input: string | number | boolean | (string | number | boolean | null)[] | null, secretKey?: string | Buffer | undefined) => string | number | boolean | null;
|
|
29
159
|
static decode: (input: string | number | null, fieldType?: FieldType | FieldType[] | undefined, fieldChildrenType?: FieldType | FieldType[] | undefined, secretKey?: string | Buffer | undefined) => string | number | boolean | (string | number | boolean | null)[] | null;
|
|
@@ -31,5 +161,5 @@ export default class File {
|
|
|
31
161
|
static sum: (filePath: string, lineNumbers?: number | number[] | undefined) => Promise<number>;
|
|
32
162
|
static min: (filePath: string, lineNumbers?: number | number[] | undefined) => Promise<number>;
|
|
33
163
|
static max: (filePath: string, lineNumbers?: number | number[] | undefined) => Promise<number>;
|
|
34
|
-
static append: (filePath: string, data: string | number | (string | number)[]
|
|
164
|
+
static append: (filePath: string, data: string | number | (string | number)[]) => Promise<string[]>;
|
|
35
165
|
}
|
package/dist/file.js
CHANGED
|
@@ -1,16 +1,33 @@
|
|
|
1
|
-
import { open,
|
|
1
|
+
import { open, access, constants, writeFile, } from "node:fs/promises";
|
|
2
2
|
import { createInterface } from "node:readline";
|
|
3
|
+
import { Transform } from "node:stream";
|
|
4
|
+
import { pipeline } from "node:stream/promises";
|
|
3
5
|
import { detectFieldType, isArrayOfArrays, isNumber, isObject, } from "./utils.js";
|
|
4
6
|
import { encodeID, comparePassword } from "./utils.server.js";
|
|
7
|
+
/**
|
|
8
|
+
* Creates a readline interface for a given file handle.
|
|
9
|
+
*
|
|
10
|
+
* @param fileHandle - The file handle from which to create a read stream.
|
|
11
|
+
* @returns A readline.Interface instance configured with the provided file stream.
|
|
12
|
+
*/
|
|
5
13
|
const readLineInternface = (fileHandle) => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
const [major, minor, patch] = process.versions.node.split(".").map(Number);
|
|
15
|
+
return major > 18 || (major === 18 && minor >= 11)
|
|
16
|
+
? fileHandle.readLines()
|
|
17
|
+
: createInterface({
|
|
18
|
+
input: fileHandle.createReadStream(), // .pipe(createInflate())
|
|
19
|
+
crlfDelay: Infinity,
|
|
20
|
+
});
|
|
10
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Checks if a file or directory exists at the specified path.
|
|
24
|
+
*
|
|
25
|
+
* @param path - The path to the file or directory.
|
|
26
|
+
* @returns A Promise that resolves to true if the file/directory exists, false otherwise.
|
|
27
|
+
*/
|
|
11
28
|
export const isExists = async (path) => {
|
|
12
29
|
try {
|
|
13
|
-
await
|
|
30
|
+
await access(path, constants.R_OK | constants.W_OK);
|
|
14
31
|
return true;
|
|
15
32
|
}
|
|
16
33
|
catch {
|
|
@@ -18,6 +35,12 @@ export const isExists = async (path) => {
|
|
|
18
35
|
}
|
|
19
36
|
};
|
|
20
37
|
const delimiters = [",", "|", "&", "$", "#", "@", "^", ":", "!", ";"];
|
|
38
|
+
/**
|
|
39
|
+
* Secures input by encoding/escaping characters.
|
|
40
|
+
*
|
|
41
|
+
* @param input - String, number, boolean, or null.
|
|
42
|
+
* @returns Encoded string for true/false, special characters in strings, or original input.
|
|
43
|
+
*/
|
|
21
44
|
const secureString = (input) => {
|
|
22
45
|
if (["true", "false"].includes(String(input)))
|
|
23
46
|
return input ? 1 : 0;
|
|
@@ -39,7 +62,20 @@ const secureString = (input) => {
|
|
|
39
62
|
.replaceAll("\r", "\\r")
|
|
40
63
|
: input;
|
|
41
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Secures each element in an array or a single value using secureString.
|
|
67
|
+
*
|
|
68
|
+
* @param arr_str - An array or a single value of any type.
|
|
69
|
+
* @returns An array with each element secured, or a single secured value.
|
|
70
|
+
*/
|
|
42
71
|
const secureArray = (arr_str) => Array.isArray(arr_str) ? arr_str.map(secureArray) : secureString(arr_str);
|
|
72
|
+
/**
|
|
73
|
+
* Joins elements of a multidimensional array into a string.
|
|
74
|
+
*
|
|
75
|
+
* @param arr - A multidimensional array or a single level array.
|
|
76
|
+
* @param delimiter_index - Index for selecting delimiter, defaults to 0.
|
|
77
|
+
* @returns Joined string of array elements with appropriate delimiters.
|
|
78
|
+
*/
|
|
43
79
|
const joinMultidimensionalArray = (arr, delimiter_index = 0) => {
|
|
44
80
|
delimiter_index++;
|
|
45
81
|
if (isArrayOfArrays(arr))
|
|
@@ -47,11 +83,26 @@ const joinMultidimensionalArray = (arr, delimiter_index = 0) => {
|
|
|
47
83
|
delimiter_index--;
|
|
48
84
|
return arr.join(delimiters[delimiter_index]);
|
|
49
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* Encodes the input using 'secureString' and 'joinMultidimensionalArray' functions.
|
|
88
|
+
* If the input is an array, it is first secured and then joined into a string.
|
|
89
|
+
* If the input is a single value, it is directly secured.
|
|
90
|
+
*
|
|
91
|
+
* @param input - A value or array of values (string, number, boolean, null).
|
|
92
|
+
* @param secretKey - Optional secret key for encoding, can be a string or Buffer.
|
|
93
|
+
* @returns The secured and/or joined string.
|
|
94
|
+
*/
|
|
50
95
|
export const encode = (input, secretKey) => {
|
|
51
96
|
return Array.isArray(input)
|
|
52
97
|
? joinMultidimensionalArray(secureArray(input))
|
|
53
98
|
: secureString(input);
|
|
54
99
|
};
|
|
100
|
+
/**
|
|
101
|
+
* Reverses the encoding done by 'secureString'. Replaces encoded characters with their original symbols.
|
|
102
|
+
*
|
|
103
|
+
* @param input - Encoded string.
|
|
104
|
+
* @returns Decoded string or null if input is empty.
|
|
105
|
+
*/
|
|
55
106
|
const unSecureString = (input) => input
|
|
56
107
|
.replaceAll("<", "<")
|
|
57
108
|
.replaceAll(">", ">")
|
|
@@ -67,7 +118,20 @@ const unSecureString = (input) => input
|
|
|
67
118
|
.replaceAll("%3B", ";")
|
|
68
119
|
.replaceAll("\\n", "\n")
|
|
69
120
|
.replaceAll("\\r", "\r") || null;
|
|
121
|
+
/**
|
|
122
|
+
* Decodes each element in an array or a single value using unSecureString.
|
|
123
|
+
*
|
|
124
|
+
* @param arr_str - An array or a single value of any type.
|
|
125
|
+
* @returns An array with each element decoded, or a single decoded value.
|
|
126
|
+
*/
|
|
70
127
|
const unSecureArray = (arr_str) => Array.isArray(arr_str) ? arr_str.map(unSecureArray) : unSecureString(arr_str);
|
|
128
|
+
/**
|
|
129
|
+
* Reverses the process of 'joinMultidimensionalArray', splitting a string back into a multidimensional array.
|
|
130
|
+
* It identifies delimiters used in the joined string and applies them recursively to reconstruct the original array structure.
|
|
131
|
+
*
|
|
132
|
+
* @param joinedString - A string, array, or multidimensional array.
|
|
133
|
+
* @returns Original array structure before joining, or the input if no delimiters are found.
|
|
134
|
+
*/
|
|
71
135
|
const reverseJoinMultidimensionalArray = (joinedString) => {
|
|
72
136
|
const reverseJoinMultidimensionalArrayHelper = (arr, delimiter) => Array.isArray(arr)
|
|
73
137
|
? arr.map((ar) => reverseJoinMultidimensionalArrayHelper(ar, delimiter))
|
|
@@ -80,6 +144,16 @@ const reverseJoinMultidimensionalArray = (joinedString) => {
|
|
|
80
144
|
}
|
|
81
145
|
return joinedString;
|
|
82
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* Decodes a value based on specified field types and optional secret key.
|
|
149
|
+
* Handles different data types and structures, including nested arrays.
|
|
150
|
+
*
|
|
151
|
+
* @param value - The value to be decoded, can be string, number, or array.
|
|
152
|
+
* @param fieldType - Optional type of the field to guide decoding (e.g., 'number', 'boolean').
|
|
153
|
+
* @param fieldChildrenType - Optional type for children elements, used for arrays.
|
|
154
|
+
* @param secretKey - Optional secret key for decoding, can be string or Buffer.
|
|
155
|
+
* @returns Decoded value, transformed according to the specified field type(s).
|
|
156
|
+
*/
|
|
83
157
|
const decodeHelper = (value, fieldType, fieldChildrenType, secretKey) => {
|
|
84
158
|
if (Array.isArray(value) && fieldType !== "array")
|
|
85
159
|
return value.map((v) => decodeHelper(v, fieldType, fieldChildrenType, secretKey));
|
|
@@ -106,6 +180,16 @@ const decodeHelper = (value, fieldType, fieldChildrenType, secretKey) => {
|
|
|
106
180
|
return value;
|
|
107
181
|
}
|
|
108
182
|
};
|
|
183
|
+
/**
|
|
184
|
+
* Decodes the input based on the specified field type(s) and an optional secret key.
|
|
185
|
+
* Handles different formats of input, including strings, numbers, and their array representations.
|
|
186
|
+
*
|
|
187
|
+
* @param input - The input to be decoded, can be a string, number, or null.
|
|
188
|
+
* @param fieldType - Optional type of the field to guide decoding (e.g., 'number', 'boolean').
|
|
189
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
190
|
+
* @param secretKey - Optional secret key for decoding, can be a string or Buffer.
|
|
191
|
+
* @returns Decoded value as a string, number, boolean, or array of these, or null if no fieldType or input is null/empty.
|
|
192
|
+
*/
|
|
109
193
|
export const decode = (input, fieldType, fieldChildrenType, secretKey) => {
|
|
110
194
|
if (!fieldType)
|
|
111
195
|
return null;
|
|
@@ -119,6 +203,19 @@ export const decode = (input, fieldType, fieldChildrenType, secretKey) => {
|
|
|
119
203
|
: unSecureString(input)
|
|
120
204
|
: input, fieldType, fieldChildrenType, secretKey);
|
|
121
205
|
};
|
|
206
|
+
/**
|
|
207
|
+
* Asynchronously reads and decodes data from a file at specified line numbers.
|
|
208
|
+
* Decodes each line based on specified field types and an optional secret key.
|
|
209
|
+
*
|
|
210
|
+
* @param filePath - Path of the file to be read.
|
|
211
|
+
* @param lineNumbers - Optional line number(s) to read from the file. If -1, reads the last line.
|
|
212
|
+
* @param fieldType - Optional type of the field to guide decoding (e.g., 'number', 'boolean').
|
|
213
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
214
|
+
* @param secretKey - Optional secret key for decoding, can be a string or Buffer.
|
|
215
|
+
* @returns Promise resolving to a tuple:
|
|
216
|
+
* 1. Record of line numbers and their decoded content or null if no lines are read.
|
|
217
|
+
* 2. Total count of lines processed.
|
|
218
|
+
*/
|
|
122
219
|
export const get = async (filePath, lineNumbers, fieldType, fieldChildrenType, secretKey) => {
|
|
123
220
|
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
124
221
|
let lines = new Map(), lineCount = 0;
|
|
@@ -149,71 +246,122 @@ export const get = async (filePath, lineNumbers, fieldType, fieldChildrenType, s
|
|
|
149
246
|
await fileHandle.close();
|
|
150
247
|
return [lines.size ? Object.fromEntries(lines) : null, lineCount];
|
|
151
248
|
};
|
|
249
|
+
/**
|
|
250
|
+
* Asynchronously replaces specific lines in a file based on the provided replacements map or string.
|
|
251
|
+
*
|
|
252
|
+
* @param filePath - Path of the file to modify.
|
|
253
|
+
* @param replacements - Map of line numbers to replacement values, or a single replacement value for all lines.
|
|
254
|
+
* Can be a string, number, boolean, null, array of these types, or a Record/Map of line numbers to these types.
|
|
255
|
+
* @returns Promise<string[]>
|
|
256
|
+
*
|
|
257
|
+
* Note: If the file doesn't exist and replacements is an object, it creates a new file with the specified replacements.
|
|
258
|
+
*/
|
|
152
259
|
export const replace = async (filePath, replacements) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
replacements = new Map(Object.entries(replacements));
|
|
159
|
-
for await (const line of rl) {
|
|
260
|
+
let lineCount = 0;
|
|
261
|
+
const fileHandle = await open(filePath, "r"), fileTempPath = filePath.replace(/([^/]+)\/?$/, `.tmp/${Date.now()}-$1`), fileTempHandle = await open(fileTempPath, "w"), rl = readLineInternface(fileHandle);
|
|
262
|
+
if (isObject(replacements))
|
|
263
|
+
await pipeline(rl, new Transform({
|
|
264
|
+
transform(line, encoding, callback) {
|
|
160
265
|
lineCount++;
|
|
161
|
-
|
|
162
|
-
? replacements
|
|
266
|
+
callback(null, (replacements.hasOwnProperty(lineCount)
|
|
267
|
+
? replacements[lineCount]
|
|
163
268
|
: line) + "\n");
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
269
|
+
},
|
|
270
|
+
final(callback) {
|
|
271
|
+
const newLinesNumbers = Object.entries(replacements)
|
|
272
|
+
.map(([key, value]) => Number(key))
|
|
273
|
+
.filter((num) => num > lineCount);
|
|
274
|
+
if (newLinesNumbers.length) {
|
|
275
|
+
if (Math.min(...newLinesNumbers) - lineCount - 1 > 1)
|
|
276
|
+
this.push("\n".repeat(Math.min(...newLinesNumbers) - lineCount - 1));
|
|
277
|
+
this.push(newLinesNumbers
|
|
278
|
+
.map((newLineNumber) => replacements[newLineNumber])
|
|
279
|
+
.join("\n") + "\n");
|
|
280
|
+
}
|
|
281
|
+
callback();
|
|
282
|
+
},
|
|
283
|
+
}),
|
|
284
|
+
// createDeflate(),
|
|
285
|
+
fileTempHandle.createWriteStream());
|
|
286
|
+
else
|
|
287
|
+
await pipeline(rl, new Transform({
|
|
288
|
+
transform(line, encoding, callback) {
|
|
289
|
+
lineCount++;
|
|
290
|
+
callback(null, replacements + "\n");
|
|
291
|
+
},
|
|
292
|
+
}),
|
|
293
|
+
// createDeflate(),
|
|
294
|
+
fileTempHandle.createWriteStream());
|
|
295
|
+
await fileHandle.close();
|
|
296
|
+
await fileTempHandle.close();
|
|
297
|
+
return [fileTempPath, filePath];
|
|
298
|
+
};
|
|
299
|
+
/**
|
|
300
|
+
* Asynchronously appends data to a file.
|
|
301
|
+
*
|
|
302
|
+
* @param filePath - Path of the file to append to.
|
|
303
|
+
* @param data - Data to append. Can be a string, number, or an array of strings/numbers.
|
|
304
|
+
* @returns Promise<string[]>. Modifies the file by appending data.
|
|
305
|
+
*
|
|
306
|
+
*/
|
|
307
|
+
export const append = async (filePath, data) => {
|
|
308
|
+
const fileTempPath = filePath.replace(/([^/]+)\/?$/, `.tmp/${Date.now()}-$1`);
|
|
309
|
+
if (await isExists(filePath)) {
|
|
310
|
+
const fileHandle = await open(filePath, "r"), fileTempHandle = await open(fileTempPath, "w"), rl = readLineInternface(fileHandle);
|
|
311
|
+
await pipeline(rl, new Transform({
|
|
312
|
+
transform(line, encoding, callback) {
|
|
313
|
+
callback(null, `${line}\n`);
|
|
314
|
+
},
|
|
315
|
+
final(callback) {
|
|
316
|
+
this.push((Array.isArray(data) ? data.join("\n") : data) + "\n");
|
|
317
|
+
callback();
|
|
318
|
+
},
|
|
319
|
+
}),
|
|
320
|
+
// createDeflate(),
|
|
321
|
+
fileTempHandle.createWriteStream());
|
|
176
322
|
await fileHandle.close();
|
|
177
323
|
await fileTempHandle.close();
|
|
178
|
-
await rename(fileTempPath, filePath);
|
|
179
|
-
}
|
|
180
|
-
else if (isObject(replacements)) {
|
|
181
|
-
if (!(replacements instanceof Map))
|
|
182
|
-
replacements = new Map(Object.entries(replacements).map(([key, value]) => [Number(key), value]));
|
|
183
|
-
await writeFile(filePath, (Math.min(...replacements.keys()) - 1 > 1
|
|
184
|
-
? "\n".repeat(Math.min(...replacements.keys()) - 1)
|
|
185
|
-
: "") +
|
|
186
|
-
Array.from(new Map([...replacements.entries()].sort(([keyA], [keyB]) => keyA - keyB)).values()).join("\n") +
|
|
187
|
-
"\n");
|
|
188
324
|
}
|
|
325
|
+
else
|
|
326
|
+
await writeFile(fileTempPath, `${Array.isArray(data) ? data.join("\n") : data}\n`);
|
|
327
|
+
return [fileTempPath, filePath];
|
|
189
328
|
};
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
: "") +
|
|
200
|
-
(Array.isArray(data) ? data.join("\n") : data) +
|
|
201
|
-
"\n");
|
|
202
|
-
};
|
|
329
|
+
/**
|
|
330
|
+
* Asynchronously removes specified lines from a file.
|
|
331
|
+
*
|
|
332
|
+
* @param filePath - Path of the file from which lines are to be removed.
|
|
333
|
+
* @param linesToDelete - A single line number or an array of line numbers to be deleted.
|
|
334
|
+
* @returns Promise<string[]>. Modifies the file by removing specified lines.
|
|
335
|
+
*
|
|
336
|
+
* Note: Creates a temporary file during the process and replaces the original file with it after removing lines.
|
|
337
|
+
*/
|
|
203
338
|
export const remove = async (filePath, linesToDelete) => {
|
|
204
339
|
let lineCount = 0;
|
|
205
|
-
const fileHandle = await open(filePath, "r"), fileTempPath =
|
|
340
|
+
const fileHandle = await open(filePath, "r"), fileTempPath = filePath.replace(/([^/]+)\/?$/, `.tmp/${Date.now()}-$1`), fileTempHandle = await open(fileTempPath, "w"), linesToDeleteArray = new Set(Array.isArray(linesToDelete)
|
|
206
341
|
? linesToDelete.map(Number)
|
|
207
|
-
: [Number(linesToDelete)]), rl = readLineInternface(fileHandle)
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
342
|
+
: [Number(linesToDelete)]), rl = readLineInternface(fileHandle);
|
|
343
|
+
await pipeline(rl, new Transform({
|
|
344
|
+
transform(line, encoding, callback) {
|
|
345
|
+
lineCount++;
|
|
346
|
+
if (!linesToDeleteArray.has(lineCount))
|
|
347
|
+
callback(null, `${line}\n`);
|
|
348
|
+
callback();
|
|
349
|
+
},
|
|
350
|
+
}),
|
|
351
|
+
// createDeflate(),
|
|
352
|
+
fileTempHandle.createWriteStream());
|
|
214
353
|
await fileTempHandle.close();
|
|
215
354
|
await fileHandle.close();
|
|
355
|
+
return [fileTempPath, filePath];
|
|
216
356
|
};
|
|
357
|
+
/**
|
|
358
|
+
* Asynchronously counts the number of lines in a file.
|
|
359
|
+
*
|
|
360
|
+
* @param filePath - Path of the file to count lines in.
|
|
361
|
+
* @returns Promise<number>. The number of lines in the file.
|
|
362
|
+
*
|
|
363
|
+
* Note: Reads through the file line by line to count the total number of lines.
|
|
364
|
+
*/
|
|
217
365
|
export const count = async (filePath) => {
|
|
218
366
|
// return Number((await exec(`wc -l < ${filePath}`)).stdout.trim());
|
|
219
367
|
let lineCount = 0;
|
|
@@ -223,6 +371,18 @@ export const count = async (filePath) => {
|
|
|
223
371
|
await fileHandle.close();
|
|
224
372
|
return lineCount;
|
|
225
373
|
};
|
|
374
|
+
/**
|
|
375
|
+
* Evaluates a comparison between two values based on a specified operator and field types.
|
|
376
|
+
*
|
|
377
|
+
* @param operator - The comparison operator (e.g., '=', '!=', '>', '<', '>=', '<=', '[]', '![]', '*', '!*').
|
|
378
|
+
* @param originalValue - The value to compare, can be a single value or an array of values.
|
|
379
|
+
* @param comparedAtValue - The value or values to compare against.
|
|
380
|
+
* @param fieldType - Optional type of the field to guide comparison (e.g., 'password', 'boolean').
|
|
381
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
382
|
+
* @returns boolean - Result of the comparison operation.
|
|
383
|
+
*
|
|
384
|
+
* Note: Handles various data types and comparison logic, including special handling for passwords and regex patterns.
|
|
385
|
+
*/
|
|
226
386
|
const handleComparisonOperator = (operator, originalValue, comparedAtValue, fieldType, fieldChildrenType) => {
|
|
227
387
|
if (Array.isArray(fieldType))
|
|
228
388
|
fieldType = detectFieldType(String(originalValue), fieldType);
|
|
@@ -282,6 +442,25 @@ const handleComparisonOperator = (operator, originalValue, comparedAtValue, fiel
|
|
|
282
442
|
throw new Error(operator);
|
|
283
443
|
}
|
|
284
444
|
};
|
|
445
|
+
/**
|
|
446
|
+
* Asynchronously searches a file for lines matching specified criteria, using comparison and logical operators.
|
|
447
|
+
*
|
|
448
|
+
* @param filePath - Path of the file to search.
|
|
449
|
+
* @param operator - Comparison operator(s) for evaluation (e.g., '=', '!=', '>', '<').
|
|
450
|
+
* @param comparedAtValue - Value(s) to compare each line against.
|
|
451
|
+
* @param logicalOperator - Optional logical operator ('and' or 'or') for combining multiple comparisons.
|
|
452
|
+
* @param fieldType - Optional type of the field to guide comparison.
|
|
453
|
+
* @param fieldChildrenType - Optional type for child elements in array inputs.
|
|
454
|
+
* @param limit - Optional limit on the number of results to return.
|
|
455
|
+
* @param offset - Optional offset to start returning results from.
|
|
456
|
+
* @param readWholeFile - Flag to indicate whether to continue reading the file after reaching the limit.
|
|
457
|
+
* @param secretKey - Optional secret key for decoding, can be a string or Buffer.
|
|
458
|
+
* @returns Promise resolving to a tuple:
|
|
459
|
+
* 1. Record of line numbers and their content that match the criteria or null if none.
|
|
460
|
+
* 2. The count of found items or processed items based on the 'readWholeFile' flag.
|
|
461
|
+
*
|
|
462
|
+
* Note: Decodes each line for comparison and can handle complex queries with multiple conditions.
|
|
463
|
+
*/
|
|
285
464
|
export const search = async (filePath, operator, comparedAtValue, logicalOperator, fieldType, fieldChildrenType, limit, offset, readWholeFile, secretKey) => {
|
|
286
465
|
let RETURN = new Map(), lineCount = 0, foundItems = 0;
|
|
287
466
|
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
@@ -312,6 +491,15 @@ export const search = async (filePath, operator, comparedAtValue, logicalOperato
|
|
|
312
491
|
? [Object.fromEntries(RETURN), readWholeFile ? foundItems : foundItems - 1]
|
|
313
492
|
: [null, 0];
|
|
314
493
|
};
|
|
494
|
+
/**
|
|
495
|
+
* Asynchronously calculates the sum of numerical values from specified lines in a file.
|
|
496
|
+
*
|
|
497
|
+
* @param filePath - Path of the file to read.
|
|
498
|
+
* @param lineNumbers - Optional specific line number(s) to include in the sum. If not provided, sums all lines.
|
|
499
|
+
* @returns Promise<number>. The sum of numerical values from the specified lines.
|
|
500
|
+
*
|
|
501
|
+
* Note: Decodes each line as a number using the 'decode' function. Non-numeric lines contribute 0 to the sum.
|
|
502
|
+
*/
|
|
315
503
|
export const sum = async (filePath, lineNumbers) => {
|
|
316
504
|
let sum = 0;
|
|
317
505
|
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
@@ -334,6 +522,15 @@ export const sum = async (filePath, lineNumbers) => {
|
|
|
334
522
|
await fileHandle.close();
|
|
335
523
|
return sum;
|
|
336
524
|
};
|
|
525
|
+
/**
|
|
526
|
+
* Asynchronously finds the maximum numerical value from specified lines in a file.
|
|
527
|
+
*
|
|
528
|
+
* @param filePath - Path of the file to read.
|
|
529
|
+
* @param lineNumbers - Optional specific line number(s) to consider for finding the maximum value. If not provided, considers all lines.
|
|
530
|
+
* @returns Promise<number>. The maximum numerical value found in the specified lines.
|
|
531
|
+
*
|
|
532
|
+
* Note: Decodes each line as a number using the 'decode' function. Considers only numerical values for determining the maximum.
|
|
533
|
+
*/
|
|
337
534
|
export const max = async (filePath, lineNumbers) => {
|
|
338
535
|
let max = 0;
|
|
339
536
|
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
@@ -361,6 +558,15 @@ export const max = async (filePath, lineNumbers) => {
|
|
|
361
558
|
await fileHandle.close();
|
|
362
559
|
return max;
|
|
363
560
|
};
|
|
561
|
+
/**
|
|
562
|
+
* Asynchronously finds the minimum numerical value from specified lines in a file.
|
|
563
|
+
*
|
|
564
|
+
* @param filePath - Path of the file to read.
|
|
565
|
+
* @param lineNumbers - Optional specific line number(s) to consider for finding the minimum value. If not provided, considers all lines.
|
|
566
|
+
* @returns Promise<number>. The minimum numerical value found in the specified lines.
|
|
567
|
+
*
|
|
568
|
+
* Note: Decodes each line as a number using the 'decode' function. Considers only numerical values for determining the minimum.
|
|
569
|
+
*/
|
|
364
570
|
export const min = async (filePath, lineNumbers) => {
|
|
365
571
|
let min = 0;
|
|
366
572
|
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
@@ -388,6 +594,17 @@ export const min = async (filePath, lineNumbers) => {
|
|
|
388
594
|
await fileHandle.close();
|
|
389
595
|
return min;
|
|
390
596
|
};
|
|
597
|
+
/**
|
|
598
|
+
* Asynchronously sorts the lines in a file in the specified direction.
|
|
599
|
+
*
|
|
600
|
+
* @param filePath - Path of the file to be sorted.
|
|
601
|
+
* @param sortDirection - Direction for sorting: 1 or 'asc' for ascending, -1 or 'desc' for descending.
|
|
602
|
+
* @param lineNumbers - Optional specific line numbers to sort. If not provided, sorts all lines.
|
|
603
|
+
* @param _lineNumbersPerChunk - Optional parameter for handling large files, specifying the number of lines per chunk.
|
|
604
|
+
* @returns Promise<void>. Modifies the file by sorting specified lines.
|
|
605
|
+
*
|
|
606
|
+
* Note: The sorting is applied either to the entire file or to the specified lines. Large files are handled in chunks.
|
|
607
|
+
*/
|
|
391
608
|
export const sort = async (filePath, sortDirection, lineNumbers, _lineNumbersPerChunk = 100000) => { };
|
|
392
609
|
export default class File {
|
|
393
610
|
static get = get;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { unlink, rename, readFile, writeFile, mkdir, readdir, } from "node:fs/promises";
|
|
2
2
|
import { existsSync, appendFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
// import { cpus } from "node:os";
|
|
4
5
|
import { scryptSync, randomBytes } from "node:crypto";
|
|
5
6
|
import File from "./file.js";
|
|
6
7
|
import Utils from "./utils.js";
|
|
@@ -67,6 +68,8 @@ export default class Inibase {
|
|
|
67
68
|
const TablePath = join(this.folder, this.database, tableName), TableSchemaPath = join(TablePath, "schema.json");
|
|
68
69
|
if (!(await File.isExists(TablePath)))
|
|
69
70
|
await mkdir(TablePath, { recursive: true });
|
|
71
|
+
if (!(await File.isExists(join(TablePath, ".tmp"))))
|
|
72
|
+
await mkdir(join(TablePath, ".tmp"));
|
|
70
73
|
if (await File.isExists(TableSchemaPath)) {
|
|
71
74
|
// update columns files names based on field id
|
|
72
75
|
const schemaToIdsPath = (schema, prefix = "") => {
|
|
@@ -721,20 +724,21 @@ export default class Inibase {
|
|
|
721
724
|
let RETURN;
|
|
722
725
|
if (!schema)
|
|
723
726
|
throw this.throwError("NO_SCHEMA", tableName);
|
|
724
|
-
const idFilePath = join(this.folder, this.database, tableName, "id.inib");
|
|
725
|
-
let
|
|
726
|
-
?
|
|
727
|
-
|
|
728
|
-
|
|
727
|
+
const idFilePath = join(this.folder, this.database, tableName, "id.inib"), idCacheFilePath = join(this.folder, this.database, tableName, ".tmp", "lastId.inib");
|
|
728
|
+
let lastId = (await File.isExists(idFilePath))
|
|
729
|
+
? Number((await File.isExists(idCacheFilePath))
|
|
730
|
+
? (await readFile(idCacheFilePath)).toString()
|
|
731
|
+
: Object.entries((await File.get(idFilePath, -1, "number", undefined, this.salt))[0] ?? {})[0][1] ?? 0)
|
|
732
|
+
: 0;
|
|
729
733
|
if (Utils.isArrayOfObjects(data))
|
|
730
734
|
RETURN = data.map(({ id, updatedAt, createdAt, ...rest }) => ({
|
|
731
|
-
id: ++
|
|
735
|
+
id: ++lastId,
|
|
732
736
|
...rest,
|
|
733
737
|
createdAt: Date.now(),
|
|
734
738
|
}));
|
|
735
739
|
else
|
|
736
740
|
RETURN = (({ id, updatedAt, createdAt, ...rest }) => ({
|
|
737
|
-
id: ++
|
|
741
|
+
id: ++lastId,
|
|
738
742
|
...rest,
|
|
739
743
|
createdAt: Date.now(),
|
|
740
744
|
}))(data);
|
|
@@ -742,16 +746,11 @@ export default class Inibase {
|
|
|
742
746
|
throw this.throwError("NO_DATA");
|
|
743
747
|
RETURN = this.formatData(RETURN, schema);
|
|
744
748
|
const pathesContents = this.joinPathesContents(join(this.folder, this.database, tableName), RETURN);
|
|
745
|
-
|
|
749
|
+
const renameList = [];
|
|
746
750
|
for await (const [path, content] of Object.entries(pathesContents))
|
|
747
|
-
await File.append(path,
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
// obj[last_line_number + index] = value;
|
|
751
|
-
// return obj;
|
|
752
|
-
// }, {})
|
|
753
|
-
// : { [last_line_number]: content }
|
|
754
|
-
content, last_line_number);
|
|
751
|
+
renameList.push(await File.append(path, content));
|
|
752
|
+
await Promise.all(renameList.map(([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
753
|
+
await writeFile(idCacheFilePath, lastId.toString());
|
|
755
754
|
if (returnPostedData)
|
|
756
755
|
return this.get(tableName, Utils.isArrayOfObjects(RETURN)
|
|
757
756
|
? RETURN.map((data) => Number(data.id))
|
|
@@ -822,8 +821,10 @@ export default class Inibase {
|
|
|
822
821
|
[lineNum]: Array.isArray(content) ? content[index] : content,
|
|
823
822
|
}), {}),
|
|
824
823
|
]));
|
|
824
|
+
const renameList = [];
|
|
825
825
|
for await (const [path, content] of Object.entries(pathesContents))
|
|
826
|
-
await File.replace(path, content);
|
|
826
|
+
renameList.push(await File.replace(path, content));
|
|
827
|
+
await Promise.all(renameList.map(([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
827
828
|
if (returnPostedData)
|
|
828
829
|
return this.get(tableName, where, options, !Array.isArray(where));
|
|
829
830
|
}
|
|
@@ -847,8 +848,7 @@ export default class Inibase {
|
|
|
847
848
|
if (!where) {
|
|
848
849
|
const files = (await readdir(join(this.folder, this.database, tableName)))?.filter((fileName) => fileName.endsWith(".inib"));
|
|
849
850
|
if (files.length)
|
|
850
|
-
|
|
851
|
-
await unlink(join(this.folder, this.database, tableName, file));
|
|
851
|
+
await Promise.all(files.map((file) => unlink(join(this.folder, this.database, tableName, file))));
|
|
852
852
|
return "*";
|
|
853
853
|
}
|
|
854
854
|
else if ((Array.isArray(where) &&
|
|
@@ -871,8 +871,10 @@ export default class Inibase {
|
|
|
871
871
|
_id = Object.entries((await File.get(join(this.folder, this.database, tableName, "id.inib"), where, "number", undefined, this.salt))[0] ?? {}).map(([_key, id]) => UtilsServer.encodeID(Number(id), this.salt));
|
|
872
872
|
if (!_id.length)
|
|
873
873
|
throw this.throwError("NO_ITEMS", tableName);
|
|
874
|
+
const renameList = [];
|
|
874
875
|
for await (const file of files)
|
|
875
|
-
await File.remove(join(this.folder, this.database, tableName, file), where);
|
|
876
|
+
renameList.push(await File.remove(join(this.folder, this.database, tableName, file), where));
|
|
877
|
+
await Promise.all(renameList.map(([tempPath, filePath]) => rename(tempPath, filePath)));
|
|
876
878
|
return Array.isArray(_id) && _id.length === 1 ? _id[0] : _id;
|
|
877
879
|
}
|
|
878
880
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,23 +1,178 @@
|
|
|
1
1
|
import { type FieldType } from "./index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Type guard function to check if the input is an array of objects.
|
|
4
|
+
*
|
|
5
|
+
* @param input - The value to be checked.
|
|
6
|
+
* @returns boolean - True if the input is an array of objects, false otherwise.
|
|
7
|
+
*
|
|
8
|
+
* Note: Considers empty arrays and arrays where every element is an object.
|
|
9
|
+
*/
|
|
2
10
|
export declare const isArrayOfObjects: (input: any) => input is Record<any, any>[];
|
|
11
|
+
/**
|
|
12
|
+
* Type guard function to check if the input is an array of arrays.
|
|
13
|
+
*
|
|
14
|
+
* @param input - The value to be checked.
|
|
15
|
+
* @returns boolean - True if the input is an array of arrays, false otherwise.
|
|
16
|
+
*
|
|
17
|
+
* Note: Considers empty arrays and arrays where every element is also an array.
|
|
18
|
+
*/
|
|
3
19
|
export declare const isArrayOfArrays: (input: any) => input is any[][];
|
|
20
|
+
/**
|
|
21
|
+
* Type guard function to check if the input is an array of nulls or an array of arrays of nulls.
|
|
22
|
+
*
|
|
23
|
+
* @param input - The value to be checked.
|
|
24
|
+
* @returns boolean - True if the input is an array consisting entirely of nulls or arrays of nulls, false otherwise.
|
|
25
|
+
*
|
|
26
|
+
* Note: Recursively checks each element, allowing for nested arrays of nulls.
|
|
27
|
+
*/
|
|
4
28
|
export declare const isArrayOfNulls: (input: any) => input is null[] | null[][];
|
|
29
|
+
/**
|
|
30
|
+
* Type guard function to check if the input is an object.
|
|
31
|
+
*
|
|
32
|
+
* @param obj - The value to be checked.
|
|
33
|
+
* @returns boolean - True if the input is an object (excluding arrays), false otherwise.
|
|
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.
|
|
36
|
+
*/
|
|
5
37
|
export declare const isObject: (obj: any) => obj is Record<any, any>;
|
|
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
|
+
*/
|
|
6
47
|
export declare const deepMerge: (target: any, source: any) => any;
|
|
48
|
+
/**
|
|
49
|
+
* Combines an array of objects into a single object. If the same key exists in multiple objects, the values are merged.
|
|
50
|
+
*
|
|
51
|
+
* @param arr - Array of objects to be combined.
|
|
52
|
+
* @returns Record<string, any> - A single object with combined keys and values.
|
|
53
|
+
*
|
|
54
|
+
* Note: Handles nested objects by recursively combining them. Non-object values with the same key are merged into arrays.
|
|
55
|
+
*/
|
|
7
56
|
export declare const combineObjects: (arr: Record<string, any>[]) => Record<string, any>;
|
|
57
|
+
/**
|
|
58
|
+
* Type guard function to check if the input is a number.
|
|
59
|
+
*
|
|
60
|
+
* @param input - The value to be checked.
|
|
61
|
+
* @returns boolean - True if the input is a number, false otherwise.
|
|
62
|
+
*
|
|
63
|
+
* 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.
|
|
64
|
+
*/
|
|
8
65
|
export declare const isNumber: (input: any) => input is number;
|
|
66
|
+
/**
|
|
67
|
+
* Checks if the input is a valid email format.
|
|
68
|
+
*
|
|
69
|
+
* @param input - The value to be checked.
|
|
70
|
+
* @returns boolean - True if the input matches the email format, false otherwise.
|
|
71
|
+
*
|
|
72
|
+
* Note: Uses a regular expression to validate the email format, ensuring it has parts separated by '@' and contains a domain with a period.
|
|
73
|
+
*/
|
|
9
74
|
export declare const isEmail: (input: any) => boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Checks if the input is a valid URL format.
|
|
77
|
+
*
|
|
78
|
+
* @param input - The value to be checked.
|
|
79
|
+
* @returns boolean - True if the input matches the URL format, false otherwise.
|
|
80
|
+
*
|
|
81
|
+
* Note: Validates URLs including protocols (http/https), domain names, IP addresses, ports, paths, query strings, and fragments.
|
|
82
|
+
* Also recognizes 'tel:' and 'mailto:' as valid URL formats, as well as strings starting with '#' without spaces.
|
|
83
|
+
*/
|
|
10
84
|
export declare const isURL: (input: any) => boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Checks if the input contains HTML tags or entities.
|
|
87
|
+
*
|
|
88
|
+
* @param input - The value to be checked.
|
|
89
|
+
* @returns boolean - True if the input contains HTML tags or entities, false otherwise.
|
|
90
|
+
*
|
|
91
|
+
* Note: Uses a regular expression to detect HTML tags (like <tag>) and entities (like &entity;).
|
|
92
|
+
* Recognizes both opening and closing tags, as well as self-closing tags.
|
|
93
|
+
*/
|
|
11
94
|
export declare const isHTML: (input: any) => boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Type guard function to check if the input is a string, excluding strings that match specific formats (number, boolean, email, URL, IP).
|
|
97
|
+
*
|
|
98
|
+
* @param input - The value to be checked.
|
|
99
|
+
* @returns boolean - True if the input is a string that doesn't match the specific formats, false otherwise.
|
|
100
|
+
*
|
|
101
|
+
* Note: Validates the input against being a number, boolean, email, URL, or IP address to ensure it's a general string.
|
|
102
|
+
*/
|
|
12
103
|
export declare const isString: (input: any) => input is string;
|
|
104
|
+
/**
|
|
105
|
+
* Checks if the input is a valid IP address format.
|
|
106
|
+
*
|
|
107
|
+
* @param input - The value to be checked.
|
|
108
|
+
* @returns boolean - True if the input matches the IP address format, false otherwise.
|
|
109
|
+
*
|
|
110
|
+
* Note: Uses a regular expression to validate IP addresses, ensuring they consist of four octets, each ranging from 0 to 255.
|
|
111
|
+
*/
|
|
13
112
|
export declare const isIP: (input: any) => boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Type guard function to check if the input is a boolean or a string representation of a boolean.
|
|
115
|
+
*
|
|
116
|
+
* @param input - The value to be checked.
|
|
117
|
+
* @returns boolean - True if the input is a boolean value or 'true'/'false' strings, false otherwise.
|
|
118
|
+
*
|
|
119
|
+
* Note: Recognizes both boolean literals (true, false) and their string representations ("true", "false").
|
|
120
|
+
*/
|
|
14
121
|
export declare const isBoolean: (input: any) => input is boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Type guard function to check if the input is a password based on a specific length criterion.
|
|
124
|
+
*
|
|
125
|
+
* @param input - The value to be checked.
|
|
126
|
+
* @returns boolean - True if the input is a string with a length of 161 characters, false otherwise.
|
|
127
|
+
*
|
|
128
|
+
* Note: Specifically checks for string length to determine if it matches the defined password length criterion.
|
|
129
|
+
*/
|
|
15
130
|
export declare const isPassword: (input: any) => input is string;
|
|
131
|
+
/**
|
|
132
|
+
* Checks if the input can be converted to a valid date.
|
|
133
|
+
*
|
|
134
|
+
* @param input - The input to be checked, can be of any type.
|
|
135
|
+
* @returns A boolean indicating whether the input is a valid date.
|
|
136
|
+
*/
|
|
16
137
|
export declare const isDate: (input: any) => boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Checks if the input is a valid ID.
|
|
140
|
+
*
|
|
141
|
+
* @param input - The input to be checked, can be of any type.
|
|
142
|
+
* @returns A boolean indicating whether the input is a string representing a valid ID of length 32.
|
|
143
|
+
*/
|
|
17
144
|
export declare const isValidID: (input: any) => input is string;
|
|
145
|
+
/**
|
|
146
|
+
* Identifies and returns properties that have changed between two objects.
|
|
147
|
+
*
|
|
148
|
+
* @param obj1 - The first object for comparison, with string keys and values.
|
|
149
|
+
* @param obj2 - The second object for comparison, with string keys and values.
|
|
150
|
+
* @returns A record of changed properties with original values from obj1 and new values from obj2, or null if no changes are found.
|
|
151
|
+
*/
|
|
18
152
|
export declare const findChangedProperties: (obj1: Record<string, string>, obj2: Record<string, string>) => Record<string, string> | null;
|
|
153
|
+
/**
|
|
154
|
+
* Detects the field type of an input based on available types.
|
|
155
|
+
*
|
|
156
|
+
* @param input - The input whose field type is to be detected.
|
|
157
|
+
* @param availableTypes - An array of potential field types to consider.
|
|
158
|
+
* @returns The detected field type as a string, or undefined if no matching type is found.
|
|
159
|
+
*/
|
|
19
160
|
export declare const detectFieldType: (input: any, availableTypes: FieldType[]) => FieldType | undefined;
|
|
161
|
+
/**
|
|
162
|
+
* Validates if the given value matches the specified field type(s).
|
|
163
|
+
*
|
|
164
|
+
* @param value - The value to be validated.
|
|
165
|
+
* @param fieldType - The expected field type or an array of possible field types.
|
|
166
|
+
* @param fieldChildrenType - Optional; the expected type(s) of children elements, used if the field type is an array.
|
|
167
|
+
* @returns A boolean indicating whether the value matches the specified field type(s).
|
|
168
|
+
*/
|
|
20
169
|
export declare const validateFieldType: (value: any, fieldType: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[]) => boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Converts a nested object to dot notation, flattening the object's structure.
|
|
172
|
+
*
|
|
173
|
+
* @param input - The input object to be converted.
|
|
174
|
+
* @returns A flattened object using dot notation for keys.
|
|
175
|
+
*/
|
|
21
176
|
export declare const objectToDotNotation: (input: Record<string, any>) => Record<string, string | number | (string | number)[]>;
|
|
22
177
|
export default class Utils {
|
|
23
178
|
static isNumber: (input: any) => input is number;
|
package/dist/utils.js
CHANGED
|
@@ -1,9 +1,50 @@
|
|
|
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
|
+
*/
|
|
1
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
|
+
*/
|
|
2
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
|
+
*/
|
|
3
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
|
+
*/
|
|
4
36
|
export const isObject = (obj) => obj != null &&
|
|
5
37
|
(obj.constructor.name === "Object" ||
|
|
6
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
|
+
*/
|
|
7
48
|
export const deepMerge = (target, source) => {
|
|
8
49
|
for (const key in source) {
|
|
9
50
|
if (source.hasOwnProperty(key)) {
|
|
@@ -15,6 +56,14 @@ export const deepMerge = (target, source) => {
|
|
|
15
56
|
}
|
|
16
57
|
return target;
|
|
17
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* Combines an array of objects into a single object. If the same key exists in multiple objects, the values are merged.
|
|
61
|
+
*
|
|
62
|
+
* @param arr - Array of objects to be combined.
|
|
63
|
+
* @returns Record<string, any> - A single object with combined keys and values.
|
|
64
|
+
*
|
|
65
|
+
* Note: Handles nested objects by recursively combining them. Non-object values with the same key are merged into arrays.
|
|
66
|
+
*/
|
|
18
67
|
export const combineObjects = (arr) => {
|
|
19
68
|
const result = {};
|
|
20
69
|
for (const obj of arr) {
|
|
@@ -49,8 +98,33 @@ export const combineObjects = (arr) => {
|
|
|
49
98
|
}
|
|
50
99
|
return result;
|
|
51
100
|
};
|
|
101
|
+
/**
|
|
102
|
+
* Type guard function to check if the input is a number.
|
|
103
|
+
*
|
|
104
|
+
* @param input - The value to be checked.
|
|
105
|
+
* @returns boolean - True if the input is a number, false otherwise.
|
|
106
|
+
*
|
|
107
|
+
* 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.
|
|
108
|
+
*/
|
|
52
109
|
export const isNumber = (input) => !isNaN(parseFloat(input)) && !isNaN(input - 0);
|
|
110
|
+
/**
|
|
111
|
+
* Checks if the input is a valid email format.
|
|
112
|
+
*
|
|
113
|
+
* @param input - The value to be checked.
|
|
114
|
+
* @returns boolean - True if the input matches the email format, false otherwise.
|
|
115
|
+
*
|
|
116
|
+
* Note: Uses a regular expression to validate the email format, ensuring it has parts separated by '@' and contains a domain with a period.
|
|
117
|
+
*/
|
|
53
118
|
export const isEmail = (input) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(input));
|
|
119
|
+
/**
|
|
120
|
+
* Checks if the input is a valid URL format.
|
|
121
|
+
*
|
|
122
|
+
* @param input - The value to be checked.
|
|
123
|
+
* @returns boolean - True if the input matches the URL format, false otherwise.
|
|
124
|
+
*
|
|
125
|
+
* Note: Validates URLs including protocols (http/https), domain names, IP addresses, ports, paths, query strings, and fragments.
|
|
126
|
+
* Also recognizes 'tel:' and 'mailto:' as valid URL formats, as well as strings starting with '#' without spaces.
|
|
127
|
+
*/
|
|
54
128
|
export const isURL = (input) => {
|
|
55
129
|
if (typeof input !== "string")
|
|
56
130
|
return false;
|
|
@@ -68,20 +142,80 @@ export const isURL = (input) => {
|
|
|
68
142
|
return !!pattern.test(input);
|
|
69
143
|
}
|
|
70
144
|
};
|
|
145
|
+
/**
|
|
146
|
+
* Checks if the input contains HTML tags or entities.
|
|
147
|
+
*
|
|
148
|
+
* @param input - The value to be checked.
|
|
149
|
+
* @returns boolean - True if the input contains HTML tags or entities, false otherwise.
|
|
150
|
+
*
|
|
151
|
+
* Note: Uses a regular expression to detect HTML tags (like <tag>) and entities (like &entity;).
|
|
152
|
+
* Recognizes both opening and closing tags, as well as self-closing tags.
|
|
153
|
+
*/
|
|
71
154
|
export const isHTML = (input) => /<\/?\s*[a-z-][^>]*\s*>|(\&(?:[\w\d]+|#\d+|#x[a-f\d]+);)/g.test(input);
|
|
155
|
+
/**
|
|
156
|
+
* Type guard function to check if the input is a string, excluding strings that match specific formats (number, boolean, email, URL, IP).
|
|
157
|
+
*
|
|
158
|
+
* @param input - The value to be checked.
|
|
159
|
+
* @returns boolean - True if the input is a string that doesn't match the specific formats, false otherwise.
|
|
160
|
+
*
|
|
161
|
+
* Note: Validates the input against being a number, boolean, email, URL, or IP address to ensure it's a general string.
|
|
162
|
+
*/
|
|
72
163
|
export const isString = (input) => Object.prototype.toString.call(input) === "[object String]" &&
|
|
73
164
|
[isNumber, isBoolean, isEmail, isURL, isIP].every((fn) => !fn(input));
|
|
165
|
+
/**
|
|
166
|
+
* Checks if the input is a valid IP address format.
|
|
167
|
+
*
|
|
168
|
+
* @param input - The value to be checked.
|
|
169
|
+
* @returns boolean - True if the input matches the IP address format, false otherwise.
|
|
170
|
+
*
|
|
171
|
+
* Note: Uses a regular expression to validate IP addresses, ensuring they consist of four octets, each ranging from 0 to 255.
|
|
172
|
+
*/
|
|
74
173
|
export const isIP = (input) => /^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$/.test(input);
|
|
174
|
+
/**
|
|
175
|
+
* Type guard function to check if the input is a boolean or a string representation of a boolean.
|
|
176
|
+
*
|
|
177
|
+
* @param input - The value to be checked.
|
|
178
|
+
* @returns boolean - True if the input is a boolean value or 'true'/'false' strings, false otherwise.
|
|
179
|
+
*
|
|
180
|
+
* Note: Recognizes both boolean literals (true, false) and their string representations ("true", "false").
|
|
181
|
+
*/
|
|
75
182
|
export const isBoolean = (input) => typeof input === "boolean" ||
|
|
76
183
|
input === "true" ||
|
|
77
184
|
input === "false" ||
|
|
78
185
|
input === true ||
|
|
79
186
|
input === false;
|
|
187
|
+
/**
|
|
188
|
+
* Type guard function to check if the input is a password based on a specific length criterion.
|
|
189
|
+
*
|
|
190
|
+
* @param input - The value to be checked.
|
|
191
|
+
* @returns boolean - True if the input is a string with a length of 161 characters, false otherwise.
|
|
192
|
+
*
|
|
193
|
+
* Note: Specifically checks for string length to determine if it matches the defined password length criterion.
|
|
194
|
+
*/
|
|
80
195
|
export const isPassword = (input) => input.length === 161;
|
|
196
|
+
/**
|
|
197
|
+
* Checks if the input can be converted to a valid date.
|
|
198
|
+
*
|
|
199
|
+
* @param input - The input to be checked, can be of any type.
|
|
200
|
+
* @returns A boolean indicating whether the input is a valid date.
|
|
201
|
+
*/
|
|
81
202
|
export const isDate = (input) => !isNaN(new Date(input).getTime()) || !isNaN(Date.parse(input));
|
|
203
|
+
/**
|
|
204
|
+
* Checks if the input is a valid ID.
|
|
205
|
+
*
|
|
206
|
+
* @param input - The input to be checked, can be of any type.
|
|
207
|
+
* @returns A boolean indicating whether the input is a string representing a valid ID of length 32.
|
|
208
|
+
*/
|
|
82
209
|
export const isValidID = (input) => {
|
|
83
210
|
return typeof input === "string" && input.length === 32;
|
|
84
211
|
};
|
|
212
|
+
/**
|
|
213
|
+
* Identifies and returns properties that have changed between two objects.
|
|
214
|
+
*
|
|
215
|
+
* @param obj1 - The first object for comparison, with string keys and values.
|
|
216
|
+
* @param obj2 - The second object for comparison, with string keys and values.
|
|
217
|
+
* @returns A record of changed properties with original values from obj1 and new values from obj2, or null if no changes are found.
|
|
218
|
+
*/
|
|
85
219
|
export const findChangedProperties = (obj1, obj2) => {
|
|
86
220
|
const result = {};
|
|
87
221
|
for (const key1 in obj1)
|
|
@@ -89,6 +223,13 @@ export const findChangedProperties = (obj1, obj2) => {
|
|
|
89
223
|
result[obj1[key1]] = obj2[key1];
|
|
90
224
|
return Object.keys(result).length ? result : null;
|
|
91
225
|
};
|
|
226
|
+
/**
|
|
227
|
+
* Detects the field type of an input based on available types.
|
|
228
|
+
*
|
|
229
|
+
* @param input - The input whose field type is to be detected.
|
|
230
|
+
* @param availableTypes - An array of potential field types to consider.
|
|
231
|
+
* @returns The detected field type as a string, or undefined if no matching type is found.
|
|
232
|
+
*/
|
|
92
233
|
export const detectFieldType = (input, availableTypes) => {
|
|
93
234
|
if (!Array.isArray(input)) {
|
|
94
235
|
if ((input === "0" ||
|
|
@@ -126,6 +267,14 @@ export const detectFieldType = (input, availableTypes) => {
|
|
|
126
267
|
return "array";
|
|
127
268
|
return undefined;
|
|
128
269
|
};
|
|
270
|
+
/**
|
|
271
|
+
* Validates if the given value matches the specified field type(s).
|
|
272
|
+
*
|
|
273
|
+
* @param value - The value to be validated.
|
|
274
|
+
* @param fieldType - The expected field type or an array of possible field types.
|
|
275
|
+
* @param fieldChildrenType - Optional; the expected type(s) of children elements, used if the field type is an array.
|
|
276
|
+
* @returns A boolean indicating whether the value matches the specified field type(s).
|
|
277
|
+
*/
|
|
129
278
|
export const validateFieldType = (value, fieldType, fieldChildrenType) => {
|
|
130
279
|
if (value === null)
|
|
131
280
|
return true;
|
|
@@ -177,6 +326,12 @@ export const validateFieldType = (value, fieldType, fieldChildrenType) => {
|
|
|
177
326
|
return false;
|
|
178
327
|
}
|
|
179
328
|
};
|
|
329
|
+
/**
|
|
330
|
+
* Converts a nested object to dot notation, flattening the object's structure.
|
|
331
|
+
*
|
|
332
|
+
* @param input - The input object to be converted.
|
|
333
|
+
* @returns A flattened object using dot notation for keys.
|
|
334
|
+
*/
|
|
180
335
|
export const objectToDotNotation = (input) => {
|
|
181
336
|
const result = {};
|
|
182
337
|
const stack = [
|
package/dist/utils.server.d.ts
CHANGED
|
@@ -1,10 +1,52 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import { type Schema } from "./index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generates a hashed password using SHA-256.
|
|
5
|
+
*
|
|
6
|
+
* @param password - The plain text password to hash.
|
|
7
|
+
* @returns A string containing the salt and the hashed password, separated by a colon.
|
|
8
|
+
*/
|
|
3
9
|
export declare const hashPassword: (password: string) => string;
|
|
10
|
+
/**
|
|
11
|
+
* Compares a hashed password with an input password to verify a match.
|
|
12
|
+
*
|
|
13
|
+
* @param hashedPassword - The hashed password, containing both the salt and the hash, separated by a colon.
|
|
14
|
+
* @param inputPassword - The plain text input password to compare against the hashed password.
|
|
15
|
+
* @returns A boolean indicating whether the input password matches the hashed password.
|
|
16
|
+
*/
|
|
4
17
|
export declare const comparePassword: (hashedPassword: string, inputPassword: string) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Encodes an ID using AES-256-CBC encryption.
|
|
20
|
+
*
|
|
21
|
+
* @param id - The ID to encode, either a number or a string.
|
|
22
|
+
* @param secretKeyOrSalt - The secret key or salt for encryption, can be a string, number, or Buffer.
|
|
23
|
+
* @returns The encoded ID as a hexadecimal string.
|
|
24
|
+
*/
|
|
5
25
|
export declare const encodeID: (id: number | string, secretKeyOrSalt: string | number | Buffer) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Decodes an encrypted ID using AES-256-CBC decryption.
|
|
28
|
+
*
|
|
29
|
+
* @param input - The encrypted ID as a hexadecimal string.
|
|
30
|
+
* @param secretKeyOrSalt - The secret key or salt used for decryption, can be a string, number, or Buffer.
|
|
31
|
+
* @returns The decoded ID as a number.
|
|
32
|
+
*/
|
|
6
33
|
export declare const decodeID: (input: string, secretKeyOrSalt: string | number | Buffer) => number;
|
|
34
|
+
/**
|
|
35
|
+
* Finds the last ID number in a schema, potentially decoding it if encrypted.
|
|
36
|
+
*
|
|
37
|
+
* @param schema - The schema to search, defined as an array of schema objects.
|
|
38
|
+
* @param secretKeyOrSalt - The secret key or salt for decoding an encrypted ID, can be a string, number, or Buffer.
|
|
39
|
+
* @returns The last ID number in the schema, decoded if necessary.
|
|
40
|
+
*/
|
|
7
41
|
export declare const findLastIdNumber: (schema: Schema, secretKeyOrSalt: string | number | Buffer) => number;
|
|
42
|
+
/**
|
|
43
|
+
* Adds or updates IDs in a schema, encoding them using a provided secret key or salt.
|
|
44
|
+
*
|
|
45
|
+
* @param schema - The schema to update, defined as an array of schema objects.
|
|
46
|
+
* @param oldIndex - The starting index for generating new IDs, defaults to 0.
|
|
47
|
+
* @param secretKeyOrSalt - The secret key or salt for encoding IDs, can be a string, number, or Buffer.
|
|
48
|
+
* @returns The updated schema with encoded IDs.
|
|
49
|
+
*/
|
|
8
50
|
export declare const addIdToSchema: (schema: Schema, oldIndex: number | undefined, secretKeyOrSalt: string | number | Buffer) => import("./index.js").Field[];
|
|
9
51
|
export default class UtilsServer {
|
|
10
52
|
static encodeID: (id: string | number, secretKeyOrSalt: string | number | Buffer) => string;
|
package/dist/utils.server.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { createCipheriv, createDecipheriv, randomBytes, scryptSync, createHash, } from "node:crypto";
|
|
2
2
|
import { isArrayOfObjects, isNumber, isValidID } from "./utils.js";
|
|
3
|
+
/**
|
|
4
|
+
* Generates a hashed password using SHA-256.
|
|
5
|
+
*
|
|
6
|
+
* @param password - The plain text password to hash.
|
|
7
|
+
* @returns A string containing the salt and the hashed password, separated by a colon.
|
|
8
|
+
*/
|
|
3
9
|
export const hashPassword = (password) => {
|
|
4
10
|
const salt = randomBytes(16).toString("hex");
|
|
5
11
|
const hash = createHash("sha256")
|
|
@@ -7,6 +13,13 @@ export const hashPassword = (password) => {
|
|
|
7
13
|
.digest("hex");
|
|
8
14
|
return `${salt}:${hash}`;
|
|
9
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Compares a hashed password with an input password to verify a match.
|
|
18
|
+
*
|
|
19
|
+
* @param hashedPassword - The hashed password, containing both the salt and the hash, separated by a colon.
|
|
20
|
+
* @param inputPassword - The plain text input password to compare against the hashed password.
|
|
21
|
+
* @returns A boolean indicating whether the input password matches the hashed password.
|
|
22
|
+
*/
|
|
10
23
|
export const comparePassword = (hashedPassword, inputPassword) => {
|
|
11
24
|
const [salt, originalHash] = hashedPassword.split(":");
|
|
12
25
|
const inputHash = createHash("sha256")
|
|
@@ -14,6 +27,13 @@ export const comparePassword = (hashedPassword, inputPassword) => {
|
|
|
14
27
|
.digest("hex");
|
|
15
28
|
return inputHash === originalHash;
|
|
16
29
|
};
|
|
30
|
+
/**
|
|
31
|
+
* Encodes an ID using AES-256-CBC encryption.
|
|
32
|
+
*
|
|
33
|
+
* @param id - The ID to encode, either a number or a string.
|
|
34
|
+
* @param secretKeyOrSalt - The secret key or salt for encryption, can be a string, number, or Buffer.
|
|
35
|
+
* @returns The encoded ID as a hexadecimal string.
|
|
36
|
+
*/
|
|
17
37
|
export const encodeID = (id, secretKeyOrSalt) => {
|
|
18
38
|
let cipher;
|
|
19
39
|
if (Buffer.isBuffer(secretKeyOrSalt))
|
|
@@ -24,6 +44,13 @@ export const encodeID = (id, secretKeyOrSalt) => {
|
|
|
24
44
|
}
|
|
25
45
|
return cipher.update(id.toString(), "utf8", "hex") + cipher.final("hex");
|
|
26
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Decodes an encrypted ID using AES-256-CBC decryption.
|
|
49
|
+
*
|
|
50
|
+
* @param input - The encrypted ID as a hexadecimal string.
|
|
51
|
+
* @param secretKeyOrSalt - The secret key or salt used for decryption, can be a string, number, or Buffer.
|
|
52
|
+
* @returns The decoded ID as a number.
|
|
53
|
+
*/
|
|
27
54
|
export const decodeID = (input, secretKeyOrSalt) => {
|
|
28
55
|
let decipher;
|
|
29
56
|
if (Buffer.isBuffer(secretKeyOrSalt))
|
|
@@ -34,6 +61,13 @@ export const decodeID = (input, secretKeyOrSalt) => {
|
|
|
34
61
|
}
|
|
35
62
|
return Number(decipher.update(input, "hex", "utf8") + decipher.final("utf8"));
|
|
36
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Finds the last ID number in a schema, potentially decoding it if encrypted.
|
|
66
|
+
*
|
|
67
|
+
* @param schema - The schema to search, defined as an array of schema objects.
|
|
68
|
+
* @param secretKeyOrSalt - The secret key or salt for decoding an encrypted ID, can be a string, number, or Buffer.
|
|
69
|
+
* @returns The last ID number in the schema, decoded if necessary.
|
|
70
|
+
*/
|
|
37
71
|
export const findLastIdNumber = (schema, secretKeyOrSalt) => {
|
|
38
72
|
const lastField = schema[schema.length - 1];
|
|
39
73
|
if (lastField) {
|
|
@@ -47,6 +81,14 @@ export const findLastIdNumber = (schema, secretKeyOrSalt) => {
|
|
|
47
81
|
}
|
|
48
82
|
return 0;
|
|
49
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* Adds or updates IDs in a schema, encoding them using a provided secret key or salt.
|
|
86
|
+
*
|
|
87
|
+
* @param schema - The schema to update, defined as an array of schema objects.
|
|
88
|
+
* @param oldIndex - The starting index for generating new IDs, defaults to 0.
|
|
89
|
+
* @param secretKeyOrSalt - The secret key or salt for encoding IDs, can be a string, number, or Buffer.
|
|
90
|
+
* @returns The updated schema with encoded IDs.
|
|
91
|
+
*/
|
|
50
92
|
export const addIdToSchema = (schema, oldIndex = 0, secretKeyOrSalt) => schema.map((field) => {
|
|
51
93
|
if (!field.id) {
|
|
52
94
|
oldIndex++;
|