cradova 1.0.0

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.
Files changed (60) hide show
  1. package/LICENSE +201 -0
  2. package/cradova.png +0 -0
  3. package/docs/README.md +0 -0
  4. package/index.d.ts +52 -0
  5. package/index.js +342 -0
  6. package/index.ts +366 -0
  7. package/package.json +36 -0
  8. package/scripts/JsonDB.d.ts +298 -0
  9. package/scripts/JsonDB.js +698 -0
  10. package/scripts/JsonDB.ts +794 -0
  11. package/scripts/Metrics.d.ts +51 -0
  12. package/scripts/Metrics.js +56 -0
  13. package/scripts/Metrics.ts +66 -0
  14. package/scripts/Router.d.ts +12 -0
  15. package/scripts/Router.js +95 -0
  16. package/scripts/Router.ts +105 -0
  17. package/scripts/Screen.d.ts +11 -0
  18. package/scripts/Screen.js +62 -0
  19. package/scripts/Screen.ts +62 -0
  20. package/scripts/animate.d.ts +25 -0
  21. package/scripts/animate.js +47 -0
  22. package/scripts/animate.ts +57 -0
  23. package/scripts/css.d.ts +20 -0
  24. package/scripts/css.js +41 -0
  25. package/scripts/css.ts +46 -0
  26. package/scripts/dispatcher.d.ts +1 -0
  27. package/scripts/dispatcher.js +57 -0
  28. package/scripts/dispatcher.ts +58 -0
  29. package/scripts/file-system.d.ts +2 -0
  30. package/scripts/file-system.js +175 -0
  31. package/scripts/file-system.ts +177 -0
  32. package/scripts/fullscreen.d.ts +4 -0
  33. package/scripts/fullscreen.js +29 -0
  34. package/scripts/fullscreen.ts +30 -0
  35. package/scripts/init.d.ts +2 -0
  36. package/scripts/init.js +17 -0
  37. package/scripts/init.ts +18 -0
  38. package/scripts/localStorage.d.ts +9 -0
  39. package/scripts/localStorage.js +26 -0
  40. package/scripts/localStorage.ts +37 -0
  41. package/scripts/media.d.ts +22 -0
  42. package/scripts/media.js +48 -0
  43. package/scripts/media.ts +51 -0
  44. package/scripts/reuse.ts +74 -0
  45. package/scripts/speaker.d.ts +2 -0
  46. package/scripts/speaker.js +16 -0
  47. package/scripts/speaker.ts +25 -0
  48. package/scripts/store.d.ts +10 -0
  49. package/scripts/store.js +56 -0
  50. package/scripts/store.ts +47 -0
  51. package/scripts/swipe.d.ts +9 -0
  52. package/scripts/swipe.js +113 -0
  53. package/scripts/swipe.ts +129 -0
  54. package/scripts/widget.d.ts +2 -0
  55. package/scripts/widget.js +19 -0
  56. package/scripts/widget.ts +23 -0
  57. package/service-worker.d.ts +2 -0
  58. package/service-worker.js +40 -0
  59. package/service-worker.ts +52 -0
  60. package/tsconfig.json +11 -0
