inibase 1.0.0-rc.6 → 1.0.0-rc.8

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/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.6",
3
+ "version": "1.0.0-rc.8",
4
4
  "description": "File-based Relational Database for large data",
5
5
  "main": "index.ts",
6
6
  "type": "module",
7
+ "scripts": {
8
+ "test": "npx tsx watch ./index.test.ts"
9
+ },
7
10
  "repository": {
8
11
  "type": "git",
9
12
  "url": "git+https://github.com/inicontent/inibase.git"
@@ -31,8 +34,5 @@
31
34
  "homepage": "https://github.com/inicontent/inibase#readme",
32
35
  "devDependencies": {
33
36
  "@types/node": "^20.8.6"
34
- },
35
- "scripts": {
36
- "test": "npx tsx watch ./index.test.ts"
37
37
  }
38
- }
38
+ }
@@ -0,0 +1,79 @@
1
+ import {
2
+ scryptSync,
3
+ randomBytes,
4
+ timingSafeEqual,
5
+ createDecipheriv,
6
+ createCipheriv,
7
+ Cipher,
8
+ Decipher,
9
+ } from "node:crypto";
10
+
11
+ export const hashPassword = (password: string) => {
12
+ const salt = randomBytes(16).toString("hex");
13
+ const buf = scryptSync(password, salt, 64);
14
+ // return "161" length string
15
+ return `${buf.toString("hex")}.${salt}`;
16
+ };
17
+
18
+ export const comparePassword = (
19
+ storedPassword: string,
20
+ suppliedPassword: string
21
+ ) => {
22
+ // split() returns array
23
+ const [hashedPassword, salt] = storedPassword.split(".");
24
+ // we need to pass buffer values to timingSafeEqual
25
+ const hashedPasswordBuf = Buffer.from(hashedPassword, "hex");
26
+ // we hash the new sign-in password
27
+ const suppliedPasswordBuf = scryptSync(suppliedPassword, salt, 64);
28
+ // compare the new supplied password with the stored hashed password
29
+ return timingSafeEqual(hashedPasswordBuf, suppliedPasswordBuf);
30
+ };
31
+
32
+ export const encodeID = (
33
+ id: number,
34
+ secretKey: string | number | Buffer
35
+ ): string => {
36
+ let cipher: Cipher, ret: string;
37
+
38
+ if (Buffer.isBuffer(secretKey))
39
+ cipher = createCipheriv(
40
+ "aes-256-cbc",
41
+ secretKey,
42
+ secretKey.subarray(0, 16)
43
+ );
44
+ else {
45
+ const salt = scryptSync(secretKey.toString(), "salt", 32);
46
+ cipher = createCipheriv("aes-256-cbc", salt, salt.subarray(0, 16));
47
+ }
48
+
49
+ return cipher.update(id.toString(), "utf8", "hex") + cipher.final("hex");
50
+ };
51
+
52
+ export const decodeID = (
53
+ input: string,
54
+ secretKey: string | number | Buffer
55
+ ): number => {
56
+ let decipher: Decipher;
57
+
58
+ if (Buffer.isBuffer(secretKey))
59
+ decipher = createDecipheriv(
60
+ "aes-256-cbc",
61
+ secretKey,
62
+ secretKey.subarray(0, 16)
63
+ );
64
+ else {
65
+ const salt = scryptSync(secretKey.toString(), "salt", 32);
66
+ decipher = createDecipheriv("aes-256-cbc", salt, salt.subarray(0, 16));
67
+ }
68
+
69
+ return Number(
70
+ decipher.update(input as string, "hex", "utf8") + decipher.final("utf8")
71
+ );
72
+ };
73
+
74
+ export default class Utils {
75
+ static encodeID = encodeID;
76
+ static decodeID = decodeID;
77
+ static hashPassword = hashPassword;
78
+ static comparePassword = comparePassword;
79
+ }
package/utils.ts CHANGED
@@ -1,13 +1,4 @@
1
- import {
2
- scryptSync,
3
- randomBytes,
4
- timingSafeEqual,
5
- createDecipheriv,
6
- createCipheriv,
7
- Cipher,
8
- Decipher,
9
- } from "node:crypto";
10
- import { FieldType } from ".";
1
+ import { FieldType, Data } from ".";
11
2
 
