inibase 1.0.0-rc.0 → 1.0.0-rc.10
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/README.md +45 -62
- package/file.ts +282 -103
- package/index.test.ts +206 -0
- package/index.ts +876 -626
- package/package.json +7 -6
- package/tsconfig.json +2 -1
- package/utils.server.ts +79 -0
- package/utils.ts +166 -64
package/file.ts
CHANGED
|
@@ -1,26 +1,152 @@
|
|
|
1
|
-
import { createWriteStream,
|
|
2
|
-
import { open } from "fs/promises";
|
|
3
|
-
import {
|
|
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";
|
|
4
5
|
import { ComparisonOperator, FieldType } from ".";
|
|
5
|
-
import
|
|
6
|
+
import { detectFieldType, isArrayOfArrays, isNumber } from "./utils";
|
|
7
|
+
import { encodeID, comparePassword } from "./utils.server";
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const doesSupportReadLines = () => {
|
|
10
|
+
const [major, minor, patch] = process.versions.node.split(".").map(Number);
|
|
11
|
+
return major >= 18 && minor >= 11;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const isExists = async (path: string) => {
|
|
15
|
+
try {
|
|
16
|
+
await stat(path);
|
|
17
|
+
return true;
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
12
21
|
};
|
|
13
22
|
|
|
14
|
-
export const
|
|
15
|
-
|
|
23
|
+
export const encode = (
|
|
24
|
+
input:
|
|
25
|
+
| string
|
|
26
|
+
| number
|
|
27
|
+
| boolean
|
|
28
|
+
| null
|
|
29
|
+
| (string | number | boolean | null)[],
|
|
30
|
+
secretKey?: string | Buffer
|
|
31
|
+
) => {
|
|
32
|
+
const secureString = (input: string | number | boolean | null) => {
|
|
33
|
+
if (["true", "false"].includes(String(input))) return input ? 1 : 0;
|
|
34
|
+
return typeof input === "string"
|
|
35
|
+
? decodeURIComponent(input)
|
|
36
|
+
.replaceAll("<", "<")
|
|
37
|
+
.replaceAll(">", ">")
|
|
38
|
+
.replaceAll(",", "%2C")
|
|
39
|
+
.replaceAll("|", "%7C")
|
|
40
|
+
.replaceAll("\n", "\\n")
|
|
41
|
+
.replaceAll("\r", "\\r")
|
|
42
|
+
: input;
|
|
43
|
+
};
|
|
44
|
+
return Array.isArray(input)
|
|
45
|
+
? isArrayOfArrays(input)
|
|
46
|
+
? (input as any[])
|
|
47
|
+
.map((_input) => _input.map(secureString).join(","))
|
|
48
|
+
.join("|")
|
|
49
|
+
: input.map(secureString).join(",")
|
|
50
|
+
: secureString(input);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const decode = (
|
|
54
|
+
input: string | null | number,
|
|
55
|
+
fieldType?: FieldType | FieldType[],
|
|
56
|
+
fieldChildrenType?: FieldType | FieldType[],
|
|
57
|
+
secretKey?: string | Buffer
|
|
58
|
+
): string | number | boolean | null | (string | number | null | boolean)[] => {
|
|
59
|
+
if (!fieldType) return null;
|
|
60
|
+
const unSecureString = (input: string) =>
|
|
61
|
+
decodeURIComponent(input)
|
|
62
|
+
.replaceAll("<", "<")
|
|
63
|
+
.replaceAll(">", ">")
|
|
64
|
+
.replaceAll("%2C", ",")
|
|
65
|
+
.replaceAll("%7C", "|")
|
|
66
|
+
.replaceAll("\\n", "\n")
|
|
67
|
+
.replaceAll("\\r", "\r") || null;
|
|
68
|
+
if (input === null || input === "") return null;
|
|
69
|
+
if (Array.isArray(fieldType))
|
|
70
|
+
fieldType = detectFieldType(String(input), fieldType);
|
|
71
|
+
const decodeHelper = (value: string | number | any[]) => {
|
|
72
|
+
if (Array.isArray(value) && fieldType !== "array")
|
|
73
|
+
return value.map(decodeHelper);
|
|
74
|
+
switch (fieldType as FieldType) {
|
|
75
|
+
case "table":
|
|
76
|
+
case "number":
|
|
77
|
+
return isNumber(value) ? Number(value) : null;
|
|
78
|
+
case "boolean":
|
|
79
|
+
return typeof value === "string" ? value === "true" : Boolean(value);
|
|
80
|
+
case "array":
|
|
81
|
+
if (!Array.isArray(value)) return [value];
|
|
82
|
+
|
|
83
|
+
if (fieldChildrenType)
|
|
84
|
+
return value.map(
|
|
85
|
+
(v) =>
|
|
86
|
+
decode(
|
|
87
|
+
v,
|
|
88
|
+
Array.isArray(fieldChildrenType)
|
|
89
|
+
? detectFieldType(v, fieldChildrenType)
|
|
90
|
+
: fieldChildrenType,
|
|
91
|
+
undefined,
|
|
92
|
+
secretKey
|
|
93
|
+
) as string | number | boolean | null
|
|
94
|
+
);
|
|
95
|
+
else return value;
|
|
96
|
+
case "id":
|
|
97
|
+
return isNumber(value) ? encodeID(value as number, secretKey) : value;
|
|
98
|
+
default:
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
return decodeHelper(
|
|
103
|
+
typeof input === "string"
|
|
104
|
+
? input.includes(",")
|
|
105
|
+
? input.includes("|")
|
|
106
|
+
? input
|
|
107
|
+
.split("|")
|
|
108
|
+
.map((_input) => _input.split(",").map(unSecureString))
|
|
109
|
+
: input.split(",").map(unSecureString)
|
|
110
|
+
: input.includes("|")
|
|
111
|
+
? input
|
|
112
|
+
.split("|")
|
|
113
|
+
.map((_input) => [
|
|
114
|
+
_input
|
|
115
|
+
? fieldType === "array"
|
|
116
|
+
? [unSecureString(_input)]
|
|
117
|
+
: unSecureString(_input)
|
|
118
|
+
: null,
|
|
119
|
+
])
|
|
120
|
+
: unSecureString(input)
|
|
121
|
+
: input
|
|
122
|
+
);
|
|
16
123
|
};
|
|
17
124
|
|
|
18
125
|
export const get = async (
|
|
19
126
|
filePath: string,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
127
|
+
lineNumbers?: number | number[],
|
|
128
|
+
fieldType?: FieldType | FieldType[],
|
|
129
|
+
fieldChildrenType?: FieldType | FieldType[],
|
|
130
|
+
secretKey?: string | Buffer
|
|
131
|
+
): Promise<
|
|
132
|
+
[
|
|
133
|
+
Record<
|
|
134
|
+
number,
|
|
135
|
+
| string
|
|
136
|
+
| number
|
|
137
|
+
| boolean
|
|
138
|
+
| (string | number | boolean | (string | number | boolean)[])[]
|
|
139
|
+
> | null,
|
|
140
|
+
number
|
|
141
|
+
]
|
|
142
|
+
> => {
|
|
143
|
+
let rl: Interface;
|
|
144
|
+
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
145
|
+
else
|
|
146
|
+
rl = createInterface({
|
|
147
|
+
input: createReadStream(filePath),
|
|
148
|
+
crlfDelay: Infinity,
|
|
149
|
+
});
|
|
24
150
|
let lines: Record<
|
|
25
151
|
number,
|
|
26
152
|
| string
|
|
@@ -32,27 +158,36 @@ export const get = async (
|
|
|
32
158
|
lineCount = 0;
|
|
33
159
|
|
|
34
160
|
if (!lineNumbers) {
|
|
35
|
-
for await (const line of
|
|
36
|
-
lineCount++,
|
|
161
|
+
for await (const line of rl)
|
|
162
|
+
lineCount++,
|
|
163
|
+
(lines[lineCount] = decode(
|
|
164
|
+
line,
|
|
165
|
+
fieldType,
|
|
166
|
+
fieldChildrenType,
|
|
167
|
+
secretKey
|
|
168
|
+
));
|
|
37
169
|
} else if (lineNumbers === -1) {
|
|
38
|
-
let lastLine;
|
|
39
|
-
for await (const line of
|
|
40
|
-
if (lastLine)
|
|
170
|
+
let lastLine: string;
|
|
171
|
+
for await (const line of rl) lineCount++, (lastLine = line);
|
|
172
|
+
if (lastLine)
|
|
173
|
+
lines = {
|
|
174
|
+
[lineCount]: decode(lastLine, fieldType, fieldChildrenType, secretKey),
|
|
175
|
+
};
|
|
41
176
|
} else {
|
|
42
177
|
let lineNumbersArray = [
|
|
43
178
|
...(Array.isArray(lineNumbers) ? lineNumbers : [lineNumbers]),
|
|
44
179
|
];
|
|
45
|
-
for await (const line of
|
|
180
|
+
for await (const line of rl) {
|
|
46
181
|
lineCount++;
|
|
47
182
|
if (!lineNumbersArray.includes(lineCount)) continue;
|
|
48
183
|
const indexOfLineCount = lineNumbersArray.indexOf(lineCount);
|
|
49
|
-
lines[lineCount] =
|
|
184
|
+
lines[lineCount] = decode(line, fieldType, fieldChildrenType, secretKey);
|
|
50
185
|
lineNumbersArray[indexOfLineCount] = 0;
|
|
51
186
|
if (!lineNumbersArray.filter((lineN) => lineN !== 0).length) break;
|
|
52
187
|
}
|
|
53
188
|
}
|
|
54
189
|
|
|
55
|
-
return lines ?? null;
|
|
190
|
+
return [lines ?? null, lineCount];
|
|
56
191
|
};
|
|
57
192
|
|
|
58
193
|
export const replace = async (
|
|
@@ -66,35 +201,48 @@ export const replace = async (
|
|
|
66
201
|
| Record<
|
|
67
202
|
number,
|
|
68
203
|
string | boolean | number | null | (string | boolean | number | null)[]
|
|
69
|
-
|
|
204
|
+
>,
|
|
205
|
+
secretKey?: string | Buffer
|
|
70
206
|
) => {
|
|
71
|
-
if (
|
|
72
|
-
|
|
207
|
+
if (await isExists(filePath)) {
|
|
208
|
+
let rl: Interface, writeStream: WriteStream;
|
|
209
|
+
if (doesSupportReadLines()) {
|
|
210
|
+
const file = await open(filePath, "w+");
|
|
211
|
+
rl = file.readLines();
|
|
73
212
|
writeStream = file.createWriteStream();
|
|
213
|
+
} else {
|
|
214
|
+
rl = createInterface({
|
|
215
|
+
input: createReadStream(filePath),
|
|
216
|
+
crlfDelay: Infinity,
|
|
217
|
+
});
|
|
218
|
+
writeStream = createWriteStream(filePath);
|
|
219
|
+
}
|
|
74
220
|
if (typeof replacements === "object" && !Array.isArray(replacements)) {
|
|
75
221
|
let lineCount = 0;
|
|
76
|
-
for await (const line of
|
|
222
|
+
for await (const line of rl) {
|
|
77
223
|
lineCount++;
|
|
78
224
|
writeStream.write(
|
|
79
225
|
(lineCount in replacements
|
|
80
|
-
?
|
|
226
|
+
? encode(replacements[lineCount], secretKey)
|
|
81
227
|
: line) + "\n"
|
|
82
228
|
);
|
|
83
229
|
}
|
|
84
230
|
} else
|
|
85
|
-
for await (const _line of
|
|
86
|
-
writeStream.write(
|
|
231
|
+
for await (const _line of rl)
|
|
232
|
+
writeStream.write(encode(replacements, secretKey) + "\n");
|
|
87
233
|
|
|
88
234
|
writeStream.end();
|
|
89
235
|
} else if (typeof replacements === "object" && !Array.isArray(replacements)) {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
236
|
+
let writeStream: WriteStream;
|
|
237
|
+
if (doesSupportReadLines())
|
|
238
|
+
writeStream = (await open(filePath, "w")).createWriteStream();
|
|
239
|
+
else writeStream = createWriteStream(filePath);
|
|
240
|
+
const largestLinesNumbers =
|
|
241
|
+
Math.max(...Object.keys(replacements).map(Number)) + 1;
|
|
94
242
|
for (let lineCount = 1; lineCount < largestLinesNumbers; lineCount++) {
|
|
95
243
|
writeStream.write(
|
|
96
244
|
(lineCount in replacements
|
|
97
|
-
?
|
|
245
|
+
? encode(replacements[lineCount], secretKey)
|
|
98
246
|
: "") + "\n"
|
|
99
247
|
);
|
|
100
248
|
}
|
|
@@ -108,39 +256,52 @@ export const remove = async (
|
|
|
108
256
|
): Promise<void> => {
|
|
109
257
|
let lineCount = 0;
|
|
110
258
|
|
|
111
|
-
const tempFilePath = `${filePath}.tmp`,
|
|
259
|
+
const tempFilePath = `${filePath}-${Date.now()}.tmp`,
|
|
112
260
|
linesToDeleteArray = [
|
|
113
261
|
...(Array.isArray(linesToDelete) ? linesToDelete : [linesToDelete]),
|
|
114
|
-
]
|
|
115
|
-
|
|
116
|
-
|
|
262
|
+
];
|
|
263
|
+
|
|
264
|
+
let rl: Interface, writeStream: WriteStream;
|
|
265
|
+
if (doesSupportReadLines()) {
|
|
266
|
+
rl = (await open(filePath)).readLines();
|
|
267
|
+
writeStream = (await open(tempFilePath, "w+")).createWriteStream();
|
|
268
|
+
} else {
|
|
269
|
+
rl = createInterface({
|
|
270
|
+
input: createReadStream(filePath),
|
|
271
|
+
crlfDelay: Infinity,
|
|
272
|
+
});
|
|
273
|
+
writeStream = createWriteStream(tempFilePath);
|
|
274
|
+
}
|
|
117
275
|
|
|
118
|
-
for await (const line of
|
|
276
|
+
for await (const line of rl) {
|
|
119
277
|
lineCount++;
|
|
120
278
|
if (!linesToDeleteArray.includes(lineCount)) {
|
|
121
279
|
writeStream.write(`${line}\n`);
|
|
122
280
|
}
|
|
123
281
|
}
|
|
124
|
-
writeStream.end()
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
renameSync(tempFilePath, filePath); // Rename the temp file to the original file name
|
|
282
|
+
writeStream.end(async () => {
|
|
283
|
+
await unlink(filePath); // Remove the original file
|
|
284
|
+
await rename(tempFilePath, filePath); // Rename the temp file to the original file name
|
|
128
285
|
});
|
|
129
286
|
};
|
|
130
287
|
|
|
131
288
|
export const count = async (filePath: string): Promise<number> => {
|
|
132
|
-
let lineCount = 0
|
|
133
|
-
|
|
134
|
-
|
|
289
|
+
let lineCount = 0,
|
|
290
|
+
rl: Interface;
|
|
291
|
+
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
292
|
+
else
|
|
293
|
+
rl = createInterface({
|
|
294
|
+
input: createReadStream(filePath),
|
|
295
|
+
crlfDelay: Infinity,
|
|
296
|
+
});
|
|
135
297
|
|
|
136
|
-
for await (const line of
|
|
298
|
+
for await (const line of rl) lineCount++;
|
|
137
299
|
|
|
138
300
|
return lineCount;
|
|
139
301
|
};
|
|
140
302
|
|
|
141
303
|
export const search = async (
|
|
142
304
|
filePath: string,
|
|
143
|
-
fieldType: FieldType,
|
|
144
305
|
operator: ComparisonOperator | ComparisonOperator[],
|
|
145
306
|
comparedAtValue:
|
|
146
307
|
| string
|
|
@@ -149,9 +310,12 @@ export const search = async (
|
|
|
149
310
|
| null
|
|
150
311
|
| (string | number | boolean | null)[],
|
|
151
312
|
logicalOperator?: "and" | "or",
|
|
313
|
+
fieldType?: FieldType | FieldType[],
|
|
314
|
+
fieldChildrenType?: FieldType | FieldType[],
|
|
152
315
|
limit?: number,
|
|
153
316
|
offset?: number,
|
|
154
|
-
readWholeFile?: boolean
|
|
317
|
+
readWholeFile?: boolean,
|
|
318
|
+
secretKey?: string | Buffer
|
|
155
319
|
): Promise<
|
|
156
320
|
[
|
|
157
321
|
Record<
|
|
@@ -166,7 +330,7 @@ export const search = async (
|
|
|
166
330
|
> => {
|
|
167
331
|
const handleComparisonOperator = (
|
|
168
332
|
operator: ComparisonOperator,
|
|
169
|
-
|
|
333
|
+
originalValue:
|
|
170
334
|
| string
|
|
171
335
|
| number
|
|
172
336
|
| boolean
|
|
@@ -178,71 +342,80 @@ export const search = async (
|
|
|
178
342
|
| boolean
|
|
179
343
|
| null
|
|
180
344
|
| (string | number | boolean | null)[],
|
|
181
|
-
fieldType
|
|
345
|
+
fieldType?: FieldType | FieldType[],
|
|
346
|
+
fieldChildrenType?: FieldType | FieldType[]
|
|
182
347
|
): boolean => {
|
|
183
|
-
|
|
348
|
+
if (Array.isArray(fieldType))
|
|
349
|
+
fieldType = detectFieldType(String(originalValue), fieldType);
|
|
350
|
+
if (Array.isArray(comparedAtValue) && !["[]", "![]"].includes(operator))
|
|
351
|
+
return comparedAtValue.some((comparedAtValueSingle) =>
|
|
352
|
+
handleComparisonOperator(
|
|
353
|
+
operator,
|
|
354
|
+
originalValue,
|
|
355
|
+
comparedAtValueSingle,
|
|
356
|
+
fieldType
|
|
357
|
+
)
|
|
358
|
+
);
|
|
359
|
+
// check if not array or object // it can't be array or object!
|
|
184
360
|
switch (operator) {
|
|
185
361
|
case "=":
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
362
|
+
switch (fieldType) {
|
|
363
|
+
case "password":
|
|
364
|
+
return typeof originalValue === "string" &&
|
|
365
|
+
typeof comparedAtValue === "string"
|
|
366
|
+
? comparePassword(originalValue, comparedAtValue)
|
|
367
|
+
: false;
|
|
368
|
+
case "boolean":
|
|
369
|
+
return Number(originalValue) - Number(comparedAtValue) === 0;
|
|
370
|
+
default:
|
|
371
|
+
return originalValue === comparedAtValue;
|
|
372
|
+
}
|
|
191
373
|
case "!=":
|
|
192
374
|
return !handleComparisonOperator(
|
|
193
375
|
"=",
|
|
194
|
-
|
|
376
|
+
originalValue,
|
|
195
377
|
comparedAtValue,
|
|
196
378
|
fieldType
|
|
197
379
|
);
|
|
198
380
|
case ">":
|
|
199
|
-
return
|
|
200
|
-
value !== null && comparedAtValue !== null && value > comparedAtValue
|
|
201
|
-
);
|
|
381
|
+
return originalValue > comparedAtValue;
|
|
202
382
|
case "<":
|
|
203
|
-
return
|
|
204
|
-
value !== null && comparedAtValue !== null && value < comparedAtValue
|
|
205
|
-
);
|
|
383
|
+
return originalValue < comparedAtValue;
|
|
206
384
|
case ">=":
|
|
207
|
-
return
|
|
208
|
-
value !== null && comparedAtValue !== null && value >= comparedAtValue
|
|
209
|
-
);
|
|
385
|
+
return originalValue >= comparedAtValue;
|
|
210
386
|
case "<=":
|
|
211
|
-
return
|
|
212
|
-
value !== null && comparedAtValue !== null && value <= comparedAtValue
|
|
213
|
-
);
|
|
387
|
+
return originalValue <= comparedAtValue;
|
|
214
388
|
case "[]":
|
|
215
389
|
return (
|
|
216
|
-
(Array.isArray(
|
|
390
|
+
(Array.isArray(originalValue) &&
|
|
217
391
|
Array.isArray(comparedAtValue) &&
|
|
218
|
-
|
|
219
|
-
(Array.isArray(
|
|
392
|
+
originalValue.some(comparedAtValue.includes)) ||
|
|
393
|
+
(Array.isArray(originalValue) &&
|
|
220
394
|
!Array.isArray(comparedAtValue) &&
|
|
221
|
-
|
|
222
|
-
(!Array.isArray(
|
|
395
|
+
originalValue.includes(comparedAtValue)) ||
|
|
396
|
+
(!Array.isArray(originalValue) &&
|
|
223
397
|
Array.isArray(comparedAtValue) &&
|
|
224
|
-
comparedAtValue.includes(
|
|
398
|
+
comparedAtValue.includes(originalValue))
|
|
225
399
|
);
|
|
226
400
|
case "![]":
|
|
227
401
|
return !handleComparisonOperator(
|
|
228
402
|
"[]",
|
|
229
|
-
|
|
403
|
+
originalValue,
|
|
230
404
|
comparedAtValue,
|
|
231
405
|
fieldType
|
|
232
406
|
);
|
|
233
407
|
case "*":
|
|
234
|
-
return (
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
);
|
|
408
|
+
return new RegExp(
|
|
409
|
+
`^${(String(comparedAtValue).includes("%")
|
|
410
|
+
? String(comparedAtValue)
|
|
411
|
+
: "%" + String(comparedAtValue) + "%"
|
|
412
|
+
).replace(/%/g, ".*")}$`,
|
|
413
|
+
"i"
|
|
414
|
+
).test(String(originalValue));
|
|
242
415
|
case "!*":
|
|
243
416
|
return !handleComparisonOperator(
|
|
244
417
|
"*",
|
|
245
|
-
|
|
418
|
+
originalValue,
|
|
246
419
|
comparedAtValue,
|
|
247
420
|
fieldType
|
|
248
421
|
);
|
|
@@ -260,16 +433,21 @@ export const search = async (
|
|
|
260
433
|
> = {},
|
|
261
434
|
lineCount = 0,
|
|
262
435
|
foundItems = 0;
|
|
436
|
+
let rl: Interface;
|
|
437
|
+
if (doesSupportReadLines()) rl = (await open(filePath)).readLines();
|
|
438
|
+
else
|
|
439
|
+
rl = createInterface({
|
|
440
|
+
input: createReadStream(filePath),
|
|
441
|
+
crlfDelay: Infinity,
|
|
442
|
+
});
|
|
263
443
|
|
|
264
|
-
const
|
|
265
|
-
columnName = decodeFileName(parse(filePath).name);
|
|
444
|
+
const columnName = parse(filePath).name;
|
|
266
445
|
|
|
267
|
-
for await (const line of
|
|
446
|
+
for await (const line of rl) {
|
|
268
447
|
lineCount++;
|
|
269
|
-
const decodedLine =
|
|
448
|
+
const decodedLine = decode(line, fieldType, fieldChildrenType, secretKey);
|
|
270
449
|
if (
|
|
271
|
-
|
|
272
|
-
((Array.isArray(operator) &&
|
|
450
|
+
(Array.isArray(operator) &&
|
|
273
451
|
Array.isArray(comparedAtValue) &&
|
|
274
452
|
((logicalOperator &&
|
|
275
453
|
logicalOperator === "or" &&
|
|
@@ -289,13 +467,13 @@ export const search = async (
|
|
|
289
467
|
fieldType
|
|
290
468
|
)
|
|
291
469
|
))) ||
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
470
|
+
(!Array.isArray(operator) &&
|
|
471
|
+
handleComparisonOperator(
|
|
472
|
+
operator,
|
|
473
|
+
decodedLine,
|
|
474
|
+
comparedAtValue,
|
|
475
|
+
fieldType
|
|
476
|
+
))
|
|
299
477
|
) {
|
|
300
478
|
foundItems++;
|
|
301
479
|
if (offset && foundItems < offset) continue;
|
|
@@ -313,10 +491,11 @@ export const search = async (
|
|
|
313
491
|
|
|
314
492
|
export default class File {
|
|
315
493
|
static get = get;
|
|
316
|
-
static count = count;
|
|
317
494
|
static remove = remove;
|
|
318
495
|
static search = search;
|
|
319
496
|
static replace = replace;
|
|
320
|
-
static
|
|
321
|
-
static
|
|
497
|
+
static count = count;
|
|
498
|
+
static encode = encode;
|
|
499
|
+
static decode = decode;
|
|
500
|
+
static isExists = isExists;
|
|
322
501
|
}
|