@@ -0,0 +1,794 @@
1
+ /**
2
+ * JSON DB DataBase MIT Licence © 2022
3
+ * ************************************
4
+ * Created by Friday Candour @uiedbooker
5
+ * email > fridaymaxtour@gmail.com
6
+ * github > www.github.com/FridayCandour
7
+ * telegram > @uiedbooker
8
+ * JSONDB @version 1.0.0
9
+ * */
10
+
11
+ export const JSONDBversion = "1.0.0";
12
+ let fs: unknown,
13
+ fileURLToPath,
14
+ isNode = false,
15
+ _dirname: unknown;
16
+ if (!globalThis.localStorage) {
17
+ isNode = true;
18
+ fs = await import("fs");
19
+ const dr = await import("path");
20
+ const fp = await import("url");
21
+ fileURLToPath = fp.fileURLToPath;
22
+ _dirname = dr
23
+ .dirname(fileURLToPath(import.meta.url))
24
+ .split("node_modules")[0];
25
+ }
26
+ const schema = class {
27
+ base_name: string;
28
+ name: string;
29
+ last_index: number;
30
+ columns: string;
31
+ relations: string | null;
32
+ constructor(
33
+ schema_configuration_object: Record<string, string>,
34
+ validators: {
35
+ validateColumns: (arg0: string) => void;
36
+ validateRelations: (arg0: string) => void;
37
+ }
38
+ ) {
39
+ // validations
40
+ if (!schema_configuration_object.columns) {
41
+ throw new Error(
42
+ "JSONDB: can't create an empty table should have some columns"
43
+ );
44
+ }
45
+ validators.validateColumns(schema_configuration_object.columns);
46
+
47
+ const isEmptyObject = function (obj: any) {
48
+ // for checking for empty objects
49
+ for (const name in obj) {
50
+ return false;
51
+ }
52
+ return true;
53
+ };
54
+
55
+ if (
56
+ schema_configuration_object.relations &&
57
+ !isEmptyObject(schema_configuration_object.relations)
58
+ ) {
59
+ validators.validateRelations(schema_configuration_object.relations);
60
+ }
61
+ // assignment
62
+ this.base_name = "";
63
+ this.name = schema_configuration_object.name;
64
+ this.last_index = -1;
65
+ this.columns = schema_configuration_object.columns;
66
+ this.relations = schema_configuration_object.relations || null;
67
+ }
68
+ };
69
+
70
+ class JSONDBTableWrapper {
71
+ put: (name: string, value: any) => Promise<void>;
72
+ get: (name: string) => Promise<unknown>;
73
+ validator: (incoming: { [x: string]: any }, tables: string | any[]) => {};
74
+ self: any;
75
+ keys: any;
76
+ constructor(self: unknown, keys: any) {
77
+ this.put = async (name: string, value: any) => {
78
+ function cb(err: string) {
79
+ if (err) {
80
+ throw new Error(
81
+ "JSONDB: error failed to update entities in database because " + err
82
+ );
83
+ }
84
+ }
85
+ if (isNode) {
86
+ fs.writeFile(name + ".json", JSON.stringify(value), cb);
87
+ } else {
88
+ localStorage.setItem(name, JSON.stringify(value));
89
+ }
90
+ };
91
+ this.get = async (name: any) => {
92
+ return new Promise(function (res, rej) {
93
+ try {
94
+ if (!isNode) {
95
+ res(JSON.parse(localStorage.getItem(name)));
96
+ return;
97
+ }
98
+
99
+ fs.readFile(
100
+ _dirname + "/" + name + ".json",
101
+ { encoding: "utf-8" },
102
+ function (err: string, data: string) {
103
+ if (err) {
104
+ return rej(
105
+ "JSONDB: error failed to retrieve entities from database because " +
106
+ err
107
+ );
108
+ }
109
+ try {
110
+ res(JSON.parse(data));
111
+ } catch (error) {
112
+ try {
113
+ res(JSON.parse(fs.readFileSync(name + ".json", "utf-8")));
114
+ } catch (error) {}
115
+ }
116
+ }
117
+ );
118
+ } catch (error) {}
119
+ });
120
+ };
121
+ this.validator = (
122
+ incoming: { [x: string]: any },
123
+ tables: string | any[]
124
+ ) => {
125
+ // works for type, nulllable and unique validations.
126
+ const outgoing: Record<string, string> = {};
127
+ for (const prop in this.self.columns) {
128
+ if (
129
+ this.self.columns[prop].nullable !== true &&
130
+ !Object.hasOwnProperty.call(incoming, prop)
131
+ ) {
132
+ throw new Error(
133
+ "JSONDB: error failed to validate incoming data because " +
134
+ prop +
135
+ " is required for " +
136
+ this.self.name +
137
+ " Schema"
138
+ );
139
+ }
140
+
141
+ if (
142
+ !this.self.columns[prop].nullable &&
143
+ typeof incoming[prop] !== this.self.columns[prop].type
144
+ ) {
145
+ throw new Error(
146
+ "JSONDB: error failed to validate incoming data because " +
147
+ prop +
148
+ "'s value " +
149
+ incoming[prop] +
150
+ " has got a wrong data type of " +
151
+ typeof incoming[prop] +
152
+ " for " +
153
+ this.self.name +
154
+ " should be " +
155
+ this.self.columns[prop].type +
156
+ " type instead"
157
+ );
158
+ }
159
+
160
+ if (this.self.columns[prop].unique === true) {
161
+ for (let i = 0; i < tables.length; i++) {
162
+ const element = tables[i];
163
+ if (element[prop] === incoming[prop]) {
164
+ throw new Error(
165
+ "JSONDB: error failed to validate incoming data because " +
166
+ prop +
167
+ " is unique for " +
168
+ this.self.name +
169
+ " Schema can't have more than one instance"
170
+ );
171
+ }
172
+ }
173
+ }
174
+
175
+ // cleaning time
176
+ outgoing[prop] = incoming[prop];
177
+ }
178
+ return outgoing;
179
+ };
180
+ this.self = self;
181
+ this.keys = keys;
182
+ }
183
+
184
+ /**
185
+ * Save with relations
186
+ * ---------------------
187
+ * @type .saveWithRelations(target table, schema, schema | schema[]) => Promise(object)
188
+ * @example
189
+ * // single relation
190
+ await PollTable.saveWithRelations(MessageTable, Poll, message);
191
+ // arrays of relations
192
+ await PollTable.saveWithRelations(MessageTable, Poll, allMessages);
193
+ */
194
+ async saveWithRelations(
195
+ table: { self: { name: string | number } },
196
+ incoming: { index: string | number },
197
+ relations: string | any[]
198
+ ) {
199
+ if (!relations) {
200
+ return;
201
+ }
202
+ const db = await this.get(this.self.base_name);
203
+ db.last_access_time = Date();
204
+ if (incoming && typeof incoming.index !== "number") {
205
+ throw new Error("JsonDB: save before saving with relations");
206
+ }
207
+
208
+ db.tables[this.self.name][incoming.index] = incoming;
209
+ if (relations && Array.isArray(relations)) {
210
+ for (let i = 0; i < relations.length; i++) {
211
+ if (db.Entities[this.self.name].relations[table.self.name]) {
212
+ if (
213
+ db.Entities[this.self.name].relations[table.self.name].type ===
214
+ "many"
215
+ ) {
216
+ db.tables[this.self.name][incoming.index].relations[
217
+ table.self.name
218
+ ] = !db.tables[this.self.name][incoming.index].relations[
219
+ table.self.name
220
+ ]
221
+ ? [relations[i]]
222
+ : [
223
+ ...db.tables[this.self.name][incoming.index].relations[
224
+ table.self.name
225
+ ],
226
+ relations[i],
227
+ ];
228
+ } else {
229
+ db.tables[this.self.name][incoming.index].relations[
230
+ table.self.name
231
+ ] = relations[i];
232
+ }
233
+ }
234
+ }
235
+ } else {
236
+ if (relations) {
237
+ if (db.Entities[this.self.name].relations[table.self.name]) {
238
+ if (
239
+ db.Entities[this.self.name].relations[table.self.name].type ===
240
+ "many"
241
+ ) {
242
+ db.tables[this.self.name][incoming.index].relations[
243
+ table.self.name
244
+ ] = !db.tables[this.self.name][incoming.index].relations[
245
+ table.self.name
246
+ ]
247
+ ? [relations]
248
+ : [
249
+ ...db.tables[this.self.name][incoming.index].relations[
250
+ table.self.name
251
+ ],
252
+ relations,
253
+ ];
254
+ } else {
255
+ db.tables[this.self.name][incoming.index].relations[
256
+ table.self.name
257
+ ] = relations;
258
+ }
259
+ }
260
+ }
261
+ }
262
+ await this.put(this.self.base_name, db);
263
+ return db.tables[this.self.name][incoming.index];
264
+ }
265
+ /**
266
+ * Save table into a Jsondb instance
267
+ * -----------------------------
268
+ * @type .save(schema)=> Promise(object)
269
+ * @example
270
+ await PollTable.save(poll)
271
+ */
272
+ async save(incoming: { index: number; relations: {} }) {
273
+ // db.tables[this.self.name] = db.tables[this.self.name].sort(
274
+ // (a, b) => a.index - b.index
275
+ // );
276
+ const db = await this.get(this.self.base_name);
277
+ db.last_access_time = Date();
278
+ if (typeof incoming.index !== "number") {
279
+ incoming = this.validator(incoming, db.tables[this.self.name]);
280
+ if (this.self.relations && !incoming.relations) {
281
+ incoming.relations = {};
282
+ }
283
+
284
+ db.Entities[this.self.name].last_index += 1;
285
+ incoming.index = db.Entities[this.self.name].last_index;
286
+ db.tables[this.self.name].push(incoming);
287
+ } else {
288
+ db.tables[this.self.name][incoming.index] = incoming;
289
+ }
290
+ await this.put(this.self.base_name, db);
291
+ return incoming;
292
+ }
293
+ /**
294
+ * Save table into a Jsondb instance
295
+ * -----------------------------
296
+ * @type .remove(schema)=> Promise(object)
297
+ * @example
298
+ await PollTable.remove(poll)
299
+ */
300
+ async remove(entity: { index: string | number }) {
301
+ const db = await this.get(this.self.base_name);
302
+ db.last_access_time = Date();
303
+ // db.tables[this.self.name].splice(entity.index, 1);
304
+ db.tables[this.self.name][entity.index] = null;
305
+ await this.put(this.self.base_name, db);
306
+ }
307
+ /**
308
+ * Save table into a Jsondb instance
309
+ * -----------------------------
310
+ * @type .count(schema)=> Promise(number)
311
+ * @example
312
+ await PollTable.count(poll)
313
+ */
314
+ async count() {
315
+ const db = await this.get(this.self.base_name);
316
+ db.last_access_time = Date();
317
+ return db.tables[this.self.name].length;
318
+ }
319
+ /**
320
+ * Save table into a Jsondb instance
321
+ * -----------------------------
322
+ * @type .getAll()=> Promise(object[])
323
+ * @example
324
+ await PollTable.getAll()
325
+ */
326
+ async getAll() {
327
+ const db = await this.get(this.self.base_name);
328
+ db.last_access_time = Date();
329
+ return db.tables[this.self.name];
330
+ }
331
+ /**
332
+ * get entities with any of the values specifiled from a Jsondb instance
333
+ * -----------------------------
334
+ * @type .getWhereAny({prop: value}, number | undefind)=> Promise(object)
335
+ * @example
336
+ await PollTable.getWhereAny({name: "friday", age: 121, class: "senior"}) // gets all
337
+ await PollTable.getWhereAny({email: "fridaymaxtour@gmail.com"}, 2) // gets 2 if they are up to two
338
+ */
339
+ async getWhereAny(
340
+ props: { [s: string]: unknown } | ArrayLike<unknown>,
341
+ number: number
342
+ ) {
343
+ const results = [];
344
+ let all;
345
+ const db = await this.get(this.self.base_name);
346
+ db.last_access_time = Date();
347
+ all = db.tables[this.self.name];
348
+ for (let i = 0; i < all.length; i++) {
349
+ const element = all[i];
350
+ for (const [k, v] of Object.entries(props)) {
351
+ if (element[k] && element[k] === v) {
352
+ results.push(element);
353
+ if (typeof number === "number" && results.length === number) {
354
+ return results;
355
+ }
356
+ }
357
+ }
358
+ }
359
+ return results;
360
+ }
361
+
362
+ /**
363
+ * get entities with the given prop of type "string" where the values specifiled is included
364
+ * -----------------------------
365
+ * @type .getWhereAnyPropsIncludes({prop: value}, number | undefind)=> Promise(object)
366
+ *
367
+ * @example prop must be type string!
368
+ *
369
+ await PollTable.getWhereAnyPropsIncludes({name: "fri"}) // gets all
370
+ await PollTable.getWhereAnyPropsIncludes({name: "fri"}, 2) // gets 2 if they are up to two
371
+ */
372
+ async getWhereAnyPropsIncludes(
373
+ props: { [s: string]: unknown } | ArrayLike<unknown>,
374
+ number: number
375
+ ) {
376
+ const results = [];
377
+ let all;
378
+ const db = await this.get(this.self.base_name);
379
+ db.last_access_time = Date();
380
+ all = db.tables[this.self.name];
381
+ for (let i = 0; i < all.length; i++) {
382
+ const element = all[i];
383
+ for (const [k, v] of Object.entries(props)) {
384
+ if (element[k] && typeof v === "string" && element[k].includes(v)) {
385
+ results.push(element);
386
+ if (typeof number === "number" && results.length === number) {
387
+ return results;
388
+ }
389
+ }
390
+ }
391
+ }
392
+ return results;
393
+ }
394
+
395
+ /**
396
+ * get an entity with the values specifiled from a Jsondb instance
397
+ * -----------------------------
398
+ * @type .getOne({prop: value})=> Promise(object)
399
+ * @example
400
+
401
+ await PollTable.getOne({email: "fridaymaxtour@gamail.com"}) // gets one
402
+
403
+ */
404
+ async getOne(props: { [s: string]: unknown } | ArrayLike<unknown>) {
405
+ let results = null;
406
+ const db = await this.get(this.self.base_name);
407
+ db.last_access_time = Date();
408
+ const all = db.tables[this.self.name];
409
+ for (let i = 0; i < all.length; i++) {
410
+ const element = all[i];
411
+ for (const [k, v] of Object.entries(props)) {
412
+ if (element[k] && element[k] === v) {
413
+ results = element;
414
+ break;
415
+ }
416
+ }
417
+ }
418
+ return results;
419
+ }
420
+ }
421
+
422
+ const JSONDBConnection = class {
423
+ Entities: any;
424
+ keys: any;
425
+ constructor(Entities: any, keys?: any) {
426
+ this.Entities = Entities;
427
+ this.keys = keys;
428
+ }
429
+
430
+ /**
431
+ * Get a table from JSONDB
432
+ *------------------------
433
+ * @example
434
+ *
435
+ *
436
+ const details = {
437
+ password: "password",
438
+ username: "jsondb_username",
439
+ };
440
+ // getting connection instance into JSONDB
441
+ const connection = await database.createJSONDBConnection(details);
442
+ // getting a table
443
+ const MessageTable = connection.getTable("Message");
444
+ * */
445
+ getTable(table_name: string) {
446
+ for (const [tableName, table] of Object.entries(this.Entities)) {
447
+ if (table_name === tableName) {
448
+ return new JSONDBTableWrapper(table, this.keys);
449
+ }
450
+ }
451
+ }
452
+ };
453
+
454
+ /**
455
+ * Create a new JSONDB object
456
+ *------------------------
457
+ * @class
458
+
459
+ * const database = new JSONDB()
460
+ *
461
+ * Creates a new JSONDB object
462
+ *
463
+ * .
464
+ * */
465
+
466
+ class JSONDB {
467
+ DB_NAME: string;
468
+ username: string;
469
+ encrypted: boolean;
470
+ initialised: boolean;
471
+ time_created: string;
472
+ version: string;
473
+ last_access_time: string;
474
+ visuality: string;
475
+ Entities: {};
476
+ tables: {};
477
+ password: string;
478
+ constructor() {
479
+ this.DB_NAME = "";
480
+ this.username = "";
481
+ this.encrypted = false;
482
+ this.initialised = false;
483
+ this.time_created = Date();
484
+ this.version = JSONDBversion;
485
+ this.last_access_time = "";
486
+ this.visuality = "";
487
+ this.Entities = {};
488
+ this.tables = {};
489
+ this.password = "";
490
+ }
491
+ async getDB(name: string) {
492
+ return new Promise(function (res, rej) {
493
+ if (!isNode) {
494
+ res(JSON.parse(localStorage.getItem(name)));
495
+ return;
496
+ }
497
+
498
+ try {
499
+ fs.readFile(
500
+ _dirname + "/" + name + ".json",
501
+ { encoding: "utf-8" },
502
+ function (err: any, data: string) {
503
+ if (err) {
504
+ return rej(err);
505
+ }
506
+ try {
507
+ res(JSON.parse(data));
508
+ } catch (error) {
509
+ try {
510
+ res(JSON.parse(fs.readFileSync(name + ".json", "utf-8")));
511
+ } catch (error) {}
512
+ }
513
+ }
514
+ );
515
+ } catch (error) {}
516
+ });
517
+ }
518
+
519
+ /**
520
+ * Schema constructor for Jsondb
521
+ * -----------------------------
522
+ *
523
+ * name @type string
524
+ *
525
+ * columns @type object {
526
+ *
527
+ * type > @type any of number > string > boolean > blob and must be specified
528
+ *
529
+ * nullable @type bolean true > false default false
530
+ *
531
+ * unique @type bolean true > false default false
532
+ *
533
+ * }
534
+ *
535
+ * relations @type object {
536
+ *
537
+ * target: entity schema @type object,
538
+ *
539
+ * attachment_name: @type string,
540
+ *
541
+ * type : @type string should be "many" or "one"
542
+ *
543
+ * }
544
+ *
545
+ *
546
+ *
547
+ * @example
548
+ *
549
+ * const MessageSchema = database.schema({
550
+ name: "Message",
551
+ columns: {
552
+ vote: {
553
+ type: "number",
554
+ },
555
+ time: {
556
+ type: "string",
557
+ nullable: true,
558
+ },
559
+ value: {
560
+ type: "string",
561
+ },
562
+ },
563
+ });
564
+ *
565
+ * const PollSchema = new JSONDB.schema({
566
+ name: "Poll",
567
+ columns: {
568
+ value: {
569
+ type: "varchar",
570
+ },
571
+ },
572
+ relations: {
573
+ Message: {
574
+ target: Message,
575
+ type: "many-to-one",
576
+ },
577
+ },
578
+ });
579
+ */
580
+
581
+ schema(schema_configuration_object: Record<string, string>) {
582
+ return new schema(schema_configuration_object, {
583
+ validateColumns: this.validateColumns,
584
+ validateRelations: this.validateRelations,
585
+ });
586
+ }
587
+ /**
588
+ * Create a new JSONDB instance
589
+ *------------------------
590
+ * @example
591
+ * // creates a JSONDB object
592
+ * const Database = new JSONDB()
593
+ * // database configuration object
594
+ * const config = {
595
+ DB_NAME: "my db",
596
+ password: "password",
597
+ username: "jsondb_username",
598
+ encrypted: false,
599
+ }
600
+ // Creates a new JSONDB instance
601
+ * Database.init(config)
602
+ * */
603
+ init(config: {
604
+ name: string;
605
+ password: string;
606
+ username: string;
607
+ encrypted: boolean;
608
+ }) {
609
+ console.log(`\x1B[32m JSONDB version ${JSONDBversion} \x1B[39m`);
610
+ this.initialised = true;
611
+ this.DB_NAME = config.name;
612
+ this.password = config.password || "";
613
+ this.username = config.username || "";
614
+ this.encrypted = config.encrypted || false;
615
+ this.time_created = Date();
616
+ this.tables = {};
617
+ try {
618
+ let wasThere;
619
+ if (isNode) {
620
+ wasThere = fs.readFileSync(config.name + ".json", "utf-8");
621
+ } else {
622
+ wasThere = localStorage.getItem(config.name);
623
+ }
624
+ if (wasThere) {
625
+ return;
626
+ }
627
+ } catch (error) {}
628
+ if (!config.password) {
629
+ throw new Error("JSONDB: error password is empty ");
630
+ }
631
+ if (!config.username) {
632
+ throw new Error("JSONDB: error username is empty ");
633
+ }
634
+
635
+ function cb(err: string) {
636
+ if (err) {
637
+ throw new Error(
638
+ "JSONDB: error failed to create database because " + err
639
+ );
640
+ }
641
+ }
642
+ if (isNode) {
643
+ fs.writeFile(config.name + ".json", JSON.stringify(this), cb);
644
+ } else {
645
+ let db = JSON.stringify(this);
646
+ localStorage.setItem(config.name, db);
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Create secure connection a Jsondb instance
652
+ * -----------------------------
653
+ * @example
654
+ *
655
+ * const details = {
656
+ password: "password",
657
+ username: "jsondb_username",
658
+ };
659
+ const connection = await database.createJSONDBConnection(details);
660
+ */
661
+
662
+ async createJSONDBConnection(details: { username: any; password: any }) {
663
+ if (!this.initialised) {
664
+ throw new Error("JSONDB: you haven't create a JSONDB instance yet");
665
+ }
666
+ if (
667
+ details.username !== this.username ||
668
+ details.password !== this.password
669
+ ) {
670
+ throw new Error("JSONDB: Access Denied");
671
+ }
672
+ const connection = await this.getDB(this.DB_NAME);
673
+ connection.last_access_time = Date();
674
+
675
+ return new JSONDBConnection(connection.Entities);
676
+ }
677
+ validateRelations(relations: { [s: string]: unknown } | ArrayLike<unknown>) {
678
+ const types = ["many", "one"];
679
+ for (const [relation, value] of Object.entries(relations)) {
680
+ if (typeof value.target !== "object") {
681
+ throw new Error(
682
+ "JSONDB: wrong relationship target type given " +
683
+ value.target +
684
+ " should be object only"
685
+ );
686
+ }
687
+ if (!types.includes(value.type)) {
688
+ throw new Error(
689
+ "JSONDB: wrong relationship type given " +
690
+ value.type +
691
+ " should be many or one"
692
+ );
693
+ }
694
+ if (value.cascade && typeof value.cascade !== "boolean") {
695
+ throw new Error(
696
+ "JSONDB: wrong cascade value given " +
697
+ value.cascade +
698
+ " should be true or false"
699
+ );
700
+ }
701
+ }
702
+ }
703
+ validateColumns(columns: { [s: string]: unknown } | ArrayLike<unknown>) {
704
+ const types = ["number", "string", "boolean", "blob"];
705
+ for (const [column, value] of Object.entries(columns)) {
706
+ if (column) {
707
+ if (!types.includes(value.type)) {
708
+ throw new Error(
709
+ "JSONDB: wrong data type given " +
710
+ value.type +
711
+ " only number, string, boolean and blob are accepted"
712
+ );
713
+ }
714
+ if (value.unique && typeof value.unique !== "boolean") {
715
+ throw new Error(
716
+ "JSONDB: wrong unique value given " +
717
+ value.unique +
718
+ " should be true or false"
719
+ );
720
+ }
721
+ if (value.nullable && typeof value.nullable !== "boolean") {
722
+ throw new Error(
723
+ "JSONDB: wrong nullable value given " +
724
+ value.nullable +
725
+ " should be true or false"
726
+ );
727
+ }
728
+ }
729
+ }
730
+ }
731
+
732
+ /**
733
+ * Assemble Entities into Jsondb
734
+ * -----------------------------
735
+ * @example
736
+ *
737
+ * const MessageSchema = database.schema({
738
+ name: "Message",
739
+ columns: {
740
+ vote: {
741
+ type: "number",
742
+ },
743
+ time: {
744
+ type: "string",
745
+ nullable: true,
746
+ },
747
+ value: {
748
+ type: "string",
749
+ },
750
+ },
751
+ });
752
+
753
+ database.assemble([MessageSchema]);
754
+ *
755
+ */
756
+
757
+ assemble(allEntities: string | any[]) {
758
+ if (!this.initialised) {
759
+ throw new Error("JSONDB: you haven't create a JSONDB instance yet");
760
+ }
761
+ try {
762
+ const wasThere = fs.readFileSync(this.DB_NAME + ".json", "utf-8");
763
+ if (wasThere) {
764
+ return;
765
+ }
766
+ } catch (error) {}
767
+ if (!Array.isArray(allEntities) || typeof allEntities[0] !== "object") {
768
+ throw new Error("JSONDB: invalid entity array list, can't be assembled");
769
+ }
770
+ for (let i = 0; i < allEntities.length; i++) {
771
+ this.Entities[allEntities[i].name] = allEntities[i];
772
+ this.Entities[allEntities[i].name].base_name = this.DB_NAME;
773
+ this.tables[allEntities[i].name] = [];
774
+ }
775
+ function cb(err: string) {
776
+ if (err) {
777
+ throw new Error(
778
+ "JSONDB: error failed to assemble entities into database because " +
779
+ err
780
+ );
781
+ }
782
+ }
783
+ if (isNode) {
784
+ fs.writeFile(this.DB_NAME + ".json", JSON.stringify(this), cb);
785
+ } else {
786
+ localStorage.setItem(this.DB_NAME, JSON.stringify(this));
787
+ }
788
+ }
789
+ }
790
+
791
+ /**
792
+ * @exports
793
+ */
794
+ export default JSONDB;