inibase 1.0.0-rc.17 → 1.0.0-rc.18
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.js +29 -28
- package/dist/index.d.ts +8 -4
- package/dist/index.js +18 -14
- package/dist/utils.js +3 -2
- package/package.json +1 -1
package/dist/file.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { open, stat, writeFile } from "node:fs/promises";
|
|
1
|
+
import { open, rename, stat, writeFile } from "node:fs/promises";
|
|
2
2
|
import { createInterface } from "node:readline";
|
|
3
3
|
import { detectFieldType, isArrayOfArrays, isNumber } from "./utils.js";
|
|
4
4
|
import { encodeID, comparePassword } from "./utils.server.js";
|
|
@@ -119,9 +119,9 @@ export const decode = (input, fieldType, fieldChildrenType, secretKey) => {
|
|
|
119
119
|
};
|
|
120
120
|
export const get = async (filePath, lineNumbers, fieldType, fieldChildrenType, secretKey) => {
|
|
121
121
|
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
122
|
-
? fileHandle.readLines()
|
|
122
|
+
? fileHandle.readLines({ autoClose: false })
|
|
123
123
|
: createInterface({
|
|
124
|
-
input: fileHandle.createReadStream(),
|
|
124
|
+
input: fileHandle.createReadStream({ autoClose: false }),
|
|
125
125
|
crlfDelay: Infinity,
|
|
126
126
|
});
|
|
127
127
|
let lines = new Map(), lineCount = 0;
|
|
@@ -154,12 +154,12 @@ export const get = async (filePath, lineNumbers, fieldType, fieldChildrenType, s
|
|
|
154
154
|
};
|
|
155
155
|
export const replace = async (filePath, replacements) => {
|
|
156
156
|
if (await isExists(filePath)) {
|
|
157
|
-
const fileHandle = await open(filePath, "r
|
|
157
|
+
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
158
158
|
? fileHandle.readLines({ autoClose: false })
|
|
159
159
|
: createInterface({
|
|
160
160
|
input: fileHandle.createReadStream({ autoClose: false }),
|
|
161
161
|
crlfDelay: Infinity,
|
|
162
|
-
}), writeStream =
|
|
162
|
+
}), fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`, fileTempHandle = await open(fileTempPath, "w+"), writeStream = fileTempHandle.createWriteStream({ autoClose: false });
|
|
163
163
|
if (typeof replacements === "object" && !Array.isArray(replacements)) {
|
|
164
164
|
if (!(replacements instanceof Map))
|
|
165
165
|
replacements = new Map(Object.entries(replacements));
|
|
@@ -181,7 +181,10 @@ export const replace = async (filePath, replacements) => {
|
|
|
181
181
|
else
|
|
182
182
|
for await (const _line of rl)
|
|
183
183
|
writeStream.write(replacements + "\n");
|
|
184
|
-
writeStream.end(async () => await
|
|
184
|
+
// writeStream.end(async () => await rename(fileTempPath, filePath));
|
|
185
|
+
await fileHandle.close();
|
|
186
|
+
await fileTempHandle.close();
|
|
187
|
+
await rename(fileTempPath, filePath);
|
|
185
188
|
}
|
|
186
189
|
else if (typeof replacements === "object" && !Array.isArray(replacements)) {
|
|
187
190
|
if (!(replacements instanceof Map))
|
|
@@ -195,7 +198,7 @@ export const replace = async (filePath, replacements) => {
|
|
|
195
198
|
};
|
|
196
199
|
export const append = async (filePath, data, startsAt = 1) => {
|
|
197
200
|
const doesFileExists = await isExists(filePath);
|
|
198
|
-
const fileHandle = await open(filePath, "a"), writeStream = fileHandle.createWriteStream();
|
|
201
|
+
const fileHandle = await open(filePath, "a"), writeStream = fileHandle.createWriteStream({ autoClose: false });
|
|
199
202
|
if (doesFileExists) {
|
|
200
203
|
const currentNumberOfLines = await count(filePath);
|
|
201
204
|
if (startsAt - currentNumberOfLines - 1 > 0)
|
|
@@ -221,25 +224,28 @@ export const append = async (filePath, data, startsAt = 1) => {
|
|
|
221
224
|
};
|
|
222
225
|
export const remove = async (filePath, linesToDelete) => {
|
|
223
226
|
let lineCount = 0;
|
|
224
|
-
const linesToDeleteArray = new Set(Array.isArray(linesToDelete) ? linesToDelete : [linesToDelete]), fileHandle = await open(filePath, "r
|
|
227
|
+
const linesToDeleteArray = new Set(Array.isArray(linesToDelete) ? linesToDelete : [linesToDelete]), fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
225
228
|
? fileHandle.readLines({ autoClose: false })
|
|
226
229
|
: createInterface({
|
|
227
230
|
input: fileHandle.createReadStream({ autoClose: false }),
|
|
228
231
|
crlfDelay: Infinity,
|
|
229
|
-
}), writeStream =
|
|
232
|
+
}), fileTempPath = `${filePath.replace(".inib", "")}-${Date.now()}.tmp`, fileTempHandle = await open(fileTempPath, "w+"), writeStream = fileTempHandle.createWriteStream({ autoClose: false });
|
|
230
233
|
for await (const line of rl) {
|
|
231
234
|
lineCount++;
|
|
232
235
|
if (!linesToDeleteArray.has(lineCount))
|
|
233
236
|
writeStream.write(`${line}\n`);
|
|
234
237
|
}
|
|
235
|
-
writeStream.end(async () => await
|
|
238
|
+
// writeStream.end(async () => await rename(fileTempPath, filePath));
|
|
239
|
+
await fileHandle.close();
|
|
240
|
+
await fileTempHandle.close();
|
|
241
|
+
await rename(fileTempPath, filePath);
|
|
236
242
|
};
|
|
237
243
|
export const count = async (filePath) => {
|
|
238
244
|
let lineCount = 0;
|
|
239
245
|
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
240
|
-
? fileHandle.readLines()
|
|
246
|
+
? fileHandle.readLines({ autoClose: false })
|
|
241
247
|
: createInterface({
|
|
242
|
-
input: fileHandle.createReadStream(),
|
|
248
|
+
input: fileHandle.createReadStream({ autoClose: false }),
|
|
243
249
|
crlfDelay: Infinity,
|
|
244
250
|
});
|
|
245
251
|
for await (const line of rl)
|
|
@@ -301,9 +307,9 @@ const handleComparisonOperator = (operator, originalValue, comparedAtValue, fiel
|
|
|
301
307
|
export const search = async (filePath, operator, comparedAtValue, logicalOperator, fieldType, fieldChildrenType, limit, offset, readWholeFile, secretKey) => {
|
|
302
308
|
let RETURN = new Map(), lineCount = 0, foundItems = 0;
|
|
303
309
|
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
304
|
-
? fileHandle.readLines()
|
|
310
|
+
? fileHandle.readLines({ autoClose: false })
|
|
305
311
|
: createInterface({
|
|
306
|
-
input: fileHandle.createReadStream(),
|
|
312
|
+
input: fileHandle.createReadStream({ autoClose: false }),
|
|
307
313
|
crlfDelay: Infinity,
|
|
308
314
|
});
|
|
309
315
|
for await (const line of rl) {
|
|
@@ -335,9 +341,9 @@ export const search = async (filePath, operator, comparedAtValue, logicalOperato
|
|
|
335
341
|
};
|
|
336
342
|
export const sum = async (filePath, lineNumbers) => {
|
|
337
343
|
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
338
|
-
? fileHandle.readLines()
|
|
344
|
+
? fileHandle.readLines({ autoClose: false })
|
|
339
345
|
: createInterface({
|
|
340
|
-
input: fileHandle.createReadStream(),
|
|
346
|
+
input: fileHandle.createReadStream({ autoClose: false }),
|
|
341
347
|
crlfDelay: Infinity,
|
|
342
348
|
});
|
|
343
349
|
let sum = 0;
|
|
@@ -357,14 +363,13 @@ export const sum = async (filePath, lineNumbers) => {
|
|
|
357
363
|
else
|
|
358
364
|
for await (const line of rl)
|
|
359
365
|
sum += +decode(line, "number");
|
|
360
|
-
await fileHandle.close();
|
|
361
366
|
return sum;
|
|
362
367
|
};
|
|
363
368
|
export const max = async (filePath, lineNumbers) => {
|
|
364
369
|
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
365
|
-
? fileHandle.readLines()
|
|
370
|
+
? fileHandle.readLines({ autoClose: false })
|
|
366
371
|
: createInterface({
|
|
367
|
-
input: fileHandle.createReadStream(),
|
|
372
|
+
input: fileHandle.createReadStream({ autoClose: false }),
|
|
368
373
|
crlfDelay: Infinity,
|
|
369
374
|
});
|
|
370
375
|
let max = 0;
|
|
@@ -389,14 +394,13 @@ export const max = async (filePath, lineNumbers) => {
|
|
|
389
394
|
if (lineContentNum > max)
|
|
390
395
|
max = lineContentNum;
|
|
391
396
|
}
|
|
392
|
-
await fileHandle.close();
|
|
393
397
|
return max;
|
|
394
398
|
};
|
|
395
399
|
export const min = async (filePath, lineNumbers) => {
|
|
396
400
|
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
397
|
-
? fileHandle.readLines()
|
|
401
|
+
? fileHandle.readLines({ autoClose: false })
|
|
398
402
|
: createInterface({
|
|
399
|
-
input: fileHandle.createReadStream(),
|
|
403
|
+
input: fileHandle.createReadStream({ autoClose: false }),
|
|
400
404
|
crlfDelay: Infinity,
|
|
401
405
|
});
|
|
402
406
|
let min = 0;
|
|
@@ -421,21 +425,18 @@ export const min = async (filePath, lineNumbers) => {
|
|
|
421
425
|
if (lineContentNum < min)
|
|
422
426
|
min = lineContentNum;
|
|
423
427
|
}
|
|
424
|
-
await fileHandle.close();
|
|
425
428
|
return min;
|
|
426
429
|
};
|
|
427
430
|
export const sort = async (filePath, sortDirection, lineNumbers, _lineNumbersPerChunk = 100000) => {
|
|
428
431
|
const fileHandle = await open(filePath, "r"), rl = doesSupportReadLines()
|
|
429
|
-
? fileHandle.readLines()
|
|
432
|
+
? fileHandle.readLines({ autoClose: false })
|
|
430
433
|
: createInterface({
|
|
431
|
-
input: fileHandle.createReadStream(),
|
|
434
|
+
input: fileHandle.createReadStream({ autoClose: false }),
|
|
432
435
|
crlfDelay: Infinity,
|
|
433
436
|
});
|
|
434
437
|
let lineCount = 0;
|
|
435
|
-
for await (const line of rl)
|
|
438
|
+
for await (const line of rl)
|
|
436
439
|
lineCount++;
|
|
437
|
-
}
|
|
438
|
-
await fileHandle.close();
|
|
439
440
|
};
|
|
440
441
|
export default class File {
|
|
441
442
|
static get = get;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
export interface Data {
|
|
3
3
|
id?: number | string;
|
|
4
4
|
[key: string]: any;
|
|
5
|
-
createdAt?:
|
|
6
|
-
updatedAt?:
|
|
5
|
+
createdAt?: number;
|
|
6
|
+
updatedAt?: number;
|
|
7
7
|
}
|
|
8
8
|
export type FieldType = "string" | "number" | "boolean" | "date" | "email" | "url" | "table" | "object" | "array" | "password" | "html" | "ip" | "id";
|
|
9
9
|
type FieldDefault = {
|
|
@@ -75,8 +75,12 @@ export default class Inibase {
|
|
|
75
75
|
private joinPathesContents;
|
|
76
76
|
get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: true, onlyLinesNumbers?: undefined): Promise<Data | null>;
|
|
77
77
|
get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: boolean | undefined, onlyLinesNumbers?: true): Promise<number[] | null>;
|
|
78
|
-
post
|
|
79
|
-
|
|
78
|
+
post(tableName: string, data: Data | Data[], options: Options | undefined, returnPostedData?: false): Promise<void | null>;
|
|
79
|
+
post(tableName: string, data: Data, options: Options | undefined, returnPostedData: true): Promise<Data | null>;
|
|
80
|
+
post(tableName: string, data: Data[], options: Options | undefined, returnPostedData: true): Promise<Data[] | null>;
|
|
81
|
+
put(tableName: string, data: Data | Data[], where?: number | string | (number | string)[] | Criteria | undefined, options?: Options | undefined, returnPostedData?: false): Promise<void | null>;
|
|
82
|
+
put(tableName: string, data: Data, where: number | string | (number | string)[] | Criteria | undefined, options: Options | undefined, returnPostedData: true): Promise<Data | null>;
|
|
83
|
+
put(tableName: string, data: Data[], where: number | string | (number | string)[] | Criteria | undefined, options: Options | undefined, returnPostedData: true): Promise<Data[] | null>;
|
|
80
84
|
delete(tableName: string, where?: number | string | (number | string)[] | Criteria, _id?: string | string[]): Promise<string | string[] | null>;
|
|
81
85
|
sum(tableName: string, columns: string, where?: number | string | (number | string)[] | Criteria): Promise<number>;
|
|
82
86
|
sum(tableName: string, columns: string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
|
package/dist/index.js
CHANGED
|
@@ -505,7 +505,9 @@ export default class Inibase {
|
|
|
505
505
|
if (!lineNumbers)
|
|
506
506
|
throw this.throwError("INVALID_ID", where);
|
|
507
507
|
if (onlyLinesNumbers)
|
|
508
|
-
return Object.keys(lineNumbers).
|
|
508
|
+
return Object.keys(lineNumbers).length
|
|
509
|
+
? Object.keys(lineNumbers).map(Number)
|
|
510
|
+
: null;
|
|
509
511
|
RETURN = Object.values((await getItemsFromSchema(join(this.folder, this.database, tableName), schema, Object.keys(lineNumbers).map(Number))) ?? {});
|
|
510
512
|
if (RETURN.length && !Array.isArray(where))
|
|
511
513
|
RETURN = RETURN[0];
|
|
@@ -695,13 +697,13 @@ export default class Inibase {
|
|
|
695
697
|
RETURN = data.map(({ id, updatedAt, createdAt, ...rest }) => ({
|
|
696
698
|
id: ++last_id,
|
|
697
699
|
...rest,
|
|
698
|
-
createdAt: new Date(),
|
|
700
|
+
createdAt: new Date().getTime(),
|
|
699
701
|
}));
|
|
700
702
|
else
|
|
701
703
|
RETURN = (({ id, updatedAt, createdAt, ...rest }) => ({
|
|
702
704
|
id: ++last_id,
|
|
703
705
|
...rest,
|
|
704
|
-
createdAt: new Date(),
|
|
706
|
+
createdAt: new Date().getTime(),
|
|
705
707
|
}))(data);
|
|
706
708
|
if (!RETURN)
|
|
707
709
|
throw this.throwError("NO_DATA");
|
|
@@ -742,11 +744,11 @@ export default class Inibase {
|
|
|
742
744
|
const pathesContents = this.joinPathesContents(join(this.folder, this.database, tableName), Utils.isArrayOfObjects(data)
|
|
743
745
|
? data.map((item) => ({
|
|
744
746
|
...(({ id, ...restOfData }) => restOfData)(item),
|
|
745
|
-
updatedAt: new Date(),
|
|
747
|
+
updatedAt: new Date().getTime(),
|
|
746
748
|
}))
|
|
747
749
|
: {
|
|
748
750
|
...(({ id, ...restOfData }) => restOfData)(data),
|
|
749
|
-
updatedAt: new Date(),
|
|
751
|
+
updatedAt: new Date().getTime(),
|
|
750
752
|
});
|
|
751
753
|
for await (const [path, content] of Object.entries(pathesContents))
|
|
752
754
|
await File.replace(path, content);
|
|
@@ -769,9 +771,9 @@ export default class Inibase {
|
|
|
769
771
|
const pathesContents = Object.fromEntries(Object.entries(this.joinPathesContents(join(this.folder, this.database, tableName), Utils.isArrayOfObjects(data)
|
|
770
772
|
? data.map((item) => ({
|
|
771
773
|
...item,
|
|
772
|
-
updatedAt: new Date(),
|
|
774
|
+
updatedAt: new Date().getTime(),
|
|
773
775
|
}))
|
|
774
|
-
: { ...data, updatedAt: new Date() })).map(([path, content]) => [
|
|
776
|
+
: { ...data, updatedAt: new Date().getTime() })).map(([path, content]) => [
|
|
775
777
|
path,
|
|
776
778
|
[...(Array.isArray(where) ? where : [where])].reduce((obj, lineNum, index) => ({
|
|
777
779
|
...obj,
|
|
@@ -784,9 +786,9 @@ export default class Inibase {
|
|
|
784
786
|
return this.get(tableName, where, options, !Array.isArray(where));
|
|
785
787
|
}
|
|
786
788
|
}
|
|
787
|
-
else if (
|
|
788
|
-
const lineNumbers = this.get(tableName, where, undefined, undefined, true);
|
|
789
|
-
if (!lineNumbers || !
|
|
789
|
+
else if (Utils.isObject(where)) {
|
|
790
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
791
|
+
if (!lineNumbers || !lineNumbers.length)
|
|
790
792
|
throw this.throwError("NO_ITEMS", tableName);
|
|
791
793
|
return this.put(tableName, data, lineNumbers);
|
|
792
794
|
}
|
|
@@ -823,16 +825,18 @@ export default class Inibase {
|
|
|
823
825
|
const files = await readdir(join(this.folder, this.database, tableName));
|
|
824
826
|
if (files.length) {
|
|
825
827
|
if (!_id)
|
|
826
|
-
_id = Object.values((await File.get(join(this.folder, this.database, tableName, "id.inib"), where, "number", undefined, this.salt))[0]).map((id) => UtilsServer.encodeID(Number(id), this.salt));
|
|
828
|
+
_id = Object.values((await File.get(join(this.folder, this.database, tableName, "id.inib"), where, "number", undefined, this.salt))[0] ?? {}).map((id) => UtilsServer.encodeID(Number(id), this.salt));
|
|
829
|
+
if (!_id.length)
|
|
830
|
+
throw this.throwError("NO_ITEMS", tableName);
|
|
827
831
|
for (const file of files.filter((fileName) => fileName.endsWith(".inib")))
|
|
828
832
|
await File.remove(join(this.folder, this.database, tableName, file), where);
|
|
829
833
|
return Array.isArray(_id) && _id.length === 1 ? _id[0] : _id;
|
|
830
834
|
}
|
|
831
835
|
}
|
|
832
836
|
}
|
|
833
|
-
else if (
|
|
834
|
-
const lineNumbers = this.get(tableName, where, undefined, undefined, true);
|
|
835
|
-
if (!lineNumbers || !
|
|
837
|
+
else if (Utils.isObject(where)) {
|
|
838
|
+
const lineNumbers = await this.get(tableName, where, undefined, undefined, true);
|
|
839
|
+
if (!lineNumbers || !lineNumbers.length)
|
|
836
840
|
throw this.throwError("NO_ITEMS", tableName);
|
|
837
841
|
return this.delete(tableName, lineNumbers);
|
|
838
842
|
}
|
package/dist/utils.js
CHANGED
|
@@ -81,7 +81,8 @@ export const isBoolean = (input) => typeof input === "boolean" ||
|
|
|
81
81
|
input === true ||
|
|
82
82
|
input === false;
|
|
83
83
|
export const isPassword = (input) => input.length === 161;
|
|
84
|
-
export const isDate = (input) =>
|
|
84
|
+
export const isDate = (input) => (isNumber(input) && new Date(input).getTime() > 0) ||
|
|
85
|
+
(!isNaN(Date.parse(String(input))) && Date.parse(String(input)) >= 0);
|
|
85
86
|
export const isValidID = (input) => {
|
|
86
87
|
return typeof input === "string" && input.length === 32;
|
|
87
88
|
};
|
|
@@ -198,7 +199,7 @@ export const objectToDotNotation = (input) => {
|
|
|
198
199
|
// If the property is an array of strings or numbers, keep the array as is
|
|
199
200
|
result[newKey] = value;
|
|
200
201
|
}
|
|
201
|
-
else if (
|
|
202
|
+
else if (isObject(value)) {
|
|
202
203
|
// If the property is an object, push it onto the stack for further processing
|
|
203
204
|
stack.push({ obj: value, parentKey: newKey });
|
|
204
205
|
}
|