beanbagdb 0.5.52 → 0.5.54

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.
@@ -0,0 +1,193 @@
1
+
2
+
3
+
4
+ const commands = {
5
+ new: {
6
+ parse: async (instance,parts) => {
7
+ let criteria = {}
8
+ criteria.schema = parts.length==0?"":parts.join("")
9
+ return criteria
10
+ },
11
+ run: async (instance,command) => {
12
+ if (command.criteria.schema==""){
13
+ // return a list of all schemas present in the DB
14
+ let all_schema = await instance.get("schema_list")
15
+ return all_schema
16
+ }else{
17
+ // return the schema object for the given schema if not found throw error
18
+ let schema_obj = await instance.search({"selector":{"schema":"schema","data.name":command.criteria.schema}})
19
+ //console.log(schema_obj)
20
+ if(schema_obj.docs.length==0){
21
+ throw new Error("Schema with this name does not exists")
22
+ }
23
+ return schema_obj.docs[0]
24
+ }
25
+ },
26
+ help: `To create a new record. Format : new/"schema_name(optional)". If no schema name provided, a list of valid schema name is returned`
27
+ },
28
+ open:{
29
+ parse: async (instance,parts) => {
30
+ let criteria = {}
31
+ if (parts.length==0){
32
+ throw new Error("Invalid arguments.open command needs unique id")
33
+ }
34
+ let id_type = parts[0]
35
+ if(id_type=="id"){
36
+ parts.shift()
37
+ criteria["_id"] = parts.join("")
38
+ }else if(id_type=="link"){
39
+ parts.shift()
40
+ criteria["link"] = parts.join("")
41
+ }else if(id_type=="key"){
42
+ parts.shift()
43
+ let text= parts.join()
44
+ let p = text.split(",")
45
+
46
+ p.map(itm=>{
47
+ let p1 = itm.split("=")
48
+ if(p1[0]=="schema"){
49
+ criteria["schema"] = p1[1]
50
+ }else{
51
+ criteria["data"][p1[0]] = p1[1]
52
+ }
53
+ })
54
+
55
+ if(!criteria["schema"]){
56
+ throw new Error("Key requires a schema")
57
+ }
58
+ }else{
59
+ throw new Error("Invalid unique key")
60
+ }
61
+ return criteria
62
+ },
63
+ run: async (instance,command) => {
64
+ try {
65
+ let data = await instance.read(command.criteria,true)
66
+ return data
67
+ } catch (error) {
68
+ throw error
69
+ }
70
+ },
71
+ help: `To open a record using it's unique id. Format : open/"id||link|key"/"value". In case of key field name must be provided as : field1=value1,fields2=value2...`
72
+ },
73
+ tool:{
74
+ parse : async (instance,parts)=>{
75
+ let criteria = {}
76
+ criteria.type = parts.length==0?"info":parts.join("")
77
+ return criteria
78
+ },
79
+ run : async (instance,command)=>{
80
+ let c_type = command.criteria.type
81
+ let data = {}
82
+ if (c_type=="info"){
83
+ // to get all basic info about the database
84
+ let data = {
85
+ meta: instance.metadata(),
86
+ schemas : {},
87
+ logs:[]
88
+ }
89
+ let schemas = await instance.get("schema_list")
90
+ data.schemas = schemas
91
+
92
+ let logs_doc = await instance.read({"schema":"system_settings","data":{name:"system_logs"}})
93
+ //console.log(logs_doc)
94
+ data =logs_doc.doc.data.value
95
+ return data
96
+
97
+ }else if(c_type=="plugins"){
98
+ // to show list of all plugins installed
99
+ // todo later not implemented yet
100
+ }else if(c_type=="settings"){
101
+ // to show the list of all setting docs available
102
+ let search = instance.search({"selector":{"schema":"system_settings"}})
103
+ return {docs:search.docs}
104
+ }
105
+ else if(c_type=="keys"){
106
+ // to show the list of all keys present in the db
107
+ let search = instance.search({"selector":{"schema":"system_keys"}})
108
+ return {docs:search.docs}
109
+ }
110
+ else{
111
+ throw new Error("Invalid tool command")
112
+ }
113
+ },
114
+ }
115
+ };
116
+
117
+ const parse = async (instance, text) => {
118
+ let data = {
119
+ errors: [],
120
+ valid: false,
121
+ name: "",
122
+ criteria: {},
123
+ };
124
+ if (!text) {
125
+ data.errors.push(
126
+ "No text command provided. Format : command_name/parameter"
127
+ );
128
+ }
129
+ let parts = text.split("/");
130
+ if (parts.length == 0) {
131
+ data.errors.push("Invalid text command");
132
+ }
133
+ let command_name = parts[0];
134
+ if (!commands[command_name]) {
135
+ data.errors.push(
136
+ "Invalid command name. Valid : " + Object.keys(commands).join(",")
137
+ );
138
+ }
139
+ data.name = command_name;
140
+ try {
141
+ parts.shift();
142
+ let criteria = await commands[command_name].parse(instance,parts);
143
+ data.criteria = criteria;
144
+ } catch (error) {
145
+ data.errors.push(error.message);
146
+ }
147
+ if (data.errors.length == 0) {
148
+ data.valid = true;
149
+ }
150
+ return data;
151
+ };
152
+
153
+ const run = async (instance, command) => {
154
+ let data = {
155
+ result:{},
156
+ errors:[],
157
+ valid:false
158
+ };
159
+
160
+ if (!command) {
161
+ data.errors.push("No command object provided ");
162
+ }
163
+ if (!command.valid){
164
+ data.errors["Command cannot be run"]
165
+
166
+ }
167
+ if(!commands[command.name]){
168
+ data.errors["Invalid command name"]
169
+ }
170
+
171
+ try {
172
+ let data1 = await commands[command.name].run(instance,command)
173
+ //console.log(data)
174
+ data.result = data1
175
+ } catch (error) {
176
+ data.errors.push(error.message)
177
+ }
178
+ if(data.errors.length==0){
179
+ data.valid = true
180
+ }
181
+ return data
182
+ };
183
+
184
+ const parse_and_run = async(instance, text) => {
185
+ let command = await parse(instance,text)
186
+ console.log(command)
187
+ let command_result = await run(instance,command)
188
+ return command_result
189
+ }
190
+
191
+ export const text_command = {
192
+ parse,run,parse_and_run
193
+ };
@@ -19,7 +19,7 @@ export const schema_schema = {
19
19
  },
