beanbagdb 0.5.53 → 0.5.60

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.
@@ -68,12 +68,6 @@ export const schema_schema = {
68
68
  },
69
69
  maxItems: 50,
70
70
  description:"Once set, all the data in this field will be encrypted before storing it in the database. Encryption key must be provided during the time of BeanBagDB initialization and must be managed by the user as it is NOT stored in the database"
71
- },
72
- single_record: {
73
- type: "boolean",
74
- default: false,
75
- description:
76
- "If set, only a single records with this schema will be allowed to insert in the database",
77
71
  }
78
72
  },
79
73
  required :["primary_keys","non_editable_fields","encrypted_fields"]
@@ -83,7 +77,7 @@ export const schema_schema = {
83
77
  },
84
78
  settings: {
85
79
  primary_keys: ["name"],
86
- editable_fields: ["schema", "settings","description"],
80
+ non_editable_fields:[],
87
81
  encrypted_fields:[]
88
82
  },
89
83
  };
@@ -91,9 +85,9 @@ export const schema_schema = {
91
85
  export const system_schemas = {
92
86
  keys: {
93
87
  system_generated:true,
94
- version:0.5,
88
+ version:0.52,
95
89
  description:"To store user defined key. this can include anything like API tokens etc. There is a special method to fetch this. The values are encrypted",
96
- name: "system_keys",
90
+ name: "system_key",
97
91
  schema: {
98
92
  type: "object",
99
93
  additionalProperties: true,
@@ -123,15 +117,14 @@ export const system_schemas = {
123
117
  settings: {
124
118
  primary_keys: ["name"],
125
119
  encrypted_fields:["value"],
126
- non_editable_fields:[],
127
- single_record: false
120
+ non_editable_fields:[]
128
121
  },
129
122
  },
130
123
  settings: {
131
124
  version:0.5,
132
125
  system_generated:true,
133
126
  description:"The system relies on these settings for proper functioning or enabling optional features.",
134
- name: "system_settings",
127
+ name: "system_setting",
135
128
  schema: {
136
129
  required:["name","value"],
137
130
  type: "object",
@@ -157,39 +150,115 @@ export const system_schemas = {
157
150
  settings: {
158
151
  primary_keys: ["name"],
159
152
  non_editable_fields: ["name"],
160
- encrypted_fields:[],
161
- single_record:false
153
+ encrypted_fields:[]
154
+ },
155
+ },
156
+ edges_constraints:{
157
+ name:"system_edge_constraint",
158
+ system_generated:true,
159
+ version:0.5,
160
+ description: "To define edge constraints for simple directed graph of records.",
161
+ schema:{
162
+ type: "object",
163
+ additionalProperties: true,
164
+ required:["node1","node2","edge_type"],
165
+ properties: {
166
+ node1: {
167
+ type: "string",
168
+ minLength: 1,
169
+ maxLength: 500,
170
+ pattern: "^(\\*|(\\*-[a-zA-Z0-9_-]+)(,[a-zA-Z0-9_-]+)*|[a-zA-Z0-9_-]+(,[a-zA-Z0-9_-]+)*)$"
171
+ },
172
+ node2: {
173
+ type: "string",
174
+ minLength: 1,
175
+ maxLength: 500,
176
+ pattern: "^(\\*|(\\*-[a-zA-Z0-9_-]+)(,[a-zA-Z0-9_-]+)*|[a-zA-Z0-9_-]+(,[a-zA-Z0-9_-]+)*)$"
177
+ },
178
+ name:{
179
+ type: "string",
180
+ minLength: 1,
181
+ maxLength: 500,
182
+ pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
183
+ },
184
+ label:{
185
+ type: "string",
186
+ maxLength: 500,
187
+ },
188
+ note:{
189
+ type: "string",
190
+ maxLength: 5000,
191
+ },
192
+ max_from_node1:{
193
+ type:"number",
194
+ default: -1,
195
+ },
196
+ max_to_node2:{
197
+ type:"number",
198
+ default: -1,
199
+ }
200
+ }
201
+ },
202
+ settings: {
203
+ primary_keys: ["name"],
204
+ non_editable_fields:["name"],
205
+ encrypted_fields:[]
206
+ },
207
+ },
208
+ edges:{
209
+ name:"system_edge",
210
+ system_generated:true,
211
+ version:0.5,
212
+ description: "To define edges in the simple directed graph of records.",
213
+ schema:{
214
+ type: "object",
215
+ additionalProperties: true,
216
+ required:["node1","node2","edge_type"],
217
+ properties: {
218
+ node1: {
219
+ type: "string",
220
+ },
221
+ node2: {
222
+ type: "string",
223
+ },
224
+ edge_name:{
225
+ type: "string",
226
+ }
227
+ }
228
+ },
229
+ settings: {
230
+ primary_keys: ["node1","node2","edge_type"],
231
+ non_editable_fields:["edge_type"],
232
+ encrypted_fields:[]
233
+ },
234
+ },
235
+ media:{
236
+ name:"system_media",
237
+ system_generated:true,
238
+ version:0.5,
239
+ description: "To store images as Base64",
240
+ schema:{
241
+ type: "object",
242
+ additionalProperties: true,
243
+ required:["imageBase64","caption","source"],
244
+ properties: {
245
+ imageBase64: {
246
+ type: "string",
247
+ },
248
+ caption: {
249
+ type: "string",
250
+ },
251
+ source:{
252
+ type: "string",
253
+ }
254
+ }
255
+ },
256
+ settings: {
257
+ primary_keys: ["caption"],
258
+ non_editable_fields:[],
259
+ encrypted_fields:[]
162
260
  },
163
261
  }
164
- // ,
165
- // edges:{
166
- // name:"edges",
167
- // description:"To relate one document to another.Labels can be configured using the db_network setting document.This stores edges of a simple directed graph",
168
- // schema:{
169
- // required:["graph","node1","node2","label"],
170
- // type:"object",
171
- // additionalProperties: false,
172
- // properties : {
173
- // graph:{
174
- // type:"string",
175
- // minLength:3,
176
- // default:"default",
177
- // maxLength:100,
178
- // description:"Name of the graph in which this edge is being added. This is managed by the db_network setting "
179
- // },
180
- // node1:{
181
- // type:"string",
182
- // description:"the source of this directed edge. this must be a valid document id."
183
- // }
184
- // }
185
- // },
186
- // settings :{
187
- // primary_key:["graph","node1","node2","label"],
188
- // non_editable_fields:["node1","node2","graph"],
189
- // encrypted_fields:[],
190
- // single_record:false
191
- // }
192
- // }
193
262
  };
194
263
 
195
264
  // this is not stored in the DB. only for validating the metadata during doc update
@@ -0,0 +1,313 @@
1
+ // to test database operations. assuming the class is initialized successfully
2
+ // to test initialization of the BeanBagDB class
3
+ import { get_pdb_doc } from "./pouchdb.js";
4
+ import assert, { throws, strictEqual, rejects } from "assert";
5
+ import {
6
+ BeanBagDB,
7
+ DocCreationError,
8
+ EncryptionError,
9
+ ValidationError,
10
+ DocNotFoundError,
11
+ DocUpdateError,
12
+ } from "../src/index.js";
13
+
14
+ import * as chai from "chai";
15
+ import chaiAsPromised from "chai-as-promised";
16
+
17
+ chai.use(chaiAsPromised);
18
+
19
+ // Then either:
20
+ const expect = chai.expect;
21
+
22
+ let database; // this is the global db object
23
+
24
+ describe("Edge constraint insertion tests", async () => {
25
+ const constraint_docs_invalid = [
26
+ [
27
+ "error when node1 empty",
28
+ {
29
+ node1: "",
30
+ node2: "*",
31
+ name: "sample",
32
+ label: "Sample",
33
+ },
34
+ ],
35
+ [
36
+ "error when node2 empty ",
37
+ {
38
+ node1: "*",
39
+ node2: "",
40
+ name: "sample",
41
+ label: "Sample",
42
+ },
43
+ ],
44
+ [
45
+ "error when edge name empty",
46
+ {
47
+ node1: "*",
48
+ node2: "*",
49
+ name: "",
50
+ label: "Sample",
51
+ },
52
+ ],
53
+ [
54
+ "error when node 1 invalid 1",
55
+ {
56
+ node1: "*3434",
57
+ node2: "*",
58
+ name: "sample",
59
+ label: "Sample",
60
+ },
61
+ ],
62
+ [
63
+ "error when node 1 invalid 2",
64
+ {
65
+ node1: "1212121 ssd sdsd",
66
+ node2: "*",
67
+ name: "sample",
68
+ label: "Sample",
69
+ },
70
+ ],
71
+ [
72
+ "error when node 1 invalid 3",
73
+ {
74
+ node1: "sample1-sample2",
75
+ node2: "*",
76
+ name: "sample",
77
+ label: "Sample",
78
+ },
79
+ ],
80
+ [
81
+ "error when node 1 invalid 4",
82
+ {
83
+ node1: "*+sample1-sample2",
84
+ node2: "*",
85
+ name: "sample",
86
+ label: "Sample",
87
+ },
88
+ ],
89
+ [
90
+ "error when edge name is invalid",
91
+ {
92
+ node1: "*",
93
+ node2: "*",
94
+ name: "Sample one",
95
+ label: "Sample",
96
+ },
97
+ ],
98
+ ];
99
+
100
+ before(async () => {
101
+ // adding a schema
102
+ let doc_obj = get_pdb_doc("test_database_41", "qwe33rtyuiopaqwsde1254");
103
+ database = new BeanBagDB(doc_obj);
104
+ await database.ready(); // Ensure the database is ready before running tests
105
+ try {
106
+ //console.log(test_schema)
107
+ //let a = await database.create("schema",test_schema)
108
+ //console.log("Ready for more tests...");
109
+ } catch (error) {
110
+ console.log("error in before");
111
+ console.log(error);
112
+ }
113
+ });
114
+
115
+ constraint_docs_invalid.forEach((element, index) => {
116
+ it(`${element[0]}`, async () => {
117
+ await rejects(async () => {
118
+ await database.create("setting_edge_constraint", element[1]);
119
+ }, DocCreationError);
120
+ });
121
+ });
122
+ });
123
+
124
+ describe("Edge insertion test", async () => {
125
+ // it('read docs', async () => {
126
+ // try {
127
+ // let udata = await database3.search({selector:{"schema":"book"}})
128
+ // assert(udata.docs.length==2)
129
+ // } catch (error) {
130
+ // //console.log(error)
131
+ // throw error
132
+ // }
133
+ // })
134
+
135
+ const edge_docs_invalid = [
136
+ [
137
+ "error when invalid node 1",
138
+ {
139
+ node1: "sample",
140
+ node2: "*",
141
+ name: "does not matter",
142
+
143
+ },
144
+ ],
145
+ [
146
+ "error when node 2 invalid ",
147
+ {
148
+ node1: { link: "does_not_exists" },
149
+ node2: "invalid,must be a criteria obj",
150
+ name: "sample",
151
+ },
152
+ ],
153
+
154
+ [
155
+ "error when edge name invalid",
156
+ {
157
+ node1: { link: "sample1" },
158
+ node2: { link: "sample2" },
159
+ name: "sample",
160
+
161
+ },
162
+ ],
163
+ [
164
+ "error when both nodes are same",
165
+ {
166
+ node1: {},
167
+ node2: "*",
168
+ name: "Sample one"
169
+ },
170
+ ],
171
+ ];
172
+
173
+ before(async () => {
174
+ // adding a schema
175
+ let doc_obj = get_pdb_doc("test_database_41", "qwe33rtyuiopaqwsde1254");
176
+ database = new BeanBagDB(doc_obj);
177
+ await database.ready(); // Ensure the database is ready before running tests
178
+ try {
179
+ let schemas = [
180
+ {
181
+ name: "player",
182
+ description:"Player",
183
+ schema: {
184
+ additionalProperties:true,
185
+ type:"object",
186
+ properties: {
187
+ name: {
188
+ type: "string",
189
+ },
190
+ },
191
+ },
192
+ settings: {
193
+ primary_keys: ["name"],
194
+ encrypted_fields: [],
195
+ non_editable_fields: ["name"],
196
+ },
197
+ },
198
+ {
199
+ name: "team",
200
+ description:"Team",
201
+ schema: {
202
+ additionalProperties:true,
203
+ type:"object",
204
+ properties: {
205
+ name: {
206
+ type: "string",
207
+ },
208
+ },
209
+ },
210
+ settings: {
211
+ primary_keys: ["name"],
212
+ encrypted_fields: [],
213
+ non_editable_fields: ["name"],
214
+ },
215
+ },
216
+ {
217
+ name: "match",
218
+ description:"Match",
219
+ schema: {
220
+ type:"object",
221
+ additionalProperties:true,
222
+ properties: {
223
+ name: {
224
+ type: "string",
225
+ },
226
+ },
227
+ },
228
+ settings: {
229
+ primary_keys: ["name"],
230
+ encrypted_fields: [],
231
+ non_editable_fields: ["name"],
232
+ },
233
+ },
234
+ ];
235
+ for (let index = 0; index < schemas.length; index++) {
236
+ try {
237
+ const element = schemas[index];
238
+ await database.create("schema", element);
239
+ } catch (error) {
240
+ console.log("not heeee")
241
+ console.log(error)
242
+ }
243
+
244
+ }
245
+ const records = [
246
+ ["player", { name: "player1" }],
247
+ ["player", { name: "player2" }],
248
+ ["player", { name: "player3" }],
249
+ ["player", { name: "player4" }],
250
+ ["player", { name: "player5" }],
251
+ ["player", { name: "player6" }],
252
+ ["player", { name: "player7" }],
253
+ ["player", { name: "player8" }],
254
+ ["player", { name: "player9" }],
255
+ ["player", { name: "player10" }],
256
+ ["player", { name: "player11" }],
257
+ ["player", { name: "player12" }],
258
+ ["player", { name: "player13" }],
259
+ ["player", { name: "player14" }],
260
+ ["player", { name: "player15" }],
261
+ ["team", { name: "team1" }],
262
+ ["team", { name: "team2" }],
263
+ ["match", { name: "match1" }],
264
+ ["match", { name: "match2" }],
265
+ ["system_edge_constraint",{ name:"part_of",node1:"player",node2:"team", max_from_node1:1, max_to_node2:5 , label:"is part of "}],
266
+ ["system_edge_constraint",{name: "plays",node1:"team",node2:"match",max_from_node1 : 1, max_to_node2: 2 , label:"plays in" }]
267
+ ];
268
+ for (let index = 0; index < records.length; index++) {
269
+ const element = records[index];
270
+ let data1 = element[1];
271
+ await database.create(element[0], data1, { link: data1.name });
272
+ }
273
+ } catch (error) {
274
+ console.log("error in before....");
275
+ console.log(error);
276
+ }
277
+ });
278
+
279
+ edge_docs_invalid.forEach((element, index) => {
280
+ it(`${element[0]}`, async () => {
281
+ await rejects(async () => {
282
+ await database.create("setting_edge", element[1]);
283
+ }, DocCreationError);
284
+ });
285
+ });
286
+
287
+
288
+ let valid_edges = [
289
+ {node1:{link:"player1"},node2:{link:"team1"},edge_name:"part_of"},
290
+ {node1:{link:"player2"},node2:{link:"team1"},edge_name:"part_of"},
291
+ {node1:{link:"player3"},node2:{link:"team1"},edge_name:"part_of"},
292
+ {node1:{link:"player4"},node2:{link:"team1"},edge_name:"part_of"},
293
+ {node1:{link:"player5"},node2:{link:"team1"},edge_name:"part_of"},
294
+ {node1:{link:"player6"},node2:{link:"team2"},edge_name:"part_of"},
295
+ {node1:{link:"player7"},node2:{link:"team2"},edge_name:"part_of"}
296
+ ]
297
+
298
+ valid_edges.forEach((element, index) => {
299
+ it(`adds an edge`, async () => {
300
+ try {
301
+ let edge = await database.create_edge(element.node1,element.node2,element.name)
302
+ console.log(edge)
303
+ } catch (error) {
304
+ console.log(error)
305
+ }
306
+
307
+ });
308
+ });
309
+
310
+
311
+
312
+
313
+ });
@@ -1656,7 +1656,7 @@ describe("Doc search tests", async () => {
1656
1656
  it('all docs', async () => {
1657
1657
  try {
1658
1658
  let udata = await database3.search({selector:{}})
1659
- assert(udata.docs.length==8)
1659
+ assert(udata.docs.length==11)
1660
1660
  } catch (error) {
1661
1661
  //console.log(error)
1662
1662
  throw error
@@ -1676,7 +1676,7 @@ describe("Doc search tests", async () => {
1676
1676
  it('read docs 2', async () => {
1677
1677
  try {
1678
1678
  let udata = await database3.search({selector:{"schema":"schema"}})
1679
- assert(udata.docs.length==4) // schema,book,setting,key
1679
+ assert(udata.docs.length==7) // schema,book,setting,key,edge,edge_constraints
1680
1680
  } catch (error) {
1681
1681
  //console.log(error)
1682
1682
  throw error
@@ -0,0 +1,52 @@
1
+ // to test database operations. assuming the class is initialized successfully
2
+ // to test initialization of the BeanBagDB class
3
+ import { get_pdb_doc } from "./pouchdb.js";
4
+ import assert, { throws, strictEqual, rejects } from "assert";
5
+ import { BeanBagDB, DocCreationError, EncryptionError, ValidationError,DocNotFoundError, DocUpdateError } from "../src/index.js";
6
+
7
+ import {text_command} from "../src/plugins/text_command.js"
8
+
9
+ import * as chai from 'chai';
10
+ import chaiAsPromised from 'chai-as-promised';
11
+
12
+ chai.use(chaiAsPromised);
13
+
14
+ // Then either:
15
+ const expect = chai.expect;
16
+
17
+ let database; // this is the global db object
18
+
19
+
20
+ describe("Testing plugin load", async () => {
21
+
22
+ before(async () => {
23
+ let doc_obj = get_pdb_doc("test_database_30", "qwertyuiopaqwsde1254");
24
+ database = new BeanBagDB(doc_obj);
25
+ await database.ready(); // Ensure the database is ready before running tests
26
+ console.log("Ready for more tests...");
27
+ });
28
+
29
+ it('successfully loads the plugin', async () => {
30
+ try {
31
+ await database.load_plugin("txtcmd",text_command)
32
+ chai.expect(database.plugins).to.not.be.empty
33
+ } catch (error) {
34
+ console.log(error)
35
+ throw error
36
+ }
37
+ })
38
+
39
+ it('successfully runs the loaded the plugin method', async () => {
40
+ try {
41
+ //await database.load_plugin("txtcmd",text_command)
42
+ let command = await database.plugins["txtcmd"].parse("new/system_keys")
43
+ //console.log(command)
44
+ assert (command.valid ==true)
45
+ } catch (error) {
46
+ console.log(error)
47
+ throw error
48
+ }
49
+ })
50
+ });
51
+
52
+