inibase 1.0.0-rc.12 → 1.0.0-rc.120
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +374 -103
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +272 -0
- package/dist/file.d.ts +140 -0
- package/dist/file.js +704 -0
- package/dist/index.d.ts +201 -0
- package/dist/index.js +1444 -0
- package/dist/utils.d.ts +205 -0
- package/dist/utils.js +520 -0
- package/dist/utils.server.d.ts +85 -0
- package/dist/utils.server.js +249 -0
- package/package.json +66 -20
- package/.env.example +0 -1
- package/file.ts +0 -674
- package/index.test.ts +0 -248
- package/index.ts +0 -1587
- package/tsconfig.json +0 -7
- package/utils.ts +0 -366
package/file.ts
DELETED
|
@@ -1,674 +0,0 @@
|
|
|
1
|
-
import { createWriteStream, createReadStream, WriteStream } from "node:fs";
|
|
2
|
-
import { open, unlink, rename, stat } from "node:fs/promises";
|
|
3
|
-
import { Interface, createInterface } from "node:readline";
|
|
4
|
-
import { parse } from "node:path";
|
|
5
|
-
import { ComparisonOperator, FieldType } from ".";
|
|
6
|
-
import {
|
|
7
|
-
detectFieldType,
|
|
8
|
-
isArrayOfArrays,
|
|
9
|
-
isNumber,
|
|
10
|
-
encodeID,
|
|
11
|
-
comparePassword,
|
|
12
|
-
} from "./utils";
|
|
13
|
-
|
|
14
|
-
const doesSupportReadLines = () => {
|
|
15
|
-
const [major, minor, patch] = process.versions.node.split(".").map(Number);
|
|
16
|
-
return major >= 18 && minor >= 11;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const isExists = async (path: string) => {
|
|
20
|
-
try {
|
|
21
|
-
await stat(path);
|
|
22
|
-
return true;
|
|
23
|
-
} catch {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const delimiters = [",", "|", "&", "$", "#", "@", "^", "%", ":", "!", ";"];
|
|
29
|
-
|
|
30
|
-
export const encode = (
|
|
31
|
-
input:
|
|
32
|
-
| string
|
|
33
|
-
| number
|
|
34
|
-
| boolean
|
|
35
|
-
| null
|
|
36
|
-
| (string | number | boolean | null)[],
|
|
37
|
-
secretKey?: string | Buffer
|
|
38
|
-
) => {
|
|
39
|
-
const secureString = (input: string | number | boolean | null) => {
|
|
40
|
-
if (["true", "false"].includes(String(input))) return input ? 1 : 0;
|
|
41
|
-
return typeof input === "string"
|
|
42
|
-
? decodeURIComponent(input)
|
|
43
|
-
.replaceAll("<", "<")
|
|
44
|
-
.replaceAll(">", ">")
|
|
45
|
-
.replaceAll(",", "%2C")
|
|
46
|
-
.replaceAll("|", "%7C")
|
|
47
|
-
.replaceAll("&", "%26")
|
|
48
|
-
.replaceAll("$", "%24")
|
|
49
|
-
.replaceAll("#", "%23")
|
|
50
|
-
.replaceAll("@", "%40")
|
|
51
|
-
.replaceAll("^", "%5E")
|
|
52
|
-
.replaceAll("%", "%25")
|
|
53
|
-
.replaceAll(":", "%3A")
|
|
54
|
-
.replaceAll("!", "%21")
|
|
55
|
-
.replaceAll(";", "%3B")
|
|
56
|
-
.replaceAll("\n", "\\n")
|
|
57
|
-
.replaceAll("\r", "\\r")
|
|
58
|
-
: input;
|
|
59
|
-
},
|
|
60
|
-
secureArray = (arr_str: any[] | any): any[] | any =>
|
|
61
|
-
Array.isArray(arr_str) ? arr_str.map(secureArray) : secureString(arr_str),
|
|
62
|
-
joinMultidimensionalArray = (
|
|
63
|
-
arr: any[] | any[][],
|
|
64
|
-
delimiter_index = 0
|
|
65
|
-
): string => {
|
|
66
|
-
delimiter_index++;
|
|
67
|
-
if (isArrayOfArrays(arr))
|
|
68
|
-
arr = arr.map((ar: any[]) =>
|
|
69
|
-
joinMultidimensionalArray(ar, delimiter_index)
|
|
70
|
-
);
|
|
71
|
-
delimiter_index--;
|
|
72
|
-
return arr.join(delimiters[delimiter_index]);
|
|
73
|
-
};
|
|
74
|
-
return Array.isArray(input)
|
|
75
|
-
? joinMultidimensionalArray(secureArray(input))
|
|
76
|
-
: secureString(input);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export const decode = (
|
|
80
|
-
input: string | null | number,
|
|
81
|
-
fieldType?: FieldType | FieldType[],
|
|
82
|
-
fieldChildrenType?: FieldType | FieldType[],
|
|
83
|
-
secretKey?: string | Buffer
|
|
84
|
-
): string | number | boolean | null | (string | number | null | boolean)[] => {
|
|
85
|
-
if (!fieldType) return null;
|
|
86
|
-
const unSecureString = (input: string) =>
|
|
87
|
-
decodeURIComponent(input)
|
|
88
|
-
.replaceAll("<", "<")
|
|
89
|
-
.replaceAll(">", ">")
|
|
90
|
-
.replaceAll("%2C", ",")
|
|
91
|
-
.replaceAll("%7C", "|")
|
|
92
|
-
.replaceAll("%26", "&")
|
|
93
|
-
.replaceAll("%24", "$")
|
|
94
|
-
.replaceAll("%23", "#")
|
|
95
|
-
.replaceAll("%40", "@")
|
|
96
|
-
.replaceAll("%5E", "^")
|
|
97
|
-
.replaceAll("%25", "%")
|
|
98
|
-
.replaceAll("%3A", ":")
|
|
99
|
-
.replaceAll("%21", "!")
|
|
100
|
-
.replaceAll("%3B", ";")
|
|
101
|
-
.replaceAll("\\n", "\n")
|
|
102
|
-
.replaceAll("\\r", "\r") || null,
|
|
103
|
-
unSecureArray = (arr_str: any[] | any): any[] | any =>
|
|
104
|
-
Array.isArray(arr_str)
|
|
105
|
-
? arr_str.map(unSecureArray)
|
|
106
|
-
: unSecureString(arr_str),
|
|
107
|
-
reverseJoinMultidimensionalArray = (
|
|
108
|
-
joinedString: string | any[] | any[][]
|
|
109
|
-
): any | any[] | any[][] => {
|
|
110
|
-
const reverseJoinMultidimensionalArrayHelper = (
|
|
111
|
-
arr: any | any[] | any[][],
|
|
112
|
-
delimiter: string
|
|
113
|
-
) =>
|
|
114
|
-
Array.isArray(arr)
|
|
115
|
-
? arr.map((ar: any) =>
|
|
116
|
-
reverseJoinMultidimensionalArrayHelper(ar, delimiter)
|
|
117
|
-
)
|
|
118
|
-
: arr.split(delimiter);
|
|
119
|
-
|
|
120
|
-
const availableDelimiters = delimiters.filter((delimiter) =>
|
|
121
|
-
joinedString.includes(delimiter)
|
|
122
|
-
);
|
|
123
|
-
for (const delimiter of availableDelimiters) {
|
|
124
|
-
joinedString = Array.isArray(joinedString)
|
|
125
|
-
? reverseJoinMultidimensionalArrayHelper(joinedString, delimiter)
|
|
126
|
-
: joinedString.split(delimiter);
|
|
127
|
-
}
|
|
128
|
-
return joinedString;
|
|
129
|
-
},
|
|
130
|
-
decodeHelper = (value: string | number | any[]) => {
|
|
131
|
-
if (Array.isArray(value) && fieldType !== "array")
|
|
132
|
-
return value.map(decodeHelper);
|
|
133
|
-
switch (fieldType as FieldType) {
|
|
134
|
-
case "table":
|
|
135
|
-
case "number":
|
|
136
|
-
return isNumber(value) ? Number(value) : null;
|
|
137
|
-
case "boolean":
|
|
138
|
-
return typeof value === "string" ? value === "true" : Boolean(value);
|
|
139
|
-
case "array":
|
|
140
|
-
if (!Array.isArray(value)) return [value];
|
|
141
|
-
|
|
142
|
-
if (fieldChildrenType)
|
|
143
|
-
return value.map(
|
|
144
|
-
(v) =>
|
|
145
|
-
decode(
|
|
146
|
-
v,
|
|
147
|
-
Array.isArray(fieldChildrenType)
|
|
148
|
-
? detectFieldType(v, fieldChildrenType)
|
|
149
|
-
: fieldChildrenType,
|
|
150
|
-
undefined,
|
|
151
|
-
secretKey
|
|
152
|
-
) as string | number | boolean | null
|
|
153
|
-
);
|
|
154
|
-
else return value;
|
|
155
|
-
case "id":
|
|
156
|
-
return isNumber(value) ? encodeID(value as number, secretKey) : value;
|
|
157
|
-
default:
|
|
158
|
-
return value;
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
if (input === null || input === "") return null;
|
|
162
|
-
if (Array.isArray(fieldType))
|
|
163
|
-
fieldType = detectFieldType(String(input), fieldType);
|
|
164
|
-
return decodeHelper(
|
|
165
|
-
typeof input === "string"
|
|
166
|
-
? input.includes(",")
|
|
167
|
-
? unSecureArray(reverseJoinMultidimensionalArray(input))
|
|
168
|
-
: unSecureString(input)
|
|
169
|
-
: input
|
|
170
|
-
);
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
export const get = async (
|
|
174
|
-
filePath: string,
|
|
175
|
-
lineNumbers?: number | number[],
|
|
176
|
-
fieldType?: FieldType | FieldType[],
|
|
177
|
-
fieldChildrenType?: FieldType | FieldType[],
|
|
178
|
-
secretKey?: string | Buffer
|
|
179
|
-
): Promise<
|
|
180
|
-
[
|
|
181
|
-
Record<
|
|
182
|
-
number,
|
|
183
|
-
| string
|
|
184
|
-
| number
|
|
185
|
-
| boolean
|
|
186
|
-
| (string | number | boolean | (string | number | boolean)[])[]
|
|
187
|
-
> | null,
|
|
188
|
-
number
|
|
189
|
-
]
|
|
190
|
-
> => {
|
|
191
|
-
let rl: Interface;
|
|
192
|
-
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
193
|
-
else
|
|
194
|
-
rl = createInterface({
|
|
195
|
-
input: createReadStream(filePath),
|
|
196
|
-
crlfDelay: Infinity,
|
|
197
|
-
});
|
|
198
|
-
let lines: Record<
|
|
199
|
-
number,
|
|
200
|
-
| string
|
|
201
|
-
| number
|
|
202
|
-
| boolean
|
|
203
|
-
| (string | number | boolean | (string | number | boolean)[] | null)[]
|
|
204
|
-
| null
|
|
205
|
-
> = {},
|
|
206
|
-
lineCount = 0;
|
|
207
|
-
|
|
208
|
-
if (!lineNumbers) {
|
|
209
|
-
for await (const line of rl)
|
|
210
|
-
lineCount++,
|
|
211
|
-
(lines[lineCount] = decode(
|
|
212
|
-
line,
|
|
213
|
-
fieldType,
|
|
214
|
-
fieldChildrenType,
|
|
215
|
-
secretKey
|
|
216
|
-
));
|
|
217
|
-
} else if (lineNumbers === -1) {
|
|
218
|
-
let lastLine: string;
|
|
219
|
-
for await (const line of rl) lineCount++, (lastLine = line);
|
|
220
|
-
if (lastLine)
|
|
221
|
-
lines = {
|
|
222
|
-
[lineCount]: decode(lastLine, fieldType, fieldChildrenType, secretKey),
|
|
223
|
-
};
|
|
224
|
-
} else {
|
|
225
|
-
let lineNumbersArray = [
|
|
226
|
-
...(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]),
|
|
227
|
-
];
|
|
228
|
-
for await (const line of rl) {
|
|
229
|
-
lineCount++;
|
|
230
|
-
if (!lineNumbersArray.includes(lineCount)) continue;
|
|
231
|
-
lines[lineCount] = decode(line, fieldType, fieldChildrenType, secretKey);
|
|
232
|
-
lineNumbersArray[lineNumbersArray.indexOf(lineCount)] = 0;
|
|
233
|
-
if (!lineNumbersArray.filter((lineN) => lineN !== 0).length) break;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return [lines ?? null, lineCount];
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
export const replace = async (
|
|
241
|
-
filePath: string,
|
|
242
|
-
replacements:
|
|
243
|
-
| string
|
|
244
|
-
| number
|
|
245
|
-
| boolean
|
|
246
|
-
| null
|
|
247
|
-
| (string | number | boolean | null)[]
|
|
248
|
-
| Record<
|
|
249
|
-
number,
|
|
250
|
-
string | boolean | number | null | (string | boolean | number | null)[]
|
|
251
|
-
>,
|
|
252
|
-
secretKey?: string | Buffer
|
|
253
|
-
) => {
|
|
254
|
-
if (await isExists(filePath)) {
|
|
255
|
-
let rl: Interface, writeStream: WriteStream;
|
|
256
|
-
if (doesSupportReadLines()) {
|
|
257
|
-
const file = await open(filePath, "w+");
|
|
258
|
-
rl = file.readLines();
|
|
259
|
-
writeStream = file.createWriteStream();
|
|
260
|
-
} else {
|
|
261
|
-
rl = createInterface({
|
|
262
|
-
input: createReadStream(filePath),
|
|
263
|
-
crlfDelay: Infinity,
|
|
264
|
-
});
|
|
265
|
-
writeStream = createWriteStream(filePath);
|
|
266
|
-
}
|
|
267
|
-
if (typeof replacements === "object" && !Array.isArray(replacements)) {
|
|
268
|
-
let lineCount = 0;
|
|
269
|
-
for await (const line of rl) {
|
|
270
|
-
lineCount++;
|
|
271
|
-
writeStream.write(
|
|
272
|
-
(lineCount in replacements
|
|
273
|
-
? encode(replacements[lineCount], secretKey)
|
|
274
|
-
: line) + "\n"
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
} else
|
|
278
|
-
for await (const _line of rl)
|
|
279
|
-
writeStream.write(encode(replacements, secretKey) + "\n");
|
|
280
|
-
|
|
281
|
-
writeStream.end();
|
|
282
|
-
} else if (typeof replacements === "object" && !Array.isArray(replacements)) {
|
|
283
|
-
let writeStream: WriteStream;
|
|
284
|
-
if (doesSupportReadLines())
|
|
285
|
-
writeStream = (await open(filePath, "w")).createWriteStream();
|
|
286
|
-
else writeStream = createWriteStream(filePath);
|
|
287
|
-
const largestLinesNumbers =
|
|
288
|
-
Math.max(...Object.keys(replacements).map(Number)) + 1;
|
|
289
|
-
for (let lineCount = 1; lineCount < largestLinesNumbers; lineCount++) {
|
|
290
|
-
writeStream.write(
|
|
291
|
-
(lineCount in replacements
|
|
292
|
-
? encode(replacements[lineCount], secretKey)
|
|
293
|
-
: "") + "\n"
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
writeStream.end();
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
export const remove = async (
|
|
301
|
-
filePath: string,
|
|
302
|
-
linesToDelete: number | number[]
|
|
303
|
-
): Promise<void> => {
|
|
304
|
-
let lineCount = 0;
|
|
305
|
-
|
|
306
|
-
const tempFilePath = `${filePath}-${Date.now()}.tmp`,
|
|
307
|
-
linesToDeleteArray = [
|
|
308
|
-
...(Array.isArray(linesToDelete) ? linesToDelete : [linesToDelete]),
|
|
309
|
-
];
|
|
310
|
-
|
|
311
|
-
let rl: Interface, writeStream: WriteStream;
|
|
312
|
-
if (doesSupportReadLines()) {
|
|
313
|
-
rl = (await open(filePath)).readLines();
|
|
314
|
-
writeStream = (await open(tempFilePath, "w+")).createWriteStream();
|
|
315
|
-
} else {
|
|
316
|
-
rl = createInterface({
|
|
317
|
-
input: createReadStream(filePath),
|
|
318
|
-
crlfDelay: Infinity,
|
|
319
|
-
});
|
|
320
|
-
writeStream = createWriteStream(tempFilePath);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
for await (const line of rl) {
|
|
324
|
-
lineCount++;
|
|
325
|
-
if (!linesToDeleteArray.includes(lineCount)) {
|
|
326
|
-
writeStream.write(`${line}\n`);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
writeStream.end(async () => {
|
|
330
|
-
await unlink(filePath); // Remove the original file
|
|
331
|
-
await rename(tempFilePath, filePath); // Rename the temp file to the original file name
|
|
332
|
-
});
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
export const count = async (filePath: string): Promise<number> => {
|
|
336
|
-
let lineCount = 0,
|
|
337
|
-
rl: Interface;
|
|
338
|
-
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
339
|
-
else
|
|
340
|
-
rl = createInterface({
|
|
341
|
-
input: createReadStream(filePath),
|
|
342
|
-
crlfDelay: Infinity,
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
for await (const line of rl) lineCount++;
|
|
346
|
-
|
|
347
|
-
return lineCount;
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
export const search = async (
|
|
351
|
-
filePath: string,
|
|
352
|
-
operator: ComparisonOperator | ComparisonOperator[],
|
|
353
|
-
comparedAtValue:
|
|
354
|
-
| string
|
|
355
|
-
| number
|
|
356
|
-
| boolean
|
|
357
|
-
| null
|
|
358
|
-
| (string | number | boolean | null)[],
|
|
359
|
-
logicalOperator?: "and" | "or",
|
|
360
|
-
fieldType?: FieldType | FieldType[],
|
|
361
|
-
fieldChildrenType?: FieldType | FieldType[],
|
|
362
|
-
limit?: number,
|
|
363
|
-
offset?: number,
|
|
364
|
-
readWholeFile?: boolean,
|
|
365
|
-
secretKey?: string | Buffer
|
|
366
|
-
): Promise<
|
|
367
|
-
[
|
|
368
|
-
Record<
|
|
369
|
-
number,
|
|
370
|
-
Record<
|
|
371
|
-
string,
|
|
372
|
-
string | number | boolean | (string | number | boolean | null)[] | null
|
|
373
|
-
>
|
|
374
|
-
> | null,
|
|
375
|
-
number
|
|
376
|
-
]
|
|
377
|
-
> => {
|
|
378
|
-
const handleComparisonOperator = (
|
|
379
|
-
operator: ComparisonOperator,
|
|
380
|
-
originalValue:
|
|
381
|
-
| string
|
|
382
|
-
| number
|
|
383
|
-
| boolean
|
|
384
|
-
| null
|
|
385
|
-
| (string | number | boolean | null)[],
|
|
386
|
-
comparedAtValue:
|
|
387
|
-
| string
|
|
388
|
-
| number
|
|
389
|
-
| boolean
|
|
390
|
-
| null
|
|
391
|
-
| (string | number | boolean | null)[],
|
|
392
|
-
fieldType?: FieldType | FieldType[],
|
|
393
|
-
fieldChildrenType?: FieldType | FieldType[]
|
|
394
|
-
): boolean => {
|
|
395
|
-
if (Array.isArray(fieldType))
|
|
396
|
-
fieldType = detectFieldType(String(originalValue), fieldType);
|
|
397
|
-
if (Array.isArray(comparedAtValue) && !["[]", "![]"].includes(operator))
|
|
398
|
-
return comparedAtValue.some((comparedAtValueSingle) =>
|
|
399
|
-
handleComparisonOperator(
|
|
400
|
-
operator,
|
|
401
|
-
originalValue,
|
|
402
|
-
comparedAtValueSingle,
|
|
403
|
-
fieldType
|
|
404
|
-
)
|
|
405
|
-
);
|
|
406
|
-
// check if not array or object // it can't be array or object!
|
|
407
|
-
switch (operator) {
|
|
408
|
-
case "=":
|
|
409
|
-
switch (fieldType) {
|
|
410
|
-
case "password":
|
|
411
|
-
return typeof originalValue === "string" &&
|
|
412
|
-
typeof comparedAtValue === "string"
|
|
413
|
-
? comparePassword(originalValue, comparedAtValue)
|
|
414
|
-
: false;
|
|
415
|
-
case "boolean":
|
|
416
|
-
return Number(originalValue) - Number(comparedAtValue) === 0;
|
|
417
|
-
default:
|
|
418
|
-
return originalValue === comparedAtValue;
|
|
419
|
-
}
|
|
420
|
-
case "!=":
|
|
421
|
-
return !handleComparisonOperator(
|
|
422
|
-
"=",
|
|
423
|
-
originalValue,
|
|
424
|
-
comparedAtValue,
|
|
425
|
-
fieldType
|
|
426
|
-
);
|
|
427
|
-
case ">":
|
|
428
|
-
return originalValue > comparedAtValue;
|
|
429
|
-
case "<":
|
|
430
|
-
return originalValue < comparedAtValue;
|
|
431
|
-
case ">=":
|
|
432
|
-
return originalValue >= comparedAtValue;
|
|
433
|
-
case "<=":
|
|
434
|
-
return originalValue <= comparedAtValue;
|
|
435
|
-
case "[]":
|
|
436
|
-
return (
|
|
437
|
-
(Array.isArray(originalValue) &&
|
|
438
|
-
Array.isArray(comparedAtValue) &&
|
|
439
|
-
originalValue.some(comparedAtValue.includes)) ||
|
|
440
|
-
(Array.isArray(originalValue) &&
|
|
441
|
-
!Array.isArray(comparedAtValue) &&
|
|
442
|
-
originalValue.includes(comparedAtValue)) ||
|
|
443
|
-
(!Array.isArray(originalValue) &&
|
|
444
|
-
Array.isArray(comparedAtValue) &&
|
|
445
|
-
comparedAtValue.includes(originalValue))
|
|
446
|
-
);
|
|
447
|
-
case "![]":
|
|
448
|
-
return !handleComparisonOperator(
|
|
449
|
-
"[]",
|
|
450
|
-
originalValue,
|
|
451
|
-
comparedAtValue,
|
|
452
|
-
fieldType
|
|
453
|
-
);
|
|
454
|
-
case "*":
|
|
455
|
-
return new RegExp(
|
|
456
|
-
`^${(String(comparedAtValue).includes("%")
|
|
457
|
-
? String(comparedAtValue)
|
|
458
|
-
: "%" + String(comparedAtValue) + "%"
|
|
459
|
-
).replace(/%/g, ".*")}$`,
|
|
460
|
-
"i"
|
|
461
|
-
).test(String(originalValue));
|
|
462
|
-
case "!*":
|
|
463
|
-
return !handleComparisonOperator(
|
|
464
|
-
"*",
|
|
465
|
-
originalValue,
|
|
466
|
-
comparedAtValue,
|
|
467
|
-
fieldType
|
|
468
|
-
);
|
|
469
|
-
default:
|
|
470
|
-
throw new Error(operator);
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
|
|
474
|
-
let RETURN: Record<
|
|
475
|
-
number,
|
|
476
|
-
Record<
|
|
477
|
-
string,
|
|
478
|
-
string | number | boolean | null | (string | number | boolean | null)[]
|
|
479
|
-
>
|
|
480
|
-
> = {},
|
|
481
|
-
lineCount = 0,
|
|
482
|
-
foundItems = 0;
|
|
483
|
-
let rl: Interface;
|
|
484
|
-
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
485
|
-
else
|
|
486
|
-
rl = createInterface({
|
|
487
|
-
input: createReadStream(filePath),
|
|
488
|
-
crlfDelay: Infinity,
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
const columnName = parse(filePath).name;
|
|
492
|
-
|
|
493
|
-
for await (const line of rl) {
|
|
494
|
-
lineCount++;
|
|
495
|
-
const decodedLine = decode(line, fieldType, fieldChildrenType, secretKey);
|
|
496
|
-
if (
|
|
497
|
-
(Array.isArray(operator) &&
|
|
498
|
-
Array.isArray(comparedAtValue) &&
|
|
499
|
-
((logicalOperator &&
|
|
500
|
-
logicalOperator === "or" &&
|
|
501
|
-
operator.some((single_operator, index) =>
|
|
502
|
-
handleComparisonOperator(
|
|
503
|
-
single_operator,
|
|
504
|
-
decodedLine,
|
|
505
|
-
comparedAtValue[index],
|
|
506
|
-
fieldType
|
|
507
|
-
)
|
|
508
|
-
)) ||
|
|
509
|
-
operator.every((single_operator, index) =>
|
|
510
|
-
handleComparisonOperator(
|
|
511
|
-
single_operator,
|
|
512
|
-
decodedLine,
|
|
513
|
-
comparedAtValue[index],
|
|
514
|
-
fieldType
|
|
515
|
-
)
|
|
516
|
-
))) ||
|
|
517
|
-
(!Array.isArray(operator) &&
|
|
518
|
-
handleComparisonOperator(
|
|
519
|
-
operator,
|
|
520
|
-
decodedLine,
|
|
521
|
-
comparedAtValue,
|
|
522
|
-
fieldType
|
|
523
|
-
))
|
|
524
|
-
) {
|
|
525
|
-
foundItems++;
|
|
526
|
-
if (offset && foundItems < offset) continue;
|
|
527
|
-
if (limit && foundItems > limit)
|
|
528
|
-
if (readWholeFile) continue;
|
|
529
|
-
else break;
|
|
530
|
-
if (!RETURN[lineCount]) RETURN[lineCount] = {};
|
|
531
|
-
RETURN[lineCount][columnName] = decodedLine;
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
if (foundItems) {
|
|
535
|
-
return [RETURN, readWholeFile ? foundItems : foundItems - 1];
|
|
536
|
-
} else return [null, 0];
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
export const sum = async (
|
|
540
|
-
filePath: string,
|
|
541
|
-
lineNumbers?: number | number[]
|
|
542
|
-
): Promise<number> => {
|
|
543
|
-
let rl: Interface;
|
|
544
|
-
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
545
|
-
else
|
|
546
|
-
rl = createInterface({
|
|
547
|
-
input: createReadStream(filePath),
|
|
548
|
-
crlfDelay: Infinity,
|
|
549
|
-
});
|
|
550
|
-
let sum = 0;
|
|
551
|
-
|
|
552
|
-
if (lineNumbers) {
|
|
553
|
-
let lineCount = 0;
|
|
554
|
-
|
|
555
|
-
let lineNumbersArray = [
|
|
556
|
-
...(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]),
|
|
557
|
-
];
|
|
558
|
-
for await (const line of rl) {
|
|
559
|
-
lineCount++;
|
|
560
|
-
if (!lineNumbersArray.includes(lineCount)) continue;
|
|
561
|
-
sum += +decode(line, "number");
|
|
562
|
-
lineNumbersArray[lineNumbersArray.indexOf(lineCount)] = 0;
|
|
563
|
-
if (!lineNumbersArray.filter((lineN) => lineN !== 0).length) break;
|
|
564
|
-
}
|
|
565
|
-
} else for await (const line of rl) sum += +decode(line, "number");
|
|
566
|
-
|
|
567
|
-
return sum;
|
|
568
|
-
};
|
|
569
|
-
|
|
570
|
-
export const max = async (
|
|
571
|
-
filePath: string,
|
|
572
|
-
lineNumbers?: number | number[]
|
|
573
|
-
): Promise<number> => {
|
|
574
|
-
let rl: Interface;
|
|
575
|
-
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
576
|
-
else
|
|
577
|
-
rl = createInterface({
|
|
578
|
-
input: createReadStream(filePath),
|
|
579
|
-
crlfDelay: Infinity,
|
|
580
|
-
});
|
|
581
|
-
let max = 0;
|
|
582
|
-
|
|
583
|
-
if (lineNumbers) {
|
|
584
|
-
let lineCount = 0;
|
|
585
|
-
|
|
586
|
-
let lineNumbersArray = [
|
|
587
|
-
...(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]),
|
|
588
|
-
];
|
|
589
|
-
for await (const line of rl) {
|
|
590
|
-
lineCount++;
|
|
591
|
-
if (!lineNumbersArray.includes(lineCount)) continue;
|
|
592
|
-
const lineContentNum = +decode(line, "number");
|
|
593
|
-
if (lineContentNum > max) max = lineContentNum;
|
|
594
|
-
lineNumbersArray[lineNumbersArray.indexOf(lineCount)] = 0;
|
|
595
|
-
if (!lineNumbersArray.filter((lineN) => lineN !== 0).length) break;
|
|
596
|
-
}
|
|
597
|
-
} else
|
|
598
|
-
for await (const line of rl) {
|
|
599
|
-
const lineContentNum = +decode(line, "number");
|
|
600
|
-
if (lineContentNum > max) max = lineContentNum;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
return max;
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
export const min = async (
|
|
607
|
-
filePath: string,
|
|
608
|
-
lineNumbers?: number | number[]
|
|
609
|
-
): Promise<number> => {
|
|
610
|
-
let rl: Interface;
|
|
611
|
-
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
612
|
-
else
|
|
613
|
-
rl = createInterface({
|
|
614
|
-
input: createReadStream(filePath),
|
|
615
|
-
crlfDelay: Infinity,
|
|
616
|
-
});
|
|
617
|
-
let min = 0;
|
|
618
|
-
|
|
619
|
-
if (lineNumbers) {
|
|
620
|
-
let lineCount = 0;
|
|
621
|
-
|
|
622
|
-
let lineNumbersArray = [
|
|
623
|
-
...(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]),
|
|
624
|
-
];
|
|
625
|
-
for await (const line of rl) {
|
|
626
|
-
lineCount++;
|
|
627
|
-
if (!lineNumbersArray.includes(lineCount)) continue;
|
|
628
|
-
const lineContentNum = +decode(line, "number");
|
|
629
|
-
if (lineContentNum < min) min = lineContentNum;
|
|
630
|
-
lineNumbersArray[lineNumbersArray.indexOf(lineCount)] = 0;
|
|
631
|
-
if (!lineNumbersArray.filter((lineN) => lineN !== 0).length) break;
|
|
632
|
-
}
|
|
633
|
-
} else
|
|
634
|
-
for await (const line of rl) {
|
|
635
|
-
const lineContentNum = +decode(line, "number");
|
|
636
|
-
if (lineContentNum < min) min = lineContentNum;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
return min;
|
|
640
|
-
};
|
|
641
|
-
|
|
642
|
-
export const sort = async (
|
|
643
|
-
filePath: string,
|
|
644
|
-
sortDirection: 1 | -1 | "asc" | "desc",
|
|
645
|
-
lineNumbers?: number | number[],
|
|
646
|
-
_lineNumbersPerChunk: number = 100000
|
|
647
|
-
): Promise<void> => {
|
|
648
|
-
let rl: Interface;
|
|
649
|
-
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
650
|
-
else
|
|
651
|
-
rl = createInterface({
|
|
652
|
-
input: createReadStream(filePath),
|
|
653
|
-
crlfDelay: Infinity,
|
|
654
|
-
});
|
|
655
|
-
let lineCount = 0;
|
|
656
|
-
|
|
657
|
-
for await (const line of rl) {
|
|
658
|
-
lineCount++;
|
|
659
|
-
}
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
export default class File {
|
|
663
|
-
static get = get;
|
|
664
|
-
static remove = remove;
|
|
665
|
-
static search = search;
|
|
666
|
-
static replace = replace;
|
|
667
|
-
static count = count;
|
|
668
|
-
static encode = encode;
|
|
669
|
-
static decode = decode;
|
|
670
|
-
static isExists = isExists;
|
|
671
|
-
static sum = sum;
|
|
672
|
-
static min = min;
|
|
673
|
-
static max = max;
|
|
674
|
-
}
|