20
20
  name: {
21
21
  type: "string",
22
- minLength: 5,
22
+ minLength: 4,
23
23
  maxLength: 50,
24
24
  pattern: "^[a-zA-Z][a-zA-Z0-9_]*$",
25
25
  description:"This is the name of the schema.It cannot be changed later"
@@ -74,16 +74,17 @@ export const schema_schema = {
74
74
  default: false,
75
75
  description:
76
76
  "If set, only a single records with this schema will be allowed to insert in the database",
77
- },
77
+ }
78
78
  },
79
- required :["primary_keys","non_editable_fields","single_record","encrypted_fields"]
79
+ required :["primary_keys","non_editable_fields","encrypted_fields"]
80
80
  },
81
81
  },
82
82
  required: ["name","description","schema", "settings"],
83
83
  },
84
84
  settings: {
85
- primary_key: ["name"],
85
+ primary_keys: ["name"],
86
86
  editable_fields: ["schema", "settings","description"],
87
+ encrypted_fields:[]
87
88
  },
88
89
  };
89
90
 
@@ -160,6 +161,35 @@ export const system_schemas = {
160
161
  single_record:false
161
162
  },
162
163
  }
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
+ // }
163
193
  };
164
194
 
165
195
  // this is not stored in the DB. only for validating the metadata during doc update
package/test/couchdb.js CHANGED
@@ -41,7 +41,7 @@ export class BeanBagDB_CouchDB extends BeanBagDB {
41
41
  }
42
42
  },
43
43
  utils:{
44
- encrypt: (text,encryptionKey)=>{
44
+ encrypt: async (text,encryptionKey)=>{
45
45
  const key = crypto.scryptSync(encryptionKey, 'salt', 32); // Derive a 256-bit key
46
46
  const iv = crypto.randomBytes(16); // Initialization vector
47
47
  const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
@@ -49,7 +49,7 @@ export class BeanBagDB_CouchDB extends BeanBagDB {
49
49
  encrypted += cipher.final('hex');
50
50
  return iv.toString('hex') + ':' + encrypted; // Prepend the IV for later use
51
51
  },
52
- decrypt : (encryptedText, encryptionKey)=>{
52
+ decrypt : async (encryptedText, encryptionKey)=>{
53
53
  const key = crypto.scryptSync(encryptionKey, 'salt', 32); // Derive a 256-bit key
54
54
  const [iv, encrypted] = encryptedText.split(':').map(part => Buffer.from(part, 'hex'));
55
55
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);