12
3
  export const isArrayOfObjects = (arr: any) => {
13
4
  return Array.isArray(arr) && (arr.length === 0 || arr.every(isObject));
@@ -80,69 +71,6 @@ export const isPassword = (input: any) => input.length === 161;
80
71
  export const isDate = (input: any) =>
81
72
  !isNaN(Date.parse(String(input))) && Date.parse(String(input)) >= 0;
82
73
 
83
- export const hashPassword = (password: string) => {
84
- const salt = randomBytes(16).toString("hex");
85
- const buf = scryptSync(password, salt, 64);
86
- // return "161" length string
87
- return `${buf.toString("hex")}.${salt}`;
88
- };
89
-
90
- export const comparePassword = (
91
- storedPassword: string,
92
- suppliedPassword: string
93
- ) => {
94
- // split() returns array
95
- const [hashedPassword, salt] = storedPassword.split(".");
96
- // we need to pass buffer values to timingSafeEqual
97
- const hashedPasswordBuf = Buffer.from(hashedPassword, "hex");
98
- // we hash the new sign-in password
99
- const suppliedPasswordBuf = scryptSync(suppliedPassword, salt, 64);
100
- // compare the new supplied password with the stored hashed password
101
- return timingSafeEqual(hashedPasswordBuf, suppliedPasswordBuf);
102
- };
103
-
104
- export const encodeID = (
105
- id: number,
106
- secretKey: string | number | Buffer
107
- ): string => {
108
- let cipher: Cipher, ret: string;
109
-
110
- if (Buffer.isBuffer(secretKey))
111
- cipher = createCipheriv(
112
- "aes-256-cbc",
113
- secretKey,
114
- secretKey.subarray(0, 16)
115
- );
116
- else {
117
- const salt = scryptSync(secretKey.toString(), "salt", 32);
118
- cipher = createCipheriv("aes-256-cbc", salt, salt.subarray(0, 16));
119
- }
120
-
121
- return cipher.update(id.toString(), "utf8", "hex") + cipher.final("hex");
122
- };
123
-
124
- export const decodeID = (
125
- input: string,
126
- secretKey: string | number | Buffer
127
- ): number => {
128
- let decipher: Decipher;
129
-
130
- if (Buffer.isBuffer(secretKey))
131
- decipher = createDecipheriv(
132
- "aes-256-cbc",
133
- secretKey,
134
- secretKey.subarray(0, 16)
135
- );
136
- else {
137
- const salt = scryptSync(secretKey.toString(), "salt", 32);
138
- decipher = createDecipheriv("aes-256-cbc", salt, salt.subarray(0, 16));
139
- }
140
-
141
- return Number(
142
- decipher.update(input as string, "hex", "utf8") + decipher.final("utf8")
143
- );
144
- };
145
-
146
74
  export const isValidID = (input: any): boolean => {
147
75
  return Array.isArray(input)
148
76
  ? input.every(isValidID)
@@ -175,30 +103,94 @@ export const detectFieldType = (
175
103
  availableTypes.includes("boolean")
176
104
  )
177
105
  return "boolean";
178
- else if (Utils.isNumber(input)) {
106
+ else if (isNumber(input)) {
179
107
  if (availableTypes.includes("table")) return "table";
180
108
  else if (availableTypes.includes("date")) return "date";
181
109
  else if (availableTypes.includes("number")) return "number";
182
110
  } else if (input.includes(",") && availableTypes.includes("array"))
183
111
  return "array";
184
- else if (availableTypes.includes("email") && Utils.isEmail(input))
185
- return "email";
186
- else if (availableTypes.includes("url") && Utils.isURL(input)) return "url";
187
- else if (availableTypes.includes("password") && Utils.isPassword(input))
112
+ else if (availableTypes.includes("email") && isEmail(input)) return "email";
113
+ else if (availableTypes.includes("url") && isURL(input)) return "url";
114
+ else if (availableTypes.includes("password") && isPassword(input))
188
115
  return "password";
189
- else if (availableTypes.includes("date") && Utils.isDate(input))
190
- return "date";
191
- else if (availableTypes.includes("string") && Utils.isString(input))
116
+ else if (availableTypes.includes("date") && isDate(input)) return "date";
117
+ else if (availableTypes.includes("string") && isString(input))
192
118
  return "string";
193
- else if (availableTypes.includes("ip") && Utils.isIP(input)) return "ip";
119
+ else if (availableTypes.includes("ip") && isIP(input)) return "ip";
194
120
  } else return "array";
195
121
 
196
122
  return undefined;
197
123
  };
198
124
 
125
+ export const validateFieldType = (
126
+ value: any,
127
+ fieldType: FieldType | FieldType[],
128
+ fieldChildrenType?: FieldType | FieldType[]
129
+ ): boolean => {
130
+ if (value === null) return true;
131
+ if (Array.isArray(fieldType))
132
+ return detectFieldType(value, fieldType) !== undefined;
133
+ if (fieldType === "array" && fieldChildrenType && Array.isArray(value))
134
+ return value.some(
135
+ (v) =>
136
+ detectFieldType(
137
+ v,
138
+ Array.isArray(fieldChildrenType)
139
+ ? fieldChildrenType
140
+ : [fieldChildrenType]
141
+ ) !== undefined
142
+ );
143
+
144
+ switch (fieldType) {
145
+ case "string":
146
+ return isString(value);
147
+ case "password":
148
+ return isNumber(value) || isString(value) || isPassword(value);
149
+ case "number":
150
+ return isNumber(value);
151
+ case "html":
152
+ return isHTML(value);
153
+ case "ip":
154
+ return isIP(value);
155
+ case "boolean":
156
+ return isBoolean(value);
157
+ case "date":
158
+ return isDate(value);
159
+ case "object":
160
+ return isObject(value);
161
+ case "array":
162
+ return Array.isArray(value);
163
+ case "email":
164
+ return isEmail(value);
165
+ case "url":
166
+ return isURL(value);
167
+ case "table":
168
+ // feat: check if id exists
169
+ if (Array.isArray(value))
170
+ return (
171
+ (isArrayOfObjects(value) &&
172
+ value.every(
173
+ (element: Data) =>
174
+ element.hasOwnProperty("id") &&
175
+ (isValidID(element.id) || isNumber(element.id))
176
+ )) ||
177
+ value.every(isNumber) ||
178
+ isValidID(value)
179
+ );
180
+ else if (isObject(value))
181
+ return (
182
+ value.hasOwnProperty("id") &&
183
+ (isValidID((value as Data).id) || isNumber((value as Data).id))
184
+ );
185
+ else return isNumber(value) || isValidID(value);
186
+ case "id":
187
+ return isNumber(value) || isValidID(value);
188
+ default:
189
+ return false;
190
+ }
191
+ };
192
+
199
193
  export default class Utils {
200
- static encodeID = encodeID;
201
- static decodeID = decodeID;
202
194
  static isNumber = isNumber;
203
195
  static isObject = isObject;
204
196
  static isEmail = isEmail;
@@ -206,10 +198,8 @@ export default class Utils {
206
198
  static isURL = isURL;
207
199
  static isValidID = isValidID;
208
200
  static isPassword = isPassword;
209
- static hashPassword = hashPassword;
210
201
  static deepMerge = deepMerge;
211
202
  static combineObjects = combineObjects;
212
- static comparePassword = comparePassword;
213
203
  static isArrayOfObjects = isArrayOfObjects;
214
204
  static findChangedProperties = findChangedProperties;
215
205
  static detectFieldType = detectFieldType;
@@ -218,4 +208,5 @@ export default class Utils {
218
208
  static isString = isString;
219
209
  static isHTML = isHTML;
220
210
  static isIP = isIP;
211
+ static validateFieldType = validateFieldType;
221
212
  }