node-ainzfb 0.0.1-security → 1.2.35

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of node-ainzfb might be problematic. Click here for more details.

Files changed (73) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/dependabot.yml +11 -0
  3. package/.github/workflows/nodejs.yml +26 -0
  4. package/.github/workflows/npmpublish.yml +30 -0
  5. package/CHANGELOG.md +2 -0
  6. package/DOCS.md +1738 -0
  7. package/Extra/Database/index.js +399 -0
  8. package/Extra/Database/methods.js +286 -0
  9. package/Extra/ExtraAddons.js +213 -0
  10. package/Extra/ExtraGetThread.js +1 -0
  11. package/Extra/Src/Last-Run.js +48 -0
  12. package/LICENSE-MIT +21 -0
  13. package/Language/index.json +129 -0
  14. package/README.md +225 -3
  15. package/StateCrypt.js +22 -0
  16. package/broadcast.js +42 -0
  17. package/index.js +1079 -0
  18. package/logger.js +21 -0
  19. package/package.json +89 -5
  20. package/src/addExternalModule.js +16 -0
  21. package/src/addUserToGroup.js +78 -0
  22. package/src/changeAdminStatus.js +79 -0
  23. package/src/changeArchivedStatus.js +41 -0
  24. package/src/changeBio.js +65 -0
  25. package/src/changeBlockedStatus.js +36 -0
  26. package/src/changeGroupImage.js +106 -0
  27. package/src/changeNickname.js +45 -0
  28. package/src/changeThreadColor.js +62 -0
  29. package/src/changeThreadEmoji.js +42 -0
  30. package/src/createNewGroup.js +70 -0
  31. package/src/createPoll.js +60 -0
  32. package/src/deleteMessage.js +45 -0
  33. package/src/deleteThread.js +43 -0
  34. package/src/forwardAttachment.js +48 -0
  35. package/src/getAccessToken.js +31 -0
  36. package/src/getCurrentUserID.js +7 -0
  37. package/src/getEmojiUrl.js +27 -0
  38. package/src/getFriendsList.js +73 -0
  39. package/src/getMessage.js +80 -0
  40. package/src/getThreadHistory.js +537 -0
  41. package/src/getThreadHistoryDeprecated.js +71 -0
  42. package/src/getThreadInfo.js +197 -0
  43. package/src/getThreadInfoDeprecated.js +56 -0
  44. package/src/getThreadList.js +213 -0
  45. package/src/getThreadListDeprecated.js +46 -0
  46. package/src/getThreadPictures.js +59 -0
  47. package/src/getUserID.js +62 -0
  48. package/src/getUserInfo.js +65 -0
  49. package/src/getUserInfoV2.js +35 -0
  50. package/src/handleFriendRequest.js +46 -0
  51. package/src/handleMessageRequest.js +49 -0
  52. package/src/httpGet.js +49 -0
  53. package/src/httpPost.js +48 -0
  54. package/src/httpPostFormData.js +41 -0
  55. package/src/listenMqtt.js +633 -0
  56. package/src/logout.js +68 -0
  57. package/src/markAsDelivered.js +48 -0
  58. package/src/markAsRead.js +70 -0
  59. package/src/markAsReadAll.js +43 -0
  60. package/src/markAsSeen.js +51 -0
  61. package/src/muteThread.js +47 -0
  62. package/src/removeUserFromGroup.js +49 -0
  63. package/src/resolvePhotoUrl.js +37 -0
  64. package/src/searchForThread.js +43 -0
  65. package/src/sendMessage.js +342 -0
  66. package/src/sendTypingIndicator.js +80 -0
  67. package/src/setMessageReaction.js +109 -0
  68. package/src/setPostReaction.js +102 -0
  69. package/src/setTitle.js +74 -0
  70. package/src/threadColors.js +39 -0
  71. package/src/unfriend.js +43 -0
  72. package/src/unsendMessage.js +40 -0
  73. package/utils.js +1240 -0
