inibase 1.0.0-rc.3 → 1.0.0-rc.5
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 +16 -6
- package/file.ts +240 -85
- package/index.test.ts +248 -0
- package/index.ts +726 -436
- package/package.json +3 -2
- package/tsconfig.json +2 -1
- package/utils.ts +99 -44
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inibase",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.5",
|
|
4
4
|
"description": "File-based Relational Database for large data",
|
|
5
5
|
"main": "index.ts",
|
|
6
|
+
"type": "module",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "git+https://github.com/inicontent/inibase.git"
|
|
@@ -32,6 +33,6 @@
|
|
|
32
33
|
"@types/node": "^20.6.0"
|
|
33
34
|
},
|
|
34
35
|
"scripts": {
|
|
35
|
-
"test": "
|
|
36
|
+
"test": "npx tsx watch ./index.test.ts"
|
|
36
37
|
}
|
|
37
38
|
}
|
package/tsconfig.json
CHANGED
package/utils.ts
CHANGED
|
@@ -1,49 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
scryptSync,
|
|
3
|
+
randomBytes,
|
|
4
|
+
timingSafeEqual,
|
|
5
|
+
createDecipheriv,
|
|
6
|
+
createCipheriv,
|
|
7
|
+
} from "crypto";
|
|
1
8
|
import { FieldType } from ".";
|
|
2
|
-
import { scryptSync, randomBytes, timingSafeEqual } from "crypto";
|
|
3
|
-
|
|
4
|
-
export const encode = (
|
|
5
|
-
input: string | number | boolean | null | (string | number | boolean | null)[]
|
|
6
|
-
) => {
|
|
7
|
-
const secureString = (input: string | number | boolean | null) => {
|
|
8
|
-
if (["true", "false"].includes((input ?? "").toString()))
|
|
9
|
-
return input ? 1 : 0;
|
|
10
|
-
return typeof input === "string"
|
|
11
|
-
? decodeURIComponent(input)
|
|
12
|
-
.replaceAll("<", "<")
|
|
13
|
-
.replaceAll(">", ">")
|
|
14
|
-
.replaceAll(",", "%2C")
|
|
15
|
-
.replaceAll("\n", "\\n")
|
|
16
|
-
.replaceAll("\r", "\\r")
|
|
17
|
-
: input;
|
|
18
|
-
};
|
|
19
|
-
return Array.isArray(input)
|
|
20
|
-
? input.map(secureString).join(",")
|
|
21
|
-
: secureString(input);
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export const decode = (
|
|
25
|
-
input: string | null | number,
|
|
26
|
-
fieldType?: FieldType
|
|
27
|
-
): string | number | boolean | null | (string | number | null | boolean)[] => {
|
|
28
|
-
const unSecureString = (input: string) =>
|
|
29
|
-
decodeURIComponent(input)
|
|
30
|
-
.replaceAll("<", "<")
|
|
31
|
-
.replaceAll(">", ">")
|
|
32
|
-
.replaceAll("%2C", ",")
|
|
33
|
-
.replaceAll("\\n", "\n")
|
|
34
|
-
.replaceAll("\\r", "\r") || null;
|
|
35
|
-
|
|
36
|
-
if (input === null || input === "") return null;
|
|
37
|
-
if (!isNaN(Number(input)) && isFinite(Number(input)))
|
|
38
|
-
return fieldType === "boolean" ? Boolean(Number(input)) : Number(input);
|
|
39
|
-
return (input as string).includes(",")
|
|
40
|
-
? (input as string).split(",").map(unSecureString)
|
|
41
|
-
: unSecureString(input as string);
|
|
42
|
-
};
|
|
43
9
|
|
|
44
10
|
export const isArrayOfObjects = (arr: any) => {
|
|
45
11
|
return Array.isArray(arr) && (arr.length === 0 || arr.every(isObject));
|
|
46
12
|
};
|
|
13
|
+
export const isArrayOfArrays = (arr: any) => {
|
|
14
|
+
return Array.isArray(arr) && (arr.length === 0 || arr.every(Array.isArray));
|
|
15
|
+
};
|
|
47
16
|
|
|
48
17
|
export const isObject = (obj: any) =>
|
|
49
18
|
obj != null &&
|
|
@@ -76,6 +45,20 @@ export const isNumber = (input: any): boolean =>
|
|
|
76
45
|
? input.every(isNumber)
|
|
77
46
|
: !isNaN(parseFloat(input)) && !isNaN(input - 0);
|
|
78
47
|
|
|
48
|
+
export const isEmail = (input: any) =>
|
|
49
|
+
/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(input));
|
|
50
|
+
|
|
51
|
+
export const isURL = (input: any) =>
|
|
52
|
+
input[0] === "#" ||
|
|
53
|
+
/^((https?|www):\/\/)?[a-z0-9-]+(\.[a-z0-9-]+)*\.[a-z]+(\/[^\s]*)?$/.test(
|
|
54
|
+
input
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export const isPassword = (input: any) => input.length === 161;
|
|
58
|
+
|
|
59
|
+
export const isDate = (input: any) =>
|
|
60
|
+
!isNaN(Date.parse(String(input))) && Date.parse(String(input)) >= 0;
|
|
61
|
+
|
|
79
62
|
export const hashPassword = (password: string) => {
|
|
80
63
|
const salt = randomBytes(16).toString("hex");
|
|
81
64
|
const buf = scryptSync(password, salt, 64);
|
|
@@ -97,14 +80,86 @@ export const comparePassword = (
|
|
|
97
80
|
return timingSafeEqual(hashedPasswordBuf, suppliedPasswordBuf);
|
|
98
81
|
};
|
|
99
82
|
|
|
83
|
+
export const encodeID = (id: number, secretKey: string | number): string => {
|
|
84
|
+
const salt = scryptSync(secretKey.toString(), "salt", 32),
|
|
85
|
+
cipher = createCipheriv("aes-256-cbc", salt, salt.subarray(0, 16));
|
|
86
|
+
|
|
87
|
+
return cipher.update(id.toString(), "utf8", "hex") + cipher.final("hex");
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const decodeID = (input: string, secretKey: string | number): number => {
|
|
91
|
+
const salt = scryptSync(secretKey.toString(), "salt", 32),
|
|
92
|
+
decipher = createDecipheriv("aes-256-cbc", salt, salt.subarray(0, 16));
|
|
93
|
+
return Number(
|
|
94
|
+
decipher.update(input as string, "hex", "utf8") + decipher.final("utf8")
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const isValidID = (input: any): boolean => {
|
|
99
|
+
return Array.isArray(input)
|
|
100
|
+
? input.every(isValidID)
|
|
101
|
+
: typeof input === "string" && input.length === 32;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const findChangedProperties = (
|
|
105
|
+
obj1: Record<string, string>,
|
|
106
|
+
obj2: Record<string, string>
|
|
107
|
+
): Record<string, string> | null => {
|
|
108
|
+
const result: Record<string, string> = {};
|
|
109
|
+
|
|
110
|
+
for (const key1 in obj1)
|
|
111
|
+
if (obj2.hasOwnProperty(key1) && obj1[key1] !== obj2[key1])
|
|
112
|
+
result[obj1[key1]] = obj2[key1];
|
|
113
|
+
|
|
114
|
+
return Object.keys(result).length ? result : null;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const detectFieldType = (
|
|
118
|
+
input: any,
|
|
119
|
+
availableTypes: FieldType[]
|
|
120
|
+
): FieldType | undefined => {
|
|
121
|
+
if (
|
|
122
|
+
(input === "0" || input === "1" || input === "true" || input === "false") &&
|
|
123
|
+
availableTypes.includes("boolean")
|
|
124
|
+
)
|
|
125
|
+
return "boolean";
|
|
126
|
+
else if (Utils.isNumber(input)) {
|
|
127
|
+
if (availableTypes.includes("table")) return "table";
|
|
128
|
+
else if (availableTypes.includes("number")) return "number";
|
|
129
|
+
else if (availableTypes.includes("date")) return "date";
|
|
130
|
+
} else if (
|
|
131
|
+
(Array.isArray(input) || input.includes(",")) &&
|
|
132
|
+
availableTypes.includes("array")
|
|
133
|
+
)
|
|
134
|
+
return "array";
|
|
135
|
+
else if (Utils.isEmail(input) && availableTypes.includes("email"))
|
|
136
|
+
return "email";
|
|
137
|
+
else if (Utils.isURL(input) && availableTypes.includes("url")) return "url";
|
|
138
|
+
else if (Utils.isPassword(input) && availableTypes.includes("password"))
|
|
139
|
+
return "password";
|
|
140
|
+
else if (Utils.isDate(input) && availableTypes.includes("date"))
|
|
141
|
+
return "date";
|
|
142
|
+
else if (!Utils.isNumber(input) && availableTypes.includes("string"))
|
|
143
|
+
return "string";
|
|
144
|
+
else return undefined;
|
|
145
|
+
};
|
|
146
|
+
|
|
100
147
|
export default class Utils {
|
|
101
|
-
static
|
|
102
|
-
static
|
|
148
|
+
static encodeID = encodeID;
|
|
149
|
+
static decodeID = decodeID;
|
|
103
150
|
static isNumber = isNumber;
|
|
104
151
|
static isObject = isObject;
|
|
105
|
-
static
|
|
152
|
+
static isEmail = isEmail;
|
|
153
|
+
static isDate = isDate;
|
|
154
|
+
static isURL = isURL;
|
|
155
|
+
static isValidID = isValidID;
|
|
156
|
+
static isPassword = isPassword;
|
|
106
157
|
static hashPassword = hashPassword;
|
|
158
|
+
static deepMerge = deepMerge;
|
|
107
159
|
static combineObjects = combineObjects;
|
|
108
160
|
static comparePassword = comparePassword;
|
|
109
161
|
static isArrayOfObjects = isArrayOfObjects;
|
|
162
|
+
static findChangedProperties = findChangedProperties;
|
|
163
|
+
static detectFieldType = detectFieldType;
|
|
164
|
+
static isArrayOfArrays = isArrayOfArrays;
|
|
110
165
|
}
|