inibase 1.0.0-rc.23 → 1.0.0-rc.25
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 +10 -10
- package/dist/file.js +193 -287
- package/dist/index.d.ts +6 -5
- package/dist/index.js +174 -133
- package/dist/utils.d.ts +5 -5
- package/dist/utils.js +3 -12
- package/dist/utils.server.d.ts +2 -2
- package/dist/utils.server.js +5 -5
- package/package.json +6 -3
package/dist/file.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
import { ComparisonOperator, FieldType } from "./index.js";
|
|
3
3
|
export declare const isExists: (path: string) => Promise<boolean>;
|
|
4
|
-
export declare const encode: (input: string | number | boolean | null | (string | number | boolean | null)[], secretKey?: string | Buffer) => string | number | boolean;
|
|
4
|
+
export declare const encode: (input: string | number | boolean | null | (string | number | boolean | null)[], secretKey?: string | Buffer) => string | number | boolean | null;
|
|
5
5
|
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)[];
|
|
6
6
|
export declare const get: (filePath: string, lineNumbers?: number | number[], fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[], secretKey?: string | Buffer) => Promise<[
|
|
7
|
-
Record<number, string | number | boolean | (string | number | boolean | (string | number | boolean)[])[]> | null,
|
|
7
|
+
Record<number, string | number | boolean | null | (string | number | boolean | (string | number | boolean)[] | null)[]> | null,
|
|
8
8
|
number
|
|
9
9
|
]>;
|
|
10
10
|
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)[]> | Map<number, string | number | boolean | (string | number | boolean)[]>) => Promise<void>;
|
|
@@ -20,16 +20,16 @@ export declare const max: (filePath: string, lineNumbers?: number | number[]) =>
|
|
|
20
20
|
export declare const min: (filePath: string, lineNumbers?: number | number[]) => Promise<number>;
|
|
21
21
|
export declare const sort: (filePath: string, sortDirection: 1 | -1 | "asc" | "desc", lineNumbers?: number | number[], _lineNumbersPerChunk?: number) => Promise<void>;
|
|
22
22
|
export default class File {
|
|
23
|
-
static get: (filePath: string, lineNumbers?: number | number[], fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[], secretKey?: string | Buffer) => Promise<[Record<number, string | number | boolean | (string | number | boolean | (string | number | boolean)[])[]
|
|
23
|
+
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
24
|
static remove: (filePath: string, linesToDelete: number | number[]) => Promise<void>;
|
|
25
|
-
static search: (filePath: string, operator: ComparisonOperator | ComparisonOperator[], comparedAtValue: string | number | boolean | (string | number | boolean)[], logicalOperator?: "and" | "or", fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[], limit?: number, offset?: number, readWholeFile?: boolean, secretKey?: string | Buffer) => Promise<[Record<number, string | number | boolean | (string | number | boolean)[]
|
|
26
|
-
static replace: (filePath: string, replacements: string | number | boolean | (string | number | boolean)[] | Record<number, string | number | boolean | (string | number | boolean)[]> | Map<number, string | number | boolean | (string | number | boolean)[]>) => Promise<void>;
|
|
25
|
+
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> | Map<number, string | number | boolean | (string | number | boolean)[]> | null) => Promise<void>;
|
|
27
27
|
static count: (filePath: string) => Promise<number>;
|
|
28
|
-
static encode: (input: string | number | boolean | (string | number | boolean)[], secretKey?: string | Buffer) => string | number | boolean;
|
|
29
|
-
static decode: (input: string | number, fieldType?: FieldType | FieldType[], fieldChildrenType?: FieldType | FieldType[], secretKey?: string | Buffer) => string | number | boolean | (string | number | boolean)[];
|
|
28
|
+
static encode: (input: string | number | boolean | (string | number | boolean | null)[] | null, secretKey?: string | Buffer | undefined) => string | number | boolean | null;
|
|
29
|
+
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;
|
|
30
30
|
static isExists: (path: string) => Promise<boolean>;
|
|
31
|
-
static sum: (filePath: string, lineNumbers?: number | number[]) => Promise<number>;
|
|
32
|
-
static min: (filePath: string, lineNumbers?: number | number[]) => Promise<number>;
|
|
33
|
-
static max: (filePath: string, lineNumbers?: number | number[]) => Promise<number>;
|
|
31
|
+
static sum: (filePath: string, lineNumbers?: number | number[] | undefined) => Promise<number>;
|
|
32
|
+
static min: (filePath: string, lineNumbers?: number | number[] | undefined) => Promise<number>;
|
|
33
|
+
static max: (filePath: string, lineNumbers?: number | number[] | undefined) => Promise<number>;
|
|
34
34
|
static append: (filePath: string, data: string | number | (string | number)[], startsAt?: number) => Promise<void>;
|
|
35
35
|
}
|
package/dist/file.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { open, rename, stat, writeFile } from "node:fs/promises";
|
|
1
|
+
import { open, rename, stat, writeFile, appendFile, } from "node:fs/promises";
|
|
2
2
|
import { createInterface } from "node:readline";
|
|
3
|
-
import { detectFieldType, isArrayOfArrays, isNumber } from "./utils.js";
|
|
3
|
+
import { detectFieldType, isArrayOfArrays, isNumber, isObject, } from "./utils.js";
|
|
4
4
|
import { encodeID, comparePassword } from "./utils.server.js";
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const readLineInternface = (fileHandle) => {
|
|
6
|
+
return createInterface({
|
|
7
|
+
input: fileHandle.createReadStream(),
|
|
8
|
+
crlfDelay: Infinity,
|
|
9
|
+
});
|
|
8
10
|
};
|
|
9
11
|
export const isExists = async (path) => {
|
|
10
12
|
try {
|
|
@@ -15,12 +17,12 @@ export const isExists = async (path) => {
|
|
|
15
17
|
return false;
|
|
16
18
|
}
|
|
17
19
|
};
|
|
18
|
-
const delimiters = [",", "|", "&", "$", "#", "@", "^", "
|
|
20
|
+
const delimiters = [",", "|", "&", "$", "#", "@", "^", ":", "!", ";"];
|
|
19
21
|
const secureString = (input) => {
|
|
20
22
|
if (["true", "false"].includes(String(input)))
|
|
21
23
|
return input ? 1 : 0;
|
|
22
24
|
return typeof input === "string"
|
|
23
|
-
? decodeURIComponent(input)
|
|
25
|
+
? decodeURIComponent(input.replace(/%(?![0-9][0-9a-fA-F]+)/g, ""))
|
|
24
26
|
.replaceAll("<", "<")
|
|
25
27
|
.replaceAll(">", ">")
|
|
26
28
|
.replaceAll(",", "%2C")
|
|
@@ -30,7 +32,6 @@ const secureString = (input) => {
|
|
|
30
32
|
.replaceAll("#", "%23")
|
|
31
33
|
.replaceAll("@", "%40")
|
|
32
34
|
.replaceAll("^", "%5E")
|
|
33
|
-
.replaceAll("%", "%25")
|
|
34
35
|
.replaceAll(":", "%3A")
|
|
35
36
|
.replaceAll("!", "%21")
|
|
36
37
|
.replaceAll(";", "%3B")
|
|
@@ -61,7 +62,6 @@ const unSecureString = (input) => input
|
|
|
61
62
|
.replaceAll("%23", "#")
|
|
62
63
|
.replaceAll("%40", "@")
|
|
63
64
|
.replaceAll("%5E", "^")
|
|
64
|
-
.replaceAll("%25", "%")
|
|
65
65
|
.replaceAll("%3A", ":")
|
|
66
66
|
.replaceAll("%21", "!")
|
|
67
67
|
.replaceAll("%3B", ";")
|
|
@@ -99,7 +99,9 @@ const decodeHelper = (value, fieldType, fieldChildrenType, secretKey) => {
|
|
|
99
99
|
: fieldChildrenType, undefined, secretKey))
|
|
100
100
|
: value;
|
|
101
101
|
case "id":
|
|
102
|
-
return isNumber(value)
|
|
102
|
+
return isNumber(value) && secretKey
|
|
103
|
+
? encodeID(value, secretKey)
|
|
104
|
+
: value;
|
|
103
105
|
default:
|
|
104
106
|
return value;
|
|
105
107
|
}
|
|
@@ -118,169 +120,108 @@ export const decode = (input, fieldType, fieldChildrenType, secretKey) => {
|
|
|
118
120
|
: input, fieldType, fieldChildrenType, secretKey);
|
|
119
121
|
};
|
|
120
122
|
export const get = async (filePath, lineNumbers, fieldType, fieldChildrenType, secretKey) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
: createInterface({
|
|
127
|
-
input: fileHandle.createReadStream(),
|
|
128
|
-
crlfDelay: Infinity,
|
|
129
|
-
});
|
|
130
|
-
let lines = new Map(), lineCount = 0;
|
|
131
|
-
if (!lineNumbers) {
|
|
132
|
-
for await (const line of rl)
|
|
133
|
-
lineCount++,
|
|
134
|
-
lines.set(lineCount, decode(line, fieldType, fieldChildrenType, secretKey));
|
|
135
|
-
}
|
|
136
|
-
else if (lineNumbers === -1) {
|
|
137
|
-
let lastLine;
|
|
138
|
-
for await (const line of rl)
|
|
139
|
-
lineCount++, (lastLine = line);
|
|
140
|
-
if (lastLine)
|
|
141
|
-
lines.set(lineCount, decode(lastLine, fieldType, fieldChildrenType, secretKey));
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
|
|
145
|
-
for await (const line of rl) {
|
|
146
|
-
lineCount++;
|
|
147
|
-
if (!lineNumbersArray.has(lineCount))
|
|
148
|
-
continue;
|
|
123
|
+
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
124
|
+
let lines = new Map(), lineCount = 0;
|
|
125
|
+
if (!lineNumbers) {
|
|
126
|
+
for await (const line of rl)
|
|
127
|
+
lineCount++,
|
|
149
128
|
lines.set(lineCount, decode(line, fieldType, fieldChildrenType, secretKey));
|
|
150
|
-
lineNumbersArray.delete(lineCount);
|
|
151
|
-
if (!lineNumbersArray.size)
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return [lines.size ? Object.fromEntries(lines) : null, lineCount];
|
|
156
129
|
}
|
|
157
|
-
|
|
158
|
-
|
|
130
|
+
else if (lineNumbers === -1) {
|
|
131
|
+
let lastLine = null;
|
|
132
|
+
for await (const line of rl)
|
|
133
|
+
lineCount++, (lastLine = line);
|
|
134
|
+
if (lastLine)
|
|
135
|
+
lines.set(lineCount, decode(lastLine, fieldType, fieldChildrenType, secretKey));
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
|
|
139
|
+
for await (const line of rl) {
|
|
140
|
+
lineCount++;
|
|
141
|
+
if (!lineNumbersArray.has(lineCount))
|
|
142
|
+
continue;
|
|
143
|
+
lines.set(lineCount, decode(line, fieldType, fieldChildrenType, secretKey));
|
|
144
|
+
lineNumbersArray.delete(lineCount);
|
|
145
|
+
if (!lineNumbersArray.size)
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
159
148
|
}
|
|
149
|
+
await fileHandle.close();
|
|
150
|
+
return [lines.size ? Object.fromEntries(lines) : null, lineCount];
|
|
160
151
|
};
|
|
161
152
|
export const replace = async (filePath, replacements) => {
|
|
162
153
|
if (await isExists(filePath)) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
writeStream.write(
|
|
180
|
-
? replacements.get(lineCount.toString())
|
|
181
|
-
: line) + "\n");
|
|
182
|
-
}
|
|
183
|
-
const newLinesNumbers = new Set([...replacements.keys()].filter((num) => num > lineCount));
|
|
184
|
-
if (newLinesNumbers.size) {
|
|
185
|
-
if (Math.min(...newLinesNumbers) - lineCount - 1 > 1)
|
|
186
|
-
writeStream.write("\n".repeat(Math.min(...newLinesNumbers) - lineCount - 1));
|
|
187
|
-
for (const newLineNumber of newLinesNumbers)
|
|
188
|
-
writeStream.write(replacements.get(newLineNumber.toString()) + "\n");
|
|
189
|
-
}
|
|
154
|
+
let lineCount = 0;
|
|
155
|
+
const fileHandle = await open(filePath, "r"), fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`, fileTempHandle = await open(fileTempPath, "w"), rl = readLineInternface(fileHandle), writeStream = fileTempHandle.createWriteStream();
|
|
156
|
+
if (isObject(replacements)) {
|
|
157
|
+
if (!(replacements instanceof Map))
|
|
158
|
+
replacements = new Map(Object.entries(replacements));
|
|
159
|
+
for await (const line of rl) {
|
|
160
|
+
lineCount++;
|
|
161
|
+
writeStream.write((replacements.has(lineCount.toString())
|
|
162
|
+
? replacements.get(lineCount.toString())
|
|
163
|
+
: line) + "\n");
|
|
164
|
+
}
|
|
165
|
+
const newLinesNumbers = new Set([...replacements.keys()].filter((num) => num > lineCount));
|
|
166
|
+
if (newLinesNumbers.size) {
|
|
167
|
+
if (Math.min(...newLinesNumbers) - lineCount - 1 > 1)
|
|
168
|
+
writeStream.write("\n".repeat(Math.min(...newLinesNumbers) - lineCount - 1));
|
|
169
|
+
for await (const newLineNumber of newLinesNumbers)
|
|
170
|
+
writeStream.write(replacements.get(newLineNumber.toString()) + "\n");
|
|
190
171
|
}
|
|
191
|
-
else
|
|
192
|
-
for await (const _line of rl)
|
|
193
|
-
writeStream.write(replacements + "\n");
|
|
194
|
-
await rename(fileTempPath, filePath);
|
|
195
|
-
}
|
|
196
|
-
finally {
|
|
197
|
-
await fileHandle?.close();
|
|
198
|
-
await fileTempHandle?.close();
|
|
199
172
|
}
|
|
173
|
+
else
|
|
174
|
+
for await (const _line of rl)
|
|
175
|
+
writeStream.write(replacements + "\n");
|
|
176
|
+
await fileHandle.close();
|
|
177
|
+
await fileTempHandle.close();
|
|
178
|
+
await rename(fileTempPath, filePath);
|
|
200
179
|
}
|
|
201
|
-
else if (
|
|
180
|
+
else if (isObject(replacements)) {
|
|
202
181
|
if (!(replacements instanceof Map))
|
|
203
|
-
replacements = new Map(Object.entries(replacements));
|
|
182
|
+
replacements = new Map(Object.entries(replacements).map(([key, value]) => [Number(key), value]));
|
|
204
183
|
await writeFile(filePath, (Math.min(...replacements.keys()) - 1 > 1
|
|
205
184
|
? "\n".repeat(Math.min(...replacements.keys()) - 1)
|
|
206
185
|
: "") +
|
|
207
|
-
|
|
186
|
+
Array.from(new Map([...replacements.entries()].sort(([keyA], [keyB]) => keyA - keyB)).values()).join("\n") +
|
|
208
187
|
"\n");
|
|
209
188
|
}
|
|
210
189
|
};
|
|
211
190
|
export const append = async (filePath, data, startsAt = 1) => {
|
|
212
|
-
let
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
writeStream.write(input + "\n");
|
|
224
|
-
}
|
|
225
|
-
else
|
|
226
|
-
writeStream.write(data + "\n");
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
if (startsAt - 1 > 0)
|
|
230
|
-
writeStream.write("\n".repeat(startsAt - 1));
|
|
231
|
-
if (Array.isArray(data)) {
|
|
232
|
-
for (const input of data)
|
|
233
|
-
writeStream.write(input + "\n");
|
|
234
|
-
}
|
|
235
|
-
else
|
|
236
|
-
writeStream.write(data + "\n");
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
finally {
|
|
240
|
-
await fileHandle?.close();
|
|
241
|
-
}
|
|
191
|
+
let currentNumberOfLines = 0;
|
|
192
|
+
const doesFileExists = await isExists(filePath);
|
|
193
|
+
if (doesFileExists)
|
|
194
|
+
currentNumberOfLines = await count(filePath);
|
|
195
|
+
await appendFile(filePath, (currentNumberOfLines > 0
|
|
196
|
+
? startsAt - currentNumberOfLines - 1 > 0
|
|
197
|
+
? "\n".repeat(startsAt - currentNumberOfLines - 1)
|
|
198
|
+
: ""
|
|
199
|
+
: "") +
|
|
200
|
+
(Array.isArray(data) ? data.join("\n") : data) +
|
|
201
|
+
"\n");
|
|
242
202
|
};
|
|
243
203
|
export const remove = async (filePath, linesToDelete) => {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
input: fileHandle.createReadStream(),
|
|
253
|
-
crlfDelay: Infinity,
|
|
254
|
-
}), writeStream = fileTempHandle.createWriteStream();
|
|
255
|
-
for await (const line of rl) {
|
|
256
|
-
lineCount++;
|
|
257
|
-
if (!linesToDeleteArray.has(lineCount))
|
|
258
|
-
writeStream.write(`${line}\n`);
|
|
259
|
-
}
|
|
260
|
-
await rename(fileTempPath, filePath);
|
|
261
|
-
}
|
|
262
|
-
finally {
|
|
263
|
-
await fileTempHandle?.close();
|
|
264
|
-
await fileHandle?.close();
|
|
204
|
+
let lineCount = 0;
|
|
205
|
+
const fileHandle = await open(filePath, "r"), fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`, fileTempHandle = await open(fileTempPath, "w"), linesToDeleteArray = new Set(Array.isArray(linesToDelete)
|
|
206
|
+
? linesToDelete.map(Number)
|
|
207
|
+
: [Number(linesToDelete)]), rl = readLineInternface(fileHandle), writeStream = fileTempHandle.createWriteStream();
|
|
208
|
+
for await (const line of rl) {
|
|
209
|
+
lineCount++;
|
|
210
|
+
if (!linesToDeleteArray.has(lineCount))
|
|
211
|
+
writeStream.write(`${line}\n`);
|
|
265
212
|
}
|
|
213
|
+
await rename(fileTempPath, filePath);
|
|
214
|
+
await fileTempHandle.close();
|
|
215
|
+
await fileHandle.close();
|
|
266
216
|
};
|
|
267
217
|
export const count = async (filePath) => {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
crlfDelay: Infinity,
|
|
276
|
-
});
|
|
277
|
-
for await (const line of rl)
|
|
278
|
-
lineCount++;
|
|
279
|
-
return lineCount;
|
|
280
|
-
}
|
|
281
|
-
finally {
|
|
282
|
-
await fileHandle.close();
|
|
283
|
-
}
|
|
218
|
+
// return Number((await exec(`wc -l < ${filePath}`)).stdout.trim());
|
|
219
|
+
let lineCount = 0;
|
|
220
|
+
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
221
|
+
for await (const line of rl)
|
|
222
|
+
lineCount++;
|
|
223
|
+
await fileHandle.close();
|
|
224
|
+
return lineCount;
|
|
284
225
|
};
|
|
285
226
|
const handleComparisonOperator = (operator, originalValue, comparedAtValue, fieldType, fieldChildrenType) => {
|
|
286
227
|
if (Array.isArray(fieldType))
|
|
@@ -304,13 +245,21 @@ const handleComparisonOperator = (operator, originalValue, comparedAtValue, fiel
|
|
|
304
245
|
case "!=":
|
|
305
246
|
return !handleComparisonOperator("=", originalValue, comparedAtValue, fieldType);
|
|
306
247
|
case ">":
|
|
307
|
-
return originalValue
|
|
248
|
+
return (originalValue !== null &&
|
|
249
|
+
comparedAtValue !== null &&
|
|
250
|
+
originalValue > comparedAtValue);
|
|
308
251
|
case "<":
|
|
309
|
-
return originalValue
|
|
252
|
+
return (originalValue !== null &&
|
|
253
|
+
comparedAtValue !== null &&
|
|
254
|
+
originalValue < comparedAtValue);
|
|
310
255
|
case ">=":
|
|
311
|
-
return originalValue
|
|
256
|
+
return (originalValue !== null &&
|
|
257
|
+
comparedAtValue !== null &&
|
|
258
|
+
originalValue >= comparedAtValue);
|
|
312
259
|
case "<=":
|
|
313
|
-
return originalValue
|
|
260
|
+
return (originalValue !== null &&
|
|
261
|
+
comparedAtValue !== null &&
|
|
262
|
+
originalValue <= comparedAtValue);
|
|
314
263
|
case "[]":
|
|
315
264
|
return ((Array.isArray(originalValue) &&
|
|
316
265
|
Array.isArray(comparedAtValue) &&
|
|
@@ -334,153 +283,110 @@ const handleComparisonOperator = (operator, originalValue, comparedAtValue, fiel
|
|
|
334
283
|
}
|
|
335
284
|
};
|
|
336
285
|
export const search = async (filePath, operator, comparedAtValue, logicalOperator, fieldType, fieldChildrenType, limit, offset, readWholeFile, secretKey) => {
|
|
337
|
-
let
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
(!Array.isArray(operator) &&
|
|
356
|
-
handleComparisonOperator(operator, decodedLine, comparedAtValue, fieldType))) {
|
|
357
|
-
foundItems++;
|
|
358
|
-
if (offset && foundItems < offset)
|
|
286
|
+
let RETURN = new Map(), lineCount = 0, foundItems = 0;
|
|
287
|
+
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
288
|
+
for await (const line of rl) {
|
|
289
|
+
lineCount++;
|
|
290
|
+
const decodedLine = decode(line, fieldType, fieldChildrenType, secretKey);
|
|
291
|
+
if ((Array.isArray(operator) &&
|
|
292
|
+
Array.isArray(comparedAtValue) &&
|
|
293
|
+
((logicalOperator &&
|
|
294
|
+
logicalOperator === "or" &&
|
|
295
|
+
operator.some((single_operator, index) => handleComparisonOperator(single_operator, decodedLine, comparedAtValue[index], fieldType))) ||
|
|
296
|
+
operator.every((single_operator, index) => handleComparisonOperator(single_operator, decodedLine, comparedAtValue[index], fieldType)))) ||
|
|
297
|
+
(!Array.isArray(operator) &&
|
|
298
|
+
handleComparisonOperator(operator, decodedLine, comparedAtValue, fieldType))) {
|
|
299
|
+
foundItems++;
|
|
300
|
+
if (offset && foundItems < offset)
|
|
301
|
+
continue;
|
|
302
|
+
if (limit && foundItems > limit)
|
|
303
|
+
if (readWholeFile)
|
|
359
304
|
continue;
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
else
|
|
364
|
-
break;
|
|
365
|
-
RETURN.set(lineCount, decodedLine);
|
|
366
|
-
}
|
|
305
|
+
else
|
|
306
|
+
break;
|
|
307
|
+
RETURN.set(lineCount, decodedLine);
|
|
367
308
|
}
|
|
368
|
-
return foundItems
|
|
369
|
-
? [
|
|
370
|
-
Object.fromEntries(RETURN),
|
|
371
|
-
readWholeFile ? foundItems : foundItems - 1,
|
|
372
|
-
]
|
|
373
|
-
: [null, 0];
|
|
374
|
-
}
|
|
375
|
-
finally {
|
|
376
|
-
await fileHandle?.close();
|
|
377
309
|
}
|
|
310
|
+
await fileHandle.close();
|
|
311
|
+
return foundItems
|
|
312
|
+
? [Object.fromEntries(RETURN), readWholeFile ? foundItems : foundItems - 1]
|
|
313
|
+
: [null, 0];
|
|
378
314
|
};
|
|
379
315
|
export const sum = async (filePath, lineNumbers) => {
|
|
380
|
-
let
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
lineCount++;
|
|
394
|
-
if (!lineNumbersArray.has(lineCount))
|
|
395
|
-
continue;
|
|
396
|
-
sum += +decode(line, "number");
|
|
397
|
-
lineNumbersArray.delete(lineCount);
|
|
398
|
-
if (!lineNumbersArray.size)
|
|
399
|
-
break;
|
|
400
|
-
}
|
|
316
|
+
let sum = 0;
|
|
317
|
+
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
318
|
+
if (lineNumbers) {
|
|
319
|
+
let lineCount = 0;
|
|
320
|
+
let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
|
|
321
|
+
for await (const line of rl) {
|
|
322
|
+
lineCount++;
|
|
323
|
+
if (!lineNumbersArray.has(lineCount))
|
|
324
|
+
continue;
|
|
325
|
+
sum += +(decode(line, "number") ?? 0);
|
|
326
|
+
lineNumbersArray.delete(lineCount);
|
|
327
|
+
if (!lineNumbersArray.size)
|
|
328
|
+
break;
|
|
401
329
|
}
|
|
402
|
-
else
|
|
403
|
-
for await (const line of rl)
|
|
404
|
-
sum += +decode(line, "number");
|
|
405
|
-
return sum;
|
|
406
|
-
}
|
|
407
|
-
finally {
|
|
408
|
-
await fileHandle?.close();
|
|
409
330
|
}
|
|
331
|
+
else
|
|
332
|
+
for await (const line of rl)
|
|
333
|
+
sum += +(decode(line, "number") ?? 0);
|
|
334
|
+
await fileHandle.close();
|
|
335
|
+
return sum;
|
|
410
336
|
};
|
|
411
337
|
export const max = async (filePath, lineNumbers) => {
|
|
412
|
-
let
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
continue;
|
|
428
|
-
const lineContentNum = +decode(line, "number");
|
|
429
|
-
if (lineContentNum > max)
|
|
430
|
-
max = lineContentNum;
|
|
431
|
-
lineNumbersArray.delete(lineCount);
|
|
432
|
-
if (!lineNumbersArray.size)
|
|
433
|
-
break;
|
|
434
|
-
}
|
|
338
|
+
let max = 0;
|
|
339
|
+
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
340
|
+
if (lineNumbers) {
|
|
341
|
+
let lineCount = 0;
|
|
342
|
+
let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
|
|
343
|
+
for await (const line of rl) {
|
|
344
|
+
lineCount++;
|
|
345
|
+
if (!lineNumbersArray.has(lineCount))
|
|
346
|
+
continue;
|
|
347
|
+
const lineContentNum = +(decode(line, "number") ?? 0);
|
|
348
|
+
if (lineContentNum > max)
|
|
349
|
+
max = lineContentNum;
|
|
350
|
+
lineNumbersArray.delete(lineCount);
|
|
351
|
+
if (!lineNumbersArray.size)
|
|
352
|
+
break;
|
|
435
353
|
}
|
|
436
|
-
else
|
|
437
|
-
for await (const line of rl) {
|
|
438
|
-
const lineContentNum = +decode(line, "number");
|
|
439
|
-
if (lineContentNum > max)
|
|
440
|
-
max = lineContentNum;
|
|
441
|
-
}
|
|
442
|
-
return max;
|
|
443
|
-
}
|
|
444
|
-
finally {
|
|
445
|
-
await fileHandle?.close();
|
|
446
354
|
}
|
|
355
|
+
else
|
|
356
|
+
for await (const line of rl) {
|
|
357
|
+
const lineContentNum = +(decode(line, "number") ?? 0);
|
|
358
|
+
if (lineContentNum > max)
|
|
359
|
+
max = lineContentNum;
|
|
360
|
+
}
|
|
361
|
+
await fileHandle.close();
|
|
362
|
+
return max;
|
|
447
363
|
};
|
|
448
364
|
export const min = async (filePath, lineNumbers) => {
|
|
449
|
-
let
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
continue;
|
|
465
|
-
const lineContentNum = +decode(line, "number");
|
|
466
|
-
if (lineContentNum < min)
|
|
467
|
-
min = lineContentNum;
|
|
468
|
-
lineNumbersArray.delete(lineCount);
|
|
469
|
-
if (!lineNumbersArray.size)
|
|
470
|
-
break;
|
|
471
|
-
}
|
|
365
|
+
let min = 0;
|
|
366
|
+
const fileHandle = await open(filePath, "r"), rl = readLineInternface(fileHandle);
|
|
367
|
+
if (lineNumbers) {
|
|
368
|
+
let lineCount = 0;
|
|
369
|
+
let lineNumbersArray = new Set(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]);
|
|
370
|
+
for await (const line of rl) {
|
|
371
|
+
lineCount++;
|
|
372
|
+
if (!lineNumbersArray.has(lineCount))
|
|
373
|
+
continue;
|
|
374
|
+
const lineContentNum = +(decode(line, "number") ?? 0);
|
|
375
|
+
if (lineContentNum < min)
|
|
376
|
+
min = lineContentNum;
|
|
377
|
+
lineNumbersArray.delete(lineCount);
|
|
378
|
+
if (!lineNumbersArray.size)
|
|
379
|
+
break;
|
|
472
380
|
}
|
|
473
|
-
else
|
|
474
|
-
for await (const line of rl) {
|
|
475
|
-
const lineContentNum = +decode(line, "number");
|
|
476
|
-
if (lineContentNum < min)
|
|
477
|
-
min = lineContentNum;
|
|
478
|
-
}
|
|
479
|
-
return min;
|
|
480
|
-
}
|
|
481
|
-
finally {
|
|
482
|
-
await fileHandle?.close();
|
|
483
381
|
}
|
|
382
|
+
else
|
|
383
|
+
for await (const line of rl) {
|
|
384
|
+
const lineContentNum = +(decode(line, "number") ?? 0);
|
|
385
|
+
if (lineContentNum < min)
|
|
386
|
+
min = lineContentNum;
|
|
387
|
+
}
|
|
388
|
+
await fileHandle.close();
|
|
389
|
+
return min;
|
|
484
390
|
};
|
|
485
391
|
export const sort = async (filePath, sortDirection, lineNumbers, _lineNumbersPerChunk = 100000) => { };
|
|
486
392
|
export default class File {
|