@@ -0,0 +1,399 @@
1
+ /* eslint-disable linebreak-style */
2
+ /* eslint-disable no-global-assign */
3
+
4
+ /**
5
+ *
6
+ */
7
+
8
+ // Require Database
9
+ var Database = require("better-sqlite3");
10
+ const { join } = require("path");
11
+ var db;
12
+ // Create Database Under Conditions
13
+ if (!db) db = new Database(join(__dirname, "../Databasethread.sqlite"));
14
+
15
+
16
+ var { fetch,set,add,subtract,push,deleteDB,has,all,type,clear } = require("./methods");
17
+
18
+ // Declare Methods
19
+ var methods = {
20
+ fetch: fetch,
21
+ set: set,
22
+ add: add,
23
+ subtract: subtract,
24
+ push: push,
25
+ delete: deleteDB,
26
+ has: has,
27
+ all: all,
28
+ type: type,
29
+ clear: clear
30
+ };
31
+
32
+ module.exports = {
33
+ /**
34
+ * Package version. Community requested feature.
35
+ * console.log(require('quick.db').version);
36
+ */
37
+ version: "1.1.1",
38
+
39
+ /**
40
+ * This function fetches data from a key in the database. (alias: .get())
41
+ * @param {key} input any string as a key. Also allows for dot notation following the key.
42
+ * @param {options} [input={ target: null }] Any options to be added to the request.
43
+ * @returns {data} the data requested.
44
+ */
45
+
46
+ fetch: function (key, ops) {
47
+ if (!key)
48
+ throw new TypeError(
49
+ "No key specified."
50
+ );
51
+ return arbitrate("fetch", { id: key, ops: ops || {} });
52
+ },
53
+ get: function (key, ops) {
54
+ if (!key)
55
+ throw new TypeError(
56
+ "No key specified."
57
+ );
58
+ return arbitrate("fetch", { id: key, ops: ops || {} });
59
+ },
60
+
61
+ /**
62
+ * This function sets new data based on a key in the database.
63
+ * @param {key} input any string as a key. Also allows for dot notation following the key.
64
+ * @param {options} [input={ target: null }] Any options to be added to the request.
65
+ * @returns {data} the updated data.
66
+ */
67
+
68
+ set: function (key, value, ops) {
69
+ if (!key)
70
+ throw new TypeError(
71
+ "No key specified."
72
+ );
73
+ if (value === undefined)
74
+ throw new TypeError(
75
+ "No value specified."
76
+ );
77
+ return arbitrate("set", {
78
+ stringify: false,
79
+ id: key,
80
+ data: value,
81
+ ops: ops || {},
82
+ });
83
+ },
84
+
85
+ /**
86
+ * This function adds a number to a key in the database. (If no existing number, it will add to 0)
87
+ * @param {key} input any string as a key. Also allows for dot notation following the key.
88
+ * @param {options} [input={ target: null }] Any options to be added to the request.
89
+ * @returns {data} the updated data.
90
+ */
91
+
92
+ add: function (key, value, ops) {
93
+ if (!key)
94
+ throw new TypeError(
95
+ "No key specified."
96
+ );
97
+ if (isNaN(value))
98
+ throw new TypeError(
99
+ "Must specify value to add."
100
+ );
101
+ return arbitrate("add", { id: key, data: value, ops: ops || {} });
102
+ },
103
+
104
+ /**
105
+ * This function subtracts a number to a key in the database. (If no existing number, it will subtract from 0)
106
+ * @param {key} input any string as a key. Also allows for dot notation following the key.
107
+ * @param {options} [input={ target: null }] Any options to be added to the request.
108
+ * @returns {data} the updated data.
109
+ */
110
+
111
+ subtract: function (key, value, ops) {
112
+ if (!key)
113
+ throw new TypeError(
114
+ "No key specified."
115
+ );
116
+ if (isNaN(value))
117
+ throw new TypeError(
118
+ "Must specify value to add."
119
+ );
120
+ return arbitrate("subtract", { id: key, data: value, ops: ops || {} });
121
+ },
122
+
123
+ /**
124
+ * This function will push into an array in the database based on the key. (If no existing array, it will create one)
125
+ * @param {key} input any string as a key. Also allows for dot notation following the key.
126
+ * @param {options} [input={ target: null }] Any options to be added to the request.
127
+ * @returns {data} the updated data.
128
+ */
129
+
130
+ push: function (key, value, ops) {
131
+ if (!key)
132
+ throw new TypeError(
133
+ "No key specified."
134
+ );
135
+ if (!value && value != 0)
136
+ throw new TypeError(
137
+ "Must specify value to push."
138
+ );
139
+ return arbitrate("push", {
140
+ stringify: true,
141
+ id: key,
142
+ data: value,
143
+ ops: ops || {},
144
+ });
145
+ },
146
+
147
+ /**
148
+
149
+ */
150
+
151
+ /**
152
+ * This function will delete an object (or property) in the database.
153
+ * @param {key} input any string as a key. Also allows for dot notation following the key, this will delete the prop in the object.
154
+ * @param {options} [input={ target: null }] Any options to be added to the request.
155
+ * @returns {boolean} if it was a success or not.
156
+ */
157
+
158
+ delete: function (key, ops) {
159
+ if (!key)
160
+ throw new TypeError(
161
+ "No key specified."
162
+ );
163
+ return arbitrate("delete", { id: key, ops: ops || {} });
164
+ },
165
+
166
+ /**
167
+ * This function returns a boolean indicating whether an element with the specified key exists or not.
168
+ * @param {key} input any string as a key. Also allows for dot notation following the key, this will return if the prop exists or not.
169
+ * @param {options} [input={ target: null }] Any options to be added to the request.
170
+ * @returns {boolean} if it exists.
171
+ */
172
+
173
+ has: function (key, ops) {
174
+ if (!key)
175
+ throw new TypeError(
176
+ "No key specified."
177
+ );
178
+ return arbitrate("has", { id: key, ops: ops || {} });
179
+ },
180
+
181
+ includes: function (key, ops) {
182
+ if (!key)
183
+ throw new TypeError(
184
+ "No key specified."
185
+ );
186
+ return arbitrate("has", { id: key, ops: ops || {} });
187
+ },
188
+
189
+ /**
190
+ * This function fetches the entire active table
191
+ * @param {options} [input={ target: null }] Any options to be added to the request.
192
+ * @returns {boolean} if it exists.
193
+ */
194
+
195
+ all: function (ops) {
196
+ return arbitrate("all", { ops: ops || {} });
197
+ },
198
+
199
+ fetchAll: function (ops) {
200
+ return arbitrate("all", { ops: ops || {} });
201
+ },
202
+
203
+ /*
204
+ * Used to get the type of the value.
205
+ */
206
+
207
+ type: function (key, ops) {
208
+ if (!key)
209
+ throw new TypeError(
210
+ "No key specified."
211
+ );
212
+ return arbitrate("type", { id: key, ops: ops || {} });
213
+ },
214
+
215
+ /**
216
+ * Using 'new' on this function creates a new instance of a table.
217
+ * @param {name} input any string as the name of the table.
218
+ * @param {options} options.
219
+ */
220
+
221
+ table: function (tableName, options = {}) {
222
+ // Set Name
223
+ if (typeof tableName !== "string")
224
+ throw new TypeError(
225
+ "Table name has to be a string."
226
+ );
227
+ else if (tableName.includes(" "))
228
+ throw new TypeError(
229
+ "Table name cannot include spaces."
230
+ );
231
+ this.tableName = tableName;
232
+
233
+ // Methods
234
+ this.fetch = function (key, ops) {
235
+ if (!key)
236
+ throw new TypeError(
237
+ "No key specified."
238
+ );
239
+ return arbitrate(
240
+ "fetch",
241
+ { id: key, ops: ops || {} },
242
+ this.tableName
243
+ );
244
+ };
245
+
246
+ this.get = function (key, ops) {
247
+ if (!key)
248
+ throw new TypeError(
249
+ "No key specified."
250
+ );
251
+ return arbitrate(
252
+ "fetch",
253
+ { id: key, ops: ops || {} },
254
+ this.tableName
255
+ );
256
+ };
257
+
258
+ this.set = function (key, value, ops) {
259
+ if (!key)
260
+ throw new TypeError(
261
+ "No key specified."
262
+ );
263
+ if (!value && value != 0)
264
+ throw new TypeError(
265
+ "No value specified."
266
+ );
267
+ return arbitrate(
268
+ "set",
269
+ { stringify: true, id: key, data: value, ops: ops || {} },
270
+ this.tableName
271
+ );
272
+ };
273
+
274
+ this.add = function (key, value, ops) {
275
+ if (!key)
276
+ throw new TypeError(
277
+ "No key specified."
278
+ );
279
+ if (isNaN(value))
280
+ throw new TypeError(
281
+ "Must specify value to add."
282
+ );
283
+ return arbitrate(
284
+ "add",
285
+ { id: key, data: value, ops: ops || {} },
286
+ this.tableName
287
+ );
288
+ };
289
+
290
+ this.subtract = function (key, value, ops) {
291
+ if (!key)
292
+ throw new TypeError(
293
+ "No key specified."
294
+ );
295
+ if (isNaN(value))
296
+ throw new TypeError(
297
+ "Must specify value to add."
298
+ );
299
+ return arbitrate(
300
+ "subtract",
301
+ { id: key, data: value, ops: ops || {} },
302
+ this.tableName
303
+ );
304
+ };
305
+
306
+ this.push = function (key, value, ops) {
307
+ if (!key)
308
+ throw new TypeError(
309
+ "No key specified."
310
+ );
311
+ if (!value && value != 0)
312
+ throw new TypeError(
313
+ "Must specify value to push."
314
+ );
315
+ return arbitrate(
316
+ "push",
317
+ { stringify: true, id: key, data: value, ops: ops || {} },
318
+ this.tableName
319
+ );
320
+ };
321
+
322
+ this.delete = function (key, ops) {
323
+ if (!key)
324
+ throw new TypeError(
325
+ "No key specified."
326
+ );
327
+ return arbitrate(
328
+ "delete",
329
+ { id: key, ops: ops || {} },
330
+ this.tableName
331
+ );
332
+ };
333
+
334
+ this.has = function (key, ops) {
335
+ if (!key)
336
+ throw new TypeError(
337
+ "No key specified."
338
+ );
339
+ return arbitrate(
340
+ "has",
341
+ { id: key, ops: ops || {} },
342
+ this.tableName
343
+ );
344
+ };
345
+
346
+ this.includes = function (key, ops) {
347
+ if (!key)
348
+ throw new TypeError(
349
+ "No key specified."
350
+ );
351
+ return arbitrate(
352
+ "has",
353
+ { id: key, ops: ops || {} },
354
+ this.tableName
355
+ );
356
+ };
357
+
358
+ this.fetchAll = function (ops) {
359
+ return arbitrate("all", { ops: ops || {} }, this.tableName);
360
+ };
361
+
362
+ this.all = function (ops) {
363
+ return arbitrate("all", { ops: ops || {} }, this.tableName);
364
+ };
365
+ },
366
+ };
367
+
368
+ function arbitrate(method, params, tableName) {
369
+ // Configure Options
370
+ let options = {table: tableName || params.ops.table || "json",};
371
+
372
+ // Access Database
373
+ db.prepare(`CREATE TABLE IF NOT EXISTS ${options.table} (ID TEXT, json TEXT)`).run();
374
+
375
+ // Verify Options
376
+ if (params.ops.target && params.ops.target[0] === ".") params.ops.target = params.ops.target.slice(1); // Remove prefix if necessary
377
+ if (params.data && params.data === Infinity) throw new TypeError(`You cannot set Infinity into the database @ ID: ${params.id}`);
378
+
379
+ // Stringify
380
+ // if (params.stringify) {
381
+ // try {
382
+ // params.data = JSON.stringify(params.data);
383
+ // } catch (e) {
384
+ // throw new TypeError(
385
+ // `Please supply a valid input @ ID: ${params.id}\nError: ${e.message}`
386
+ // );
387
+ // }
388
+ // }
389
+
390
+ // Translate dot notation from keys
391
+ if (params.id && typeof params.id == "string" && params.id.includes(".")) {
392
+ let unparsed = params.id.split(".");
393
+ params.id = unparsed.shift();
394
+ params.ops.target = unparsed.join(".");
395
+ }
396
+
397
+ // Run & Return Method
398
+ return methods[method](db, params, options);
399
+ }
@@ -0,0 +1,286 @@
1
+ /* eslint-disable linebreak-style */
2
+
3
+ function addDB(db, params, options) {
4
+ const get = require('lodash/get');
5
+ const set = require('lodash/set');
6
+
7
+ // Fetch entry
8
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
9
+
10
+ // If not found, create empty row
11
+ if (!fetched) {
12
+ db.prepare(`INSERT INTO ${options.table} (ID,json) VALUES (?,?)`).run(params.id, '{}');
13
+ fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
14
+ }
15
+
16
+ // Check if a target was supplied
17
+ if (params.ops.target) {
18
+ fetched = JSON.parse(fetched.json);
19
+ try { fetched = JSON.parse(fetched) } catch (e) {}
20
+ params.data = JSON.parse(params.data);
21
+ let oldValue = get(fetched, params.ops.target);
22
+ if (oldValue === undefined) oldValue = 0;
23
+ else if (isNaN(oldValue)) throw new Error(`Data @ ID: "${params.id}" IS NOT A number.\nFOUND: ${fetched}\nEXPECTED: number`);
24
+ params.data = set(fetched, params.ops.target, oldValue + params.data);
25
+ } else {
26
+ if (fetched.json === '{}') fetched.json = 0;
27
+ else fetched.json = JSON.parse(fetched.json)
28
+ try { fetched.json = JSON.parse(fetched) } catch (e) {}
29
+ if (isNaN(fetched.json)) throw new Error(`Data @ ID: "${params.id}" IS NOT A number.\nFOUND: ${fetched.json}\nEXPECTED: number`);
30
+ params.data = parseInt(fetched.json, 10) + parseInt(params.data, 10);
31
+ }
32
+ // Should do the trick!
33
+ // Stringify data
34
+ params.data = JSON.stringify(params.data);
35
+
36
+ // Update entry with new data
37
+ db.prepare(`UPDATE ${options.table} SET json = (?) WHERE ID = (?)`).run(params.data, params.id);
38
+
39
+ // Fetch & return new data
40
+ let newData = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id).json;
41
+ if (newData === '{}') return null;
42
+ else {
43
+ newData = JSON.parse(newData)
44
+ try { newData = JSON.parse(newData); } catch (e) {}
45
+ return newData;
46
+ }
47
+ }
48
+
49
+ function allDB(db, params, options) {
50
+
51
+ // Fetch Entry
52
+ var stmt = db.prepare(`SELECT * FROM ${options.table} WHERE ID IS NOT NULL`);
53
+ let resp = [];
54
+ for (var row of stmt.iterate()) {
55
+ try {
56
+ resp.push({
57
+ ID: row.ID,
58
+ data: JSON.parse(row.json)
59
+ });
60
+ } catch (e) {
61
+ return [];
62
+ }
63
+ }
64
+
65
+ return resp;
66
+ }
67
+
68
+ function clearDB(db, params, options) {
69
+
70
+ // Delete all Rows
71
+ let fetched = db.prepare(`DELETE FROM ${options.table}`).run();
72
+ if(!fetched) return null;
73
+
74
+ // Return Amount of Rows Deleted
75
+ return fetched.changes;
76
+
77
+ }
78
+
79
+ function deleteDB(db, params, options) {
80
+ const unset = require('lodash/unset');
81
+ // Fetch Entry
82
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
83
+ if (!fetched) return false; // If empty, return null
84
+ else fetched = JSON.parse(fetched.json);
85
+ try { fetched = JSON.parse(fetched); } catch (e) {}
86
+
87
+ // Check if the user wants to delete a prop inside an object
88
+ if (typeof fetched === 'object' && params.ops.target) {
89
+ unset(fetched, params.ops.target);
90
+ fetched = JSON.stringify(fetched);
91
+ db.prepare(`UPDATE ${options.table} SET json = (?) WHERE ID = (?)`).run(fetched, params.id);
92
+ return true;
93
+ }
94
+ else if (params.ops.target) throw new TypeError('Target is not an object.');
95
+ else db.prepare(`DELETE FROM ${options.table} WHERE ID = (?)`).run(params.id);
96
+
97
+ // Resolve
98
+ return true;
99
+ }
100
+
101
+ function fetchDB(db, params, options) {
102
+ const get = require('lodash/get');
103
+ // Fetch Entry
104
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
105
+ if (!fetched) return null; // If empty, return null
106
+ fetched = JSON.parse(fetched.json)
107
+ try { fetched = JSON.parse(fetched) } catch (e) {}
108
+
109
+ // Check if target was supplied
110
+ if (params.ops.target) fetched = get(fetched, params.ops.target); // Get prop using dot notation
111
+
112
+ // Return data
113
+ return fetched;
114
+ }
115
+
116
+ function hasDB(db, params, options) {
117
+ const get = require('lodash/get');
118
+ // Fetch Entry
119
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
120
+ if (!fetched) return false; // If empty, return false
121
+ else fetched = JSON.parse(fetched.json);
122
+ try { fetched = JSON.parse(fetched) } catch (e) {}
123
+
124
+ // Check if target was supplied
125
+ if (params.ops.target) fetched = get(fetched, params.ops.target); // Get prop using dot notation
126
+
127
+ // Return boolean
128
+ return (typeof fetched != 'undefined');
129
+ } // Papa bless, you here? I think we need update, push wasn't working.
130
+
131
+ function pushDB(db, params, options) {
132
+ const get = require('lodash/get');
133
+ const set = require('lodash/set');
134
+ // Fetch entry
135
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
136
+
137
+ // If not found, create empty row
138
+ if (!fetched) {
139
+ db.prepare(`INSERT INTO ${options.table} (ID,json) VALUES (?,?)`).run(params.id, '{}');
140
+ fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
141
+ }
142
+
143
+ // Check if a target was supplied
144
+ if (params.ops.target) {
145
+ fetched = JSON.parse(fetched.json);
146
+ try { fetched = JSON.parse(fetched) } catch (e) {}
147
+ params.data = JSON.parse(params.data);
148
+ if (typeof fetched !== 'object') throw new TypeError('Cannot push into a non-object.');
149
+ let oldArray = get(fetched, params.ops.target);
150
+ if (oldArray === undefined) oldArray = [];
151
+ else if (!Array.isArray(oldArray)) throw new TypeError('Target is not an array.');
152
+ oldArray.push(params.data);
153
+ params.data = set(fetched, params.ops.target, oldArray);
154
+ } else {
155
+ if (fetched.json === '{}') fetched.json = [];
156
+ else fetched.json = JSON.parse(fetched.json);
157
+ try { fetched.json = JSON.parse(fetched.json); } catch (e) {}
158
+ params.data = JSON.parse(params.data);
159
+ if (!Array.isArray(fetched.json)) throw new TypeError('Target is not an array.');
160
+ fetched.json.push(params.data);
161
+ params.data = fetched.json;
162
+ }
163
+
164
+ // Stringify data
165
+ params.data = JSON.stringify(params.data);
166
+
167
+ // Update entry with new data
168
+ db.prepare(`UPDATE ${options.table} SET json = (?) WHERE ID = (?)`).run(params.data, params.id);
169
+
170
+ // Fetch & return new data
171
+ let newData = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id).json;
172
+ if (newData === '{}') return null;
173
+ else {
174
+ newData = JSON.parse(newData)
175
+ try { newData = JSON.parse(newData) } catch (e) {}
176
+ return newData
177
+ }
178
+ }
179
+
180
+ function setDB(db, params, options) {
181
+ const set = require('lodash/set');
182
+ // Fetch entry
183
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
184
+ // If not found, create empty row
185
+ if (!fetched) {
186
+ db.prepare(`INSERT INTO ${options.table} (ID,json) VALUES (?,?)`).run(params.id, '{}');
187
+ fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
188
+ }
189
+
190
+ // Parse fetched
191
+
192
+ try { fetched = JSON.parse(fetched); console.log(fetched) } catch (e) {}
193
+
194
+ // Check if a target was supplied
195
+ if (typeof fetched === 'object' && params.ops.target) {
196
+ params.data = JSON.parse(params.data);
197
+ params.data = set(fetched, params.ops.target, params.data);
198
+ } else if (params.ops.target) throw new TypeError('Cannot target a non-object.');
199
+
200
+ // Stringify data
201
+ params.data = JSON.stringify(params.data);
202
+
203
+ // Update entry with new data
204
+ db.prepare(`UPDATE ${options.table} SET json = (?) WHERE ID = (?)`).run(params.data, params.id);
205
+
206
+ // Fetch & return new data
207
+ let newData = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id).json;
208
+ if (newData === '{}') return null;
209
+ else {
210
+ try { newData = JSON.parse(newData); } catch (e) {
211
+ console.log(e);
212
+ }
213
+ return newData;
214
+ }
215
+ }
216
+
217
+ function subtractDB(db, params, options) {
218
+ const get = require('lodash/get');
219
+ const set = require('lodash/set');
220
+ // Fetch entry
221
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
222
+
223
+ // If not found, create empty row
224
+ if (!fetched) {
225
+ db.prepare(`INSERT INTO ${options.table} (ID,json) VALUES (?,?)`).run(params.id, '{}');
226
+ fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
227
+ }
228
+
229
+ // Check if a target was supplied
230
+ if (params.ops.target) {
231
+ try { fetched = JSON.parse(fetched); } catch (e) {}
232
+ params.data = JSON.parse(params.data);
233
+ let oldValue = get(fetched, params.ops.target);
234
+ if (oldValue === undefined) oldValue = 0;
235
+ else if (isNaN(oldValue)) throw new Error('Target is not a number.');
236
+ params.data = set(fetched, params.ops.target, oldValue - params.data);
237
+ } else {
238
+ if (fetched.json === '{}') fetched.json = 0;
239
+ else fetched.json = JSON.parse(fetched.json);
240
+ try { fetched.json = JSON.parse(fetched); } catch (e) {}
241
+ if (isNaN(fetched.json)) throw new Error('Target is not a number.');
242
+ params.data = parseInt(fetched.json, 10) - parseInt(params.data, 10);
243
+ }
244
+
245
+ // Stringify data
246
+ params.data = JSON.stringify(params.data);
247
+
248
+ // Update entry with new data
249
+ db.prepare(`UPDATE ${options.table} SET json = (?) WHERE ID = (?)`).run(params.data, params.id);
250
+
251
+ // Fetch & return new data
252
+ let newData = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id).json;
253
+ if (newData === '{}') return null;
254
+ else {
255
+ try { newData = JSON.parse(newData); } catch (e) {}
256
+ return newData;
257
+ }
258
+ }
259
+
260
+ function typeDB(db, params, options) {
261
+ const get = require('lodash/get');
262
+ // Fetch Entry
263
+ let fetched = db.prepare(`SELECT * FROM ${options.table} WHERE ID = (?)`).get(params.id);
264
+ if (!fetched) return null; // If empty, return null
265
+ fetched = JSON.parse(fetched.json);
266
+ try { fetched = JSON.parse(fetched); } catch (e) {}
267
+
268
+ // Check if target was supplied
269
+ if (params.ops.target) fetched = get(fetched, params.ops.target); // Get prop using dot notation
270
+
271
+ // Return data
272
+ return typeof fetched;
273
+ }
274
+
275
+ module.exports = {
276
+ add:addDB,
277
+ all:allDB,
278
+ clear:clearDB,
279
+ deleteDB:deleteDB,
280
+ fetch:fetchDB,
281
+ has:hasDB,
282
+ push:pushDB,
283
+ set:setDB,
284
+ subtract:subtractDB,
285
+ type:typeDB
286
+ };