inibase 1.0.0-rc.62 → 1.0.0-rc.64

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/index.d.ts CHANGED
@@ -24,9 +24,9 @@ export interface Options {
24
24
  order?: Record<string, "asc" | "desc">;
25
25
  }
26
26
  export interface Config {
27
- compression: boolean;
28
- cache: boolean;
29
- prepend: boolean;
27
+ compression?: boolean;
28
+ cache?: boolean;
29
+ prepend?: boolean;
30
30
  }
31
31
  export interface TableObject {
32
32
  schema?: Schema;
@@ -64,8 +64,28 @@ export default class Inibase {
64
64
  private throwError;
65
65
  private getFileExtension;
66
66
  private _schemaToIdsPath;
67
+ /**
68
+ * Create a new table inside database, with predefined schema and config
69
+ *
70
+ * @param {string} tableName
71
+ * @param {Schema} [schema]
72
+ * @param {Config} [config]
73
+ */
67
74
  createTable(tableName: string, schema?: Schema, config?: Config): Promise<void>;
75
+ /**
76
+ * Update table schema or config
77
+ *
78
+ * @param {string} tableName
79
+ * @param {Schema} [schema]
80
+ * @param {Config} [config]
81
+ */
68
82
  updateTable(tableName: string, schema?: Schema, config?: Config): Promise<void>;
83
+ /**
84
+ * Get table schema and config
85
+ *
86
+ * @param {string} tableName
87
+ * @return {*} {Promise<TableObject>}
88
+ */
69
89
  getTable(tableName: string): Promise<TableObject>;
70
90
  getTableSchema(tableName: string, encodeIDs?: boolean): Promise<Schema | undefined>;
71
91
  private throwErrorIfTableEmpty;
@@ -81,25 +101,105 @@ export default class Inibase {
81
101
  private getItemsFromSchema;
82
102
  private applyCriteria;
83
103
  private _filterSchemaByColumns;
84
- clearCache(tablePath: string): Promise<void>;
104
+ /**
105
+ * Clear table cache
106
+ *
107
+ * @param {string} tableName
108
+ */
109
+ clearCache(tableName: string): Promise<void>;
110
+ /**
111
+ * Retrieve item(s) from a table
112
+ *
113
+ * @param {string} tableName
114
+ * @param {(string | number | (string | number)[] | Criteria | undefined)} [where]
115
+ * @param {(Options | undefined)} [options]
116
+ * @param {true} [onlyOne]
117
+ * @param {undefined} [onlyLinesNumbers]
118
+ * @param {boolean} [_skipIdColumn]
119
+ * @return {*} {(Promise<Data[] | Data | number[] | null>)}
120
+ */
85
121
  get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: true, onlyLinesNumbers?: undefined, _skipIdColumn?: boolean): Promise<Data | null>;
86
122
  get(tableName: string, where?: string | number | (string | number)[] | Criteria | undefined, options?: Options | undefined, onlyOne?: boolean | undefined, onlyLinesNumbers?: true, _skipIdColumn?: boolean): Promise<number[]>;
123
+ /**
124
+ * Create new item(s) in a table
125
+ *
126
+ * @param {string} tableName
127
+ * @param {(Data | Data[])} data Can be array of objects or a single object
128
+ * @param {Options} [options] Pagination options, useful when the returnPostedData param is true
129
+ * @param {boolean} [returnPostedData] By default function returns void, if you want to get the posted data, set this param to true
130
+ * @return {*} {Promise<Data | Data[] | null | void>}
131
+ */
87
132
  post(tableName: string, data: Data | Data[], options?: Options, returnPostedData?: boolean): Promise<void>;
88
133
  post(tableName: string, data: Data, options: Options | undefined, returnPostedData: true): Promise<Data | null>;
89
134
  post(tableName: string, data: Data[], options: Options | undefined, returnPostedData: true): Promise<Data[] | null>;
135
+ /**
136
+ * Update item(s) in a table
137
+ *
138
+ * @param {string} tableName
139
+ * @param {(Data | Data[])} data
140
+ * @param {(number | string | (number | string)[] | Criteria)} [where]
141
+ * @param {Options} [options]
142
+ * @param {false} [returnUpdatedData]
143
+ * @return {*} {Promise<Data | Data[] | null | undefined | void>}
144
+ */
90
145
  put(tableName: string, data: Data | Data[], where?: number | string | (number | string)[] | Criteria, options?: Options, returnUpdatedData?: false): Promise<void>;
91
146
  put(tableName: string, data: Data, where: number | string | (number | string)[] | Criteria | undefined, options: Options | undefined, returnUpdatedData: true): Promise<Data | null>;
92
147
  put(tableName: string, data: Data[], where: number | string | (number | string)[] | Criteria | undefined, options: Options | undefined, returnUpdatedData: true): Promise<Data[] | null>;
148
+ /**
149
+ * Delete item(s) in a table
150
+ *
151
+ * @param {string} tableName
152
+ * @param {(number | string)} [where]
153
+ * @param {(string | string[])} [_id]
154
+ * @return {*} {(Promise<string | number | (string | number)[] | null>)}
155
+ */
93
156
  delete(tableName: string, where?: number | string, _id?: string | string[]): Promise<string | null>;
94
157
  delete(tableName: string, where?: (number | string)[] | Criteria, _id?: string | string[]): Promise<string[] | null>;
95
158
  delete(tableName: string, where?: number, _id?: string | string[]): Promise<number | null>;
96
159
  delete(tableName: string, where?: number[], _id?: string | string[]): Promise<number[] | null>;
160
+ /**
161
+ * Generate sum of column(s) in a table
162
+ *
163
+ * @param {string} tableName
164
+ * @param {string} columns
165
+ * @param {(number | string | (number | string)[] | Criteria)} [where]
166
+ * @return {*} {Promise<number | Record<string, number>>}
167
+ */
97
168
  sum(tableName: string, columns: string, where?: number | string | (number | string)[] | Criteria): Promise<number>;
98
169
  sum(tableName: string, columns: string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
170
+ /**
171
+ * Generate max of column(s) in a table
172
+ *
173
+ * @param {string} tableName
174
+ * @param {string} columns
175
+ * @param {(number | string | (number | string)[] | Criteria)} [where]
176
+ * @return {*} {Promise<number>}
177
+ */
99
178
  max(tableName: string, columns: string, where?: number | string | (number | string)[] | Criteria): Promise<number>;
100
179
  max(tableName: string, columns: string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
180
+ /**
181
+ * Generate min of column(s) in a table
182
+ *
183
+ * @param {string} tableName
184
+ * @param {string} columns
185
+ * @param {(number | string | (number | string)[] | Criteria)} [where]
186
+ * @return {*} {Promise<number>}
187
+ */
101
188
  min(tableName: string, columns: string, where?: number | string | (number | string)[] | Criteria): Promise<number>;
102
189
  min(tableName: string, columns: string[], where?: number | string | (number | string)[] | Criteria): Promise<Record<string, number>>;
190
+ /**
191
+ * Sort column(s) of a table
192
+ *
193
+ * @param {string} tableName
194
+ * @param {(string
195
+ * | string[]
196
+ * | Record<string, 1 | -1 | "asc" | "ASC" | "desc" | "DESC">)} columns
197
+ * @param {(string | number | (string | number)[] | Criteria)} [where]
198
+ * @param {Options} [options={
199
+ * page: 1,
200
+ * perPage: 15,
201
+ * }]
202
+ */
103
203
  sort(tableName: string, columns: string | string[] | Record<string, 1 | -1 | "asc" | "ASC" | "desc" | "DESC">, where?: string | number | (string | number)[] | Criteria, options?: Options): Promise<any[]>;
104
204
  }
105
205
  export {};
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import "dotenv/config";
2
- import { unlink, rename, mkdir, readdir, open, writeFile, readFile, } from "node:fs/promises";
2
+ import { unlink, rename, mkdir, readdir, writeFile, readFile, } from "node:fs/promises";
3
3
  import { existsSync, appendFileSync, readFileSync } from "node:fs";
4
4
  import { join, parse } from "node:path";
5
5
  import { scryptSync, randomBytes } from "node:crypto";
@@ -81,6 +81,13 @@ export default class Inibase {
81
81
  RETURN[field.id] = `${(prefix ?? "") + field.key}${this.getFileExtension(tableName)}`;
82
82
  return RETURN;
83
83
  };
84
+ /**
85
+ * Create a new table inside database, with predefined schema and config
86
+ *
87
+ * @param {string} tableName
88
+ * @param {Schema} [schema]
89
+ * @param {Config} [config]
90
+ */
84
91
  async createTable(tableName, schema, config) {
85
92
  const tablePath = join(this.databasePath, tableName);
86
93
  if (await File.isExists(tablePath))
@@ -89,43 +96,50 @@ export default class Inibase {
89
96
  await mkdir(join(tablePath, ".cache"));
90
97
  if (config) {
91
98
  if (config.compression)
92
- await open(join(tablePath, ".compression.config"), "w");
99
+ await writeFile(join(tablePath, ".compression.config"), "");
93
100
  if (config.cache)
94
- await open(join(tablePath, ".cache.config"), "w");
101
+ await writeFile(join(tablePath, ".cache.config"), "");
95
102
  if (config.prepend)
96
- await open(join(tablePath, ".prepend.config"), "w");
103
+ await writeFile(join(tablePath, ".prepend.config"), "");
97
104
  }
98
105
  if (schema)
99
106
  await writeFile(join(tablePath, "schema.json"), JSON.stringify(UtilsServer.addIdToSchema(schema, 0, this.salt, false), null, 2));
100
107
  }
108
+ /**
109
+ * Update table schema or config
110
+ *
111
+ * @param {string} tableName
112
+ * @param {Schema} [schema]
113
+ * @param {Config} [config]
114
+ */
101
115
  async updateTable(tableName, schema, config) {
102
116
  const table = await this.getTable(tableName), tablePath = join(this.databasePath, tableName);
103
117
  if (config) {
104
118
  if (config.compression !== undefined) {
105
119
  if (!config.compression && table.config.compression) {
106
120
  try {
107
- await UtilsServer.exec(`gunzip -r ${tablePath}/*.txt.gz 2>/dev/null`);
121
+ await UtilsServer.exec(`gunzip ${tablePath}/*.${this.fileExtension}.gz 2>/dev/null`);
108
122
  await unlink(join(tablePath, ".compression.config"));
109
123
  }
110
124
  catch { }
111
125
  }
112
126
  else if (config.compression && !table.config.compression) {
113
127
  try {
114
- await UtilsServer.exec(`gzip -r ${tablePath}/*.txt 2>/dev/null`);
115
- await open(join(tablePath, ".compression.config"), "w");
128
+ await UtilsServer.exec(`gzip ${tablePath}/*.${this.fileExtension} 2>/dev/null`);
129
+ await writeFile(join(tablePath, ".compression.config"), "");
116
130
  }
117
131
  catch { }
118
132
  }
119
133
  }
120
134
  if (config.cache !== undefined) {
121
135
  if (config.cache && !table.config.cache)
122
- await open(join(tablePath, ".cache.config"), "w");
136
+ await writeFile(join(tablePath, ".cache.config"), "");
123
137
  else if (!config.cache && table.config.cache)
124
138
  await unlink(join(tablePath, ".cache.config"));
125
139
  }
126
140
  if (config.prepend !== undefined) {
127
141
  if (config.prepend && !table.config.prepend)
128
- await open(join(tablePath, ".prepend.config"), "w");
142
+ await writeFile(join(tablePath, ".prepend.config"), "");
129
143
  else if (!config.prepend && table.config.prepend)
130
144
  await unlink(join(tablePath, ".prepend.config"));
131
145
  }
@@ -154,6 +168,12 @@ export default class Inibase {
154
168
  delete this.tables[tableName];
155
169
  }
156
170
  }
171
+ /**
172
+ * Get table schema and config
173
+ *
174
+ * @param {string} tableName
175
+ * @return {*} {Promise<TableObject>}
176
+ */
157
177
  async getTable(tableName) {
158
178
  const tablePath = join(this.databasePath, tableName);
159
179
  if (!(await File.isExists(tablePath)))
@@ -231,7 +251,22 @@ export default class Inibase {
231
251
  throw this.throwError("INVALID_TYPE", [
232
252
  field.key,
233
253
  Array.isArray(field.type) ? field.type.join(", ") : field.type,
234
- typeof data[field.key],
254
+ Utils.detectFieldType(data[field.key], [
255
+ "string",
256
+ "number",
257
+ "boolean",
258
+ "date",
259
+ "email",
260
+ "url",
261
+ "table",
262
+ "object",
263
+ "array",
264
+ "password",
265
+ "html",
266
+ "ip",
267
+ "json",
268
+ "id",
269
+ ]) ?? "undefinedType",
235
270
  ]);
236
271
  if ((field.type === "array" || field.type === "object") &&
237
272
  field.children &&
@@ -746,10 +781,13 @@ export default class Inibase {
746
781
  })
747
782
  .filter((i) => i);
748
783
  }
749
- async clearCache(tablePath) {
750
- await Promise.all((await readdir(join(tablePath, ".cache")))
751
- ?.filter((fileName) => fileName !== `pagination${this.fileExtension}`)
752
- .map(async (file) => unlink(join(tablePath, ".cache", file))));
784
+ /**
785
+ * Clear table cache
786
+ *
787
+ * @param {string} tableName
788
+ */
789
+ async clearCache(tableName) {
790
+ await Promise.all((await readdir(join(this.databasePath, tableName, ".cache"))).map((file) => unlink(join(this.databasePath, tableName, ".cache", file))));
753
791
  }
754
792
  async get(tableName, where, options = {
755
793
  page: 1,
@@ -921,7 +959,7 @@ export default class Inibase {
921
959
  renameList = [];
922
960
  totalItems += Array.isArray(RETURN) ? RETURN.length : 1;
923
961
  if (this.tables[tableName].config.cache)
924
- await this.clearCache(tablePath);
962
+ await this.clearCache(tableName);
925
963
  await writeFile(join(tablePath, ".pagination"), `${lastId},${totalItems}`);
926
964
  if (returnPostedData)
927
965
  return this.get(tableName, this.tables[tableName].config.prepend
@@ -951,6 +989,7 @@ export default class Inibase {
951
989
  if (Utils.isArrayOfObjects(data)) {
952
990
  if (!data.every((item) => Object.hasOwn(item, "id") && Utils.isValidID(item.id)))
953
991
  throw this.throwError("INVALID_ID");
992
+ // TODO: Reduce I/O
954
993
  return this.put(tableName, data, data
955
994
  .filter(({ id }) => id !== undefined)
956
995
  .map(({ id }) => id));
@@ -1019,7 +1058,7 @@ export default class Inibase {
1019
1058
  await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
1020
1059
  renameList = [];
1021
1060
  if (this.tables[tableName].config.cache)
1022
- await this.clearCache(tablePath);
1061
+ await this.clearCache(tableName);
1023
1062
  if (returnUpdatedData)
1024
1063
  return this.get(tableName, where, options, !Array.isArray(where));
1025
1064
  }
@@ -1049,7 +1088,7 @@ export default class Inibase {
1049
1088
  ?.filter((fileName) => fileName.endsWith(".inib"))
1050
1089
  .map(async (file) => unlink(join(tablePath, file))));
1051
1090
  if (this.tables[tableName].config.cache)
1052
- await this.clearCache(tablePath);
1091
+ await this.clearCache(tableName);
1053
1092
  }
1054
1093
  finally {
1055
1094
  await File.unlock(join(tablePath, ".tmp"));
@@ -1071,7 +1110,7 @@ export default class Inibase {
1071
1110
  await Promise.all(files.map(async (file) => renameList.push(await File.remove(join(tablePath, file), where))));
1072
1111
  await Promise.all(renameList.map(async ([tempPath, filePath]) => rename(tempPath, filePath)));
1073
1112
  if (this.tables[tableName].config.cache)
1074
- await this.clearCache(tablePath);
1113
+ await this.clearCache(tableName);
1075
1114
  if (await File.isExists(join(tablePath, ".pagination"))) {
1076
1115
  const [lastId, totalItems] = (await readFile(join(tablePath, ".pagination"), "utf8"))
1077
1116
  .split(",")
@@ -1160,6 +1199,19 @@ export default class Inibase {
1160
1199
  }
1161
1200
  return RETURN;
1162
1201
  }
1202
+ /**
1203
+ * Sort column(s) of a table
1204
+ *
1205
+ * @param {string} tableName
1206
+ * @param {(string
1207
+ * | string[]
1208
+ * | Record<string, 1 | -1 | "asc" | "ASC" | "desc" | "DESC">)} columns
1209
+ * @param {(string | number | (string | number)[] | Criteria)} [where]
1210
+ * @param {Options} [options={
1211
+ * page: 1,
1212
+ * perPage: 15,
1213
+ * }]
1214
+ */
1163
1215
  async sort(tableName, columns, where, options = {
1164
1216
  page: 1,
1165
1217
  perPage: 15,
package/dist/utils.d.ts CHANGED
@@ -169,9 +169,34 @@ export declare function FormatObjectCriteriaValue(value: string, isParentArray?:
169
169
  ComparisonOperator,
170
170
  string | number | boolean | null | (string | number | null)[]
171
171
  ];
172
+ /**
173
+ * Get field from schema
174
+ *
175
+ * @export
176
+ * @param {string} keyPath Support dot notation path
177
+ * @param {Schema} schema
178
+ */
172
179
  export declare function getField(keyPath: string, schema: Schema): Field | null;
180
+ /**
181
+ * Override a schema field, key, type or other properties
182
+ *
183
+ * @export
184
+ * @param {string} keyPath Support dot notation path
185
+ * @param {Schema} schema
186
+ * @param {(Omit<Field, "key" | "type"> & {
187
+ * key?: string;
188
+ * type?: FieldType | FieldType[];
189
+ * })} field
190
+ */
173
191
  export declare function setField(keyPath: string, schema: Schema, field: Omit<Field, "key" | "type"> & {
174
192
  key?: string;
175
193
  type?: FieldType | FieldType[];
176
194
  }): Field | null | undefined;
195
+ /**
196
+ * Remove field from schema
197
+ *
198
+ * @export
199
+ * @param {string} keyPath Support dot notation path
200
+ * @param {Schema} schema
201
+ */
177
202
  export declare function unsetField(keyPath: string, schema: Schema): Field | null | undefined;
package/dist/utils.js CHANGED
@@ -346,6 +346,13 @@ export function FormatObjectCriteriaValue(value, isParentArray = false) {
346
346
  return ["=", value];
347
347
  }
348
348
  }
349
+ /**
350
+ * Get field from schema
351
+ *
352
+ * @export
353
+ * @param {string} keyPath Support dot notation path
354
+ * @param {Schema} schema
355
+ */
349
356
  export function getField(keyPath, schema) {
350
357
  let RETURN = null;
351
358
  const keyPathSplited = keyPath.split(".");
@@ -364,6 +371,17 @@ export function getField(keyPath, schema) {
364
371
  return null;
365
372
  return isArrayOfObjects(RETURN) ? RETURN[0] : RETURN;
366
373
  }
374
+ /**
375
+ * Override a schema field, key, type or other properties
376
+ *
377
+ * @export
378
+ * @param {string} keyPath Support dot notation path
379
+ * @param {Schema} schema
380
+ * @param {(Omit<Field, "key" | "type"> & {
381
+ * key?: string;
382
+ * type?: FieldType | FieldType[];
383
+ * })} field
384
+ */
367
385
  export function setField(keyPath, schema, field) {
368
386
  const keyPathSplited = keyPath.split(".");
369
387
  for (const [index, key] of keyPathSplited.entries()) {
@@ -380,6 +398,13 @@ export function setField(keyPath, schema, field) {
380
398
  schema = foundItem.children;
381
399
  }
382
400
  }
401
+ /**
402
+ * Remove field from schema
403
+ *
404
+ * @export
405
+ * @param {string} keyPath Support dot notation path
406
+ * @param {Schema} schema
407
+ */
383
408
  export function unsetField(keyPath, schema) {
384
409
  const keyPathSplited = keyPath.split(".");
385
410
  let parent = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inibase",
3
- "version": "1.0.0-rc.62",
3
+ "version": "1.0.0-rc.64",
4
4
  "author": {
5
5
  "name": "Karim Amahtil",
6
6
  "email": "karim.amahtil@gmail.com"
@@ -10,7 +10,6 @@
10
10
  "exports": {
11
11
  ".": "./dist/index.js",
12
12
  "./file": "./dist/file.js",
13
- "./config": "./dist/config.js",
14
13
  "./utils": "./dist/utils.js",
15
14
  "./utils.server": "./dist/utils.server.js"
16
15
  },
@@ -63,9 +62,6 @@
63
62
  "utils": [
64
63
  "./dist/utils.d.ts"
65
64
  ],
66
- "config": [
67
- "./dist/config.d.ts"
68
- ],
69
65
  "utils.server": [
70
66
  "./dist/utils.server.d.ts"
71
67
  ]
package/dist/config.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare const isCompressionEnabled: boolean;
2
- export declare const isCacheEnabled: boolean;
3
- export declare const isReverseEnabled: boolean;
package/dist/config.js DELETED
@@ -1,3 +0,0 @@
1
- export const isCompressionEnabled = process.env.INIBASE_COMPRESSION === "true";
2
- export const isCacheEnabled = process.env.INIBASE_CACHE === "true";
3
- export const isReverseEnabled = process.env.INIBASE_REVERSE === "true";