inibase 1.0.0-rc.5 → 1.0.0-rc.6

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 CHANGED
@@ -50,11 +50,7 @@ Become a sponsor and have your company logo here 👉 [GitHub Sponsors](https://
50
50
  ## Install
51
51
 
52
52
  ```js
53
- // npm
54
- npm install inibase
55
-
56
- // pnpm
57
- pnpm add inibase
53
+ <npm|pnpm> install inibase
58
54
  ```
59
55
 
60
56
  ## How it works?
@@ -465,9 +461,9 @@ type Data = {
465
461
  - [x] Object
466
462
  - [x] Array
467
463
  - [x] Password
468
- - [ ] IP
469
- - [ ] HTML
470
- - [ ] Markdown
464
+ - [x] IP
465
+ - [x] HTML
466
+ - [x] Id
471
467
  - [ ] TO-DO:
472
468
  - [ ] Improve caching
473
469
  - [ ] Commenting the code
package/file.ts CHANGED
@@ -1,14 +1,7 @@
1
- import {
2
- createWriteStream,
3
- unlinkSync,
4
- renameSync,
5
- existsSync,
6
- createReadStream,
7
- WriteStream,
8
- } from "fs";
9
- import { open } from "fs/promises";
10
- import { Interface, createInterface } from "readline";
11
- import { parse } from "path";
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";
12
5
  import { ComparisonOperator, FieldType } from ".";
13
6
  import Utils from "./utils";
14
7
 
@@ -17,6 +10,14 @@ const doesSupportReadLines = () => {
17
10
  return major >= 18 && minor >= 11;
18
11
  };
19
12
 
13
+ export const isExists = async (path: string) => {
14
+ try {
15
+ await stat(path);
16
+ return true;
17
+ } catch {
18
+ return false;
19
+ }
20
+ };
20
21
  export const encodeFileName = (fileName: string, extension?: string) => {
21
22
  return (
22
23
  fileName.replaceAll("%", "%25").replaceAll("*", "%") +
@@ -79,7 +80,7 @@ export const decode = (
79
80
  case "boolean":
80
81
  return typeof value === "string" ? value === "true" : Boolean(value);
81
82
  case "array":
82
- if (!Array.isArray(value)) return null;
83
+ if (!Array.isArray(value)) return [value];
83
84
  if (fieldChildrenType)
84
85
  return value.map(
85
86
  (v) =>
@@ -170,7 +171,7 @@ export const replace = async (
170
171
  string | boolean | number | null | (string | boolean | number | null)[]
171
172
  >
172
173
  ) => {
173
- if (existsSync(filePath)) {
174
+ if (await isExists(filePath)) {
174
175
  let rl: Interface, writeStream: WriteStream;
175
176
  if (doesSupportReadLines()) {
176
177
  const file = await open(filePath, "w+");
@@ -220,7 +221,7 @@ export const remove = async (
220
221
  ): Promise<void> => {
221
222
  let lineCount = 0;
222
223
 
223
- const tempFilePath = `${filePath}.tmp`,
224
+ const tempFilePath = `${filePath}-${Date.now()}.tmp`,
224
225
  linesToDeleteArray = [
225
226
  ...(Array.isArray(linesToDelete) ? linesToDelete : [linesToDelete]),
226
227
  ];
@@ -243,10 +244,9 @@ export const remove = async (
243
244
  writeStream.write(`${line}\n`);
244
245
  }
245
246
  }
246
- writeStream.end();
247
- writeStream.on("finish", () => {
248
- unlinkSync(filePath); // Remove the original file
249
- renameSync(tempFilePath, filePath); // Rename the temp file to the original file name
247
+ writeStream.end(async () => {
248
+ await unlink(filePath); // Remove the original file
249
+ await rename(tempFilePath, filePath); // Rename the temp file to the original file name
250
250
  });
251
251
  };
252
252
 
@@ -279,7 +279,8 @@ export const search = async (
279
279
  fieldChildrenType?: FieldType | FieldType[],
280
280
  limit?: number,
281
281
  offset?: number,
282
- readWholeFile?: boolean
282
+ readWholeFile?: boolean,
283
+ secretKey?: string
283
284
  ): Promise<
284
285
  [
285
286
  Record<
@@ -311,6 +312,15 @@ export const search = async (
311
312
  ): boolean => {
312
313
  if (Array.isArray(fieldType))
313
314
  fieldType = Utils.detectFieldType(String(originalValue), fieldType);
315
+ if (Array.isArray(comparedAtValue) && !["[]", "![]"].includes(operator))
316
+ return comparedAtValue.some((comparedAtValueSingle) =>
317
+ handleComparisonOperator(
318
+ operator,
319
+ originalValue,
320
+ comparedAtValueSingle,
321
+ fieldType
322
+ )
323
+ );
314
324
  // check if not array or object // it can't be array or object!
315
325
  switch (operator) {
316
326
  case "=":
@@ -322,10 +332,13 @@ export const search = async (
322
332
  : false;
323
333
  case "boolean":
324
334
  return Number(originalValue) - Number(comparedAtValue) === 0;
335
+ case "id":
336
+ return secretKey && typeof comparedAtValue === "string"
337
+ ? Utils.decodeID(comparedAtValue as string, secretKey) ===
338
+ originalValue
339
+ : comparedAtValue === originalValue;
325
340
  default:
326
- return Array.isArray(comparedAtValue)
327
- ? comparedAtValue.some((value) => originalValue === value)
328
- : originalValue === comparedAtValue;
341
+ return originalValue === comparedAtValue;
329
342
  }
330
343
  case "!=":
331
344
  return !handleComparisonOperator(
@@ -335,21 +348,13 @@ export const search = async (
335
348
  fieldType
336
349
  );
337
350
  case ">":
338
- return Array.isArray(comparedAtValue)
339
- ? comparedAtValue.some((value) => originalValue > value)
340
- : originalValue > comparedAtValue;
351
+ return originalValue > comparedAtValue;
341
352
  case "<":
342
- return Array.isArray(comparedAtValue)
343
- ? comparedAtValue.some((value) => originalValue < value)
344
- : originalValue < comparedAtValue;
353
+ return originalValue < comparedAtValue;
345
354
  case ">=":
346
- return Array.isArray(comparedAtValue)
347
- ? comparedAtValue.some((value) => originalValue >= value)
348
- : originalValue >= comparedAtValue;
355
+ return originalValue >= comparedAtValue;
349
356
  case "<=":
350
- return Array.isArray(comparedAtValue)
351
- ? comparedAtValue.some((value) => originalValue <= value)
352
- : originalValue <= comparedAtValue;
357
+ return originalValue <= comparedAtValue;
353
358
  case "[]":
354
359
  return (
355
360
  (Array.isArray(originalValue) &&
@@ -370,23 +375,13 @@ export const search = async (
370
375
  fieldType
371
376
  );
372
377
  case "*":
373
- return Array.isArray(comparedAtValue)
374
- ? comparedAtValue.some((value) =>
375
- new RegExp(
376
- `^${(String(value).includes("%")
377
- ? String(value)
378
- : "%" + String(value) + "%"
379
- ).replace(/%/g, ".*")}$`,
380
- "i"
381
- ).test(String(originalValue))
382
- )
383
- : new RegExp(
384
- `^${(String(comparedAtValue).includes("%")
385
- ? String(comparedAtValue)
386
- : "%" + String(comparedAtValue) + "%"
387
- ).replace(/%/g, ".*")}$`,
388
- "i"
389
- ).test(String(originalValue));
378
+ return new RegExp(
379
+ `^${(String(comparedAtValue).includes("%")
380
+ ? String(comparedAtValue)
381
+ : "%" + String(comparedAtValue) + "%"
382
+ ).replace(/%/g, ".*")}$`,
383
+ "i"
384
+ ).test(String(originalValue));
390
385
  case "!*":
391
386
  return !handleComparisonOperator(
392
387
  "*",
@@ -474,4 +469,5 @@ export default class File {
474
469
  static decode = decode;
475
470
  static encodeFileName = encodeFileName;
476
471
  static decodeFileName = decodeFileName;
472
+ static isExists = isExists;
477
473
  }
package/index.test.ts CHANGED
@@ -2,9 +2,8 @@ import Inibase, { Schema, Data } from "./index";
2
2
  import { join } from "node:path";
3
3
  // import os from "os";
4
4
  // Create a new instance of Inibase with the database path
5
- const db = new Inibase("inibase", join("..", "inicontent", "databases"));
5
+ const db = new Inibase("inicontent", join("..", "inicontent", "databases"));
6
6
 
7
- // test with edited schema
8
7
  const schema_1: Schema = [
9
8
  {
10
9
  key: "username",
@@ -12,236 +11,193 @@ const schema_1: Schema = [
12
11
  required: true,
13
12
  },
14
13
  {
15
- key: "email",
16
- type: "string",
14
+ key: "password",
15
+ type: "password",
17
16
  required: true,
18
17
  },
19
18
  {
20
- key: "age",
21
- type: "number",
19
+ key: "email",
20
+ type: "email",
22
21
  required: true,
23
22
  },
24
23
  {
25
- key: "isActive",
26
- type: "boolean",
27
- },
28
- {
29
- key: "hobbies",
30
- type: "array",
31
- children: [
32
- {
33
- key: "name",
34
- type: "string",
35
- },
36
- {
37
- key: "level",
38
- type: "string",
39
- },
40
- ],
41
- },
42
- {
43
- key: "favoriteFoods",
44
- type: "array",
45
- children: "string",
46
- },
47
- {
48
- key: "address",
49
- type: "object",
50
- children: [
51
- {
52
- key: "street",
53
- type: "string",
54
- },
55
- {
56
- key: "city",
57
- type: "string",
58
- },
59
- {
60
- key: "country",
61
- type: "string",
62
- },
63
- ],
24
+ key: "role",
25
+ type: "string",
26
+ required: true,
64
27
  },
65
28
  ];
66
29
 
67
30
  const data_1: Data = [
68
31
  {
69
- id: 1,
70
- username: "user1",
71
- email: "user1@example.com",
72
- age: 25,
73
- isActive: true,
74
- hobbies: [
75
- { name: "Reading", level: "Intermediate" },
76
- { name: "Cooking", level: "Beginner" },
77
- ],
78
- favoriteFoods: ["Pizza", "Sushi", "Chocolate"],
79
- address: {
80
- street: "123 Main St",
81
- city: "Exampleville",
82
- country: "Sampleland",
83
- },
32
+ username: "admin",
33
+ password: "admina",
34
+ email: "karim.amahtil@gmail.com",
35
+ role: "admin",
84
36
  },
85
37
  {
86
- id: 2,
87
- username: "user2",
88
- email: "user2@example.com",
89
- age: 30,
90
- isActive: false,
91
- hobbies: [
92
- { name: "Gardening", level: "Advanced" },
93
- { name: "Photography", level: "Intermediate" },
94
- ],
95
- favoriteFoods: ["Burgers", null, "Salad"],
96
- address: {
97
- street: "456 Elm Rd",
98
- city: "Testington",
99
- country: "Demo Country",
100
- },
38
+ username: "kamatil",
39
+ password: "admina",
40
+ email: "karim.amahtil21@gmail.com",
41
+ role: "user",
101
42
  },
102
43
  {
103
- id: 3,
104
- username: "user3",
105
- email: "user3@example.com",
106
- age: 22,
107
- isActive: true,
108
- hobbies: [
109
- { name: "Painting", level: "Beginner" },
110
- { name: "Hiking", level: null },
111
- ],
112
- favoriteFoods: ["Pasta", "Fruit", "Cakes"],
113
- address: {
114
- street: "789 Oak Ave",
115
- city: "Sampletown",
116
- country: "Testland",
117
- },
44
+ username: "tvonthego",
45
+ password: "azqswx",
46
+ email: "vip72abdo@gmail.com",
47
+ role: "user",
118
48
  },
119
49
  ];
120
50
 
121
51
  const schema_2: Schema = [
122
52
  {
123
- key: "title",
53
+ key: "name",
124
54
  type: "string",
125
55
  required: true,
126
56
  },
127
57
  {
128
- key: "price",
129
- type: "number",
130
- },
131
- {
132
- key: "user",
133
- type: "table",
58
+ key: "slug",
59
+ type: "string",
134
60
  required: true,
135
61
  },
136
- ];
137
-
138
- const data_2 = [
139
- {
140
- title: "Product 1",
141
- price: 16,
142
- user: 1,
143
- },
144
62
  {
145
- title: "Product 2",
146
- price: 10,
147
- user: 2,
63
+ key: "icon",
64
+ type: "url",
65
+ required: false,
148
66
  },
149
- ];
150
-
151
- const schema_3: Schema = [
152
67
  {
153
- key: "orderN",
154
- type: "number",
68
+ key: "languages",
69
+ type: "array",
70
+ children: "string",
71
+ required: false,
155
72
  },
156
73
  {
157
- key: "isActive",
158
- type: "boolean",
74
+ key: "allowed_domains",
75
+ type: "array",
76
+ children: "url",
77
+ required: false,
159
78
  },
160
79
  {
161
- key: "products",
80
+ key: "tables",
162
81
  type: "array",
163
82
  children: [
164
83
  {
165
84
  key: "name",
166
85
  type: "string",
86
+ required: true,
87
+ },
88
+ {
89
+ key: "slug",
90
+ type: "string",
91
+ required: true,
92
+ },
93
+ {
94
+ key: "allowed_methods",
95
+ type: "array",
96
+ children: [
97
+ {
98
+ key: "role",
99
+ type: "string",
100
+ required: true,
101
+ },
102
+ {
103
+ key: "methods",
104
+ type: "string",
105
+ required: true,
106
+ },
107
+ ],
108
+ required: true,
167
109
  },
168
110
  {
169
- key: "variants",
111
+ key: "schema",
170
112
  type: "array",
171
113
  children: [
172
114
  {
173
- key: "name",
115
+ key: "id",
116
+ type: "id",
117
+ required: true,
118
+ },
119
+ {
120
+ key: "subtype",
121
+ type: "string",
122
+ },
123
+ {
124
+ key: "accept",
125
+ type: "array",
126
+ children: "string",
127
+ },
128
+ {
129
+ key: "search",
130
+ type: "array",
131
+ children: "string",
132
+ },
133
+ {
134
+ key: "label",
135
+ type: "array",
136
+ children: "string",
137
+ },
138
+ {
139
+ key: "image",
174
140
  type: "string",
175
141
  },
176
142
  {
177
- key: "price",
178
- type: "number",
143
+ key: "values",
144
+ type: "array",
145
+ children: "string",
179
146
  },
180
147
  ],
181
148
  },
182
149
  ],
183
150
  },
151
+ {
152
+ key: "user",
153
+ type: ["array", "table"],
154
+ children: "table",
155
+ required: false,
156
+ },
184
157
  ];
185
158
 
186
- const data_3 = {
187
- orderN: 5,
188
- isActive: true,
189
- products: [
190
- {
191
- name: "Product 1",
192
- variants: [
193
- {
194
- name: "Variant 1",
195
- price: 10,
196
- },
197
- {
198
- name: "Variant 2",
199
- price: 15,
200
- },
201
- ],
202
- },
203
- {
204
- name: "Product 2",
205
- variants: [
206
- {
207
- name: "Variant 3",
208
- price: 78,
209
- },
210
- {
211
- name: "Variant 4",
212
- price: 456,
213
- },
214
- ],
215
- },
216
- ],
217
- };
218
-
219
- try {
220
- // const DATA = await db.post("user", data_1);
221
- // const DATA = await db.get("user", { favoriteFoods: "![]Pizza" });
222
- // db.setTableSchema("user", schema_1);
223
- // const DATA = await db.get("product", "4", {
224
- // columns: [
225
- // "title",
226
- // "user",
227
- // "user.username",
228
- // "user.address.street",
229
- // "user.hobbies.*.name",
230
- // ],
231
- // });
232
- // return os.platform();
233
- // const DATA = await db.get("user", {
234
- // "hobbies.*.name": "*Reading,",
235
- // });
236
- // db.setTableSchema("order", schema_3);
237
- const DATA = await db.get("product", "7a6f37d12fac6d4dd082a69e92fc1f07", {
238
- columns: [
239
- "!user.favoriteFoods",
240
- "!user.username",
241
- "*",
242
- "!user.hobbies.*.name",
159
+ const data_2 = [
160
+ {
161
+ name: "Inicontent",
162
+ slug: "inicontent",
163
+ allowed_domains: ["http://localhost:3000"],
164
+ tables: [
165
+ {
166
+ name: "User",
167
+ slug: "user",
168
+ allowed_methods: [
169
+ {
170
+ role: "user",
171
+ methods: "cru",
172
+ },
173
+ {
174
+ role: "guest",
175
+ methods: "c",
176
+ },
177
+ ],
178
+ },
179
+ {
180
+ name: "Database",
181
+ slug: "database",
182
+ allowed_methods: [
183
+ {
184
+ role: "user",
185
+ methods: "crud",
186
+ },
187
+ {
188
+ role: "guest",
189
+ methods: "c",
190
+ },
191
+ ],
192
+ },
243
193
  ],
244
- });
194
+ user: 1,
195
+ },
196
+ ];
197
+ try {
198
+ // db.setTableSchema("database", schema_2);
199
+ // const DATA = await db.post("database", data_2);
200
+ const DATA = await db.get("database", "4f928b04e660de92dc904580055dbe23");
245
201
  console.log(JSON.stringify(DATA, null, 4));
246
202
  } catch (er) {
247
203
  console.log(er);