beanbagdb 0.5.53 → 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.
@@ -1 +1,23 @@
1
- # How to use plugins
1
+ # How to use plugins
2
+
3
+ ```
4
+ // MyPlugin.js
5
+ const MyPlugin = {
6
+ // This function will be bound to the class instance (passed as 'thisArg')
7
+ on_load: async function(instance) {
8
+ console.log("Plugin loaded with instance:", instance);
9
+ // You can access instance properties and methods here
10
+ instance.someMethod();
11
+ },
12
+
13
+ // Another plugin function
14
+ doSomething: function(instance, arg) {
15
+ console.log("Plugin doing something with arg:", arg);
16
+ // Access the class instance here as 'instance'
17
+ instance.someMethod();
18
+ }
19
+ };
20
+
21
+ export default MyPlugin;
22
+
23
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beanbagdb",
3
- "version": "0.5.53",
3
+ "version": "0.5.54",
4
4
  "description": "A JS library to introduce a schema layer to a No-SQL local database",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
package/src/index.js CHANGED
@@ -548,7 +548,7 @@ export class BeanBagDB {
548
548
  async delete(criteria) {
549
549
  this._check_ready_to_use();
550
550
  let doc = await this.read(criteria)
551
- const delete_blocked = ["schema","setting",""]
551
+ const delete_blocked = ["schema","setting","key"]
552
552
  if (delete_blocked.includes(doc.schema)){
553
553
  throw new Error(`Deletion of ${doc.schema} doc is not support yet.`)
554
554
  }
@@ -597,6 +597,7 @@ export class BeanBagDB {
597
597
  async get(special_doc_type,criteria={}){
598
598
  // this method returns special types of documents such as schema doc, or a blank doc for a given schema and other system related things
599
599
  const fetch_docs = {
600
+ // to return schema object for the given name
600
601
  schema:async (criteria)=>{
601
602
  let schemaSearch = await this.db_api.search({
602
603
  selector: { schema: "schema", "data.name": criteria.name },
@@ -606,6 +607,30 @@ export class BeanBagDB {
606
607
  throw new DocNotFoundError(BeanBagDB.error_codes.schema_not_found);
607
608
  }
608
609
  return schemaSearch.docs[0];
610
+ },
611
+ // schema list
612
+ schema_list:async (criteria)=>{
613
+ let schemaSearch = await this.db_api.search({
614
+ selector: { schema: "schema" },
615
+ });
616
+ // console.log(schemaSearch)
617
+ if (schemaSearch.docs.length == 0) {
618
+ throw new DocNotFoundError(BeanBagDB.error_codes.schema_not_found);
619
+ }else{
620
+ let schemas = []
621
+ schemaSearch.docs.map(doc=>{
622
+ schemas.push({
623
+ name: doc.data.name,
624
+ version: doc.data.version,
625
+ system_defined : doc.data.system_generated,
626
+ description: doc.data.description,
627
+ link: doc.meta.link,
628
+ _id:doc._id
629
+ })
630
+ })
631
+ return schemas
632
+ }
633
+
609
634
  }
610
635
  }
611
636
  if(Object.keys(fetch_docs).includes(special_doc_type)){
@@ -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
+ };
@@ -0,0 +1,55 @@
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
+
23
+ before(async () => {
24
+ let doc_obj = get_pdb_doc("test_database_30", "qwertyuiopaqwsde1254");
25
+ database = new BeanBagDB(doc_obj);
26
+ await database.ready(); // Ensure the database is ready before running tests
27
+ console.log("Ready for more tests...");
28
+ });
29
+
30
+
31
+
32
+ it('successfully loads the plugin', async () => {
33
+ try {
34
+ await database.load_plugin("txtcmd",text_command)
35
+ chai.expect(database.plugins).to.not.be.empty
36
+ } catch (error) {
37
+ console.log(error)
38
+ throw error
39
+ }
40
+ })
41
+
42
+ it('successfully runs the loaded the plugin method', async () => {
43
+ try {
44
+
45
+ let command = await database["txtcmd"].parse("new/system_keys")
46
+ console.log(command)
47
+ assert (1 ==2)
48
+ } catch (error) {
49
+ console.log(error)
50
+ throw error
51
+ }
52
+ })
53
+ });
54
+
55
+
package/test/test1.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { get_pdb_doc } from './pouchdb.js';
3
3
  import { throws, strictEqual } from "assert";
4
4
  import {BeanBagDB} from '../src/index.js';
5
+ import {text_command} from "../src/plugins/text_command.js"
5
6
 
6
7
  (async()=>{
7
8
 
@@ -13,131 +14,149 @@ import {BeanBagDB} from '../src/index.js';
13
14
  // settings: {},
14
15
  // }
15
16
  // ]
16
- let doc_obj = get_pdb_doc("test_database_27","qwertyuiopaqwsde1254")
17
- let database1 = new BeanBagDB(doc_obj);
18
- // await database.ready()
19
- // let a = await database.create("schema",schema_docs_invalid[0])
20
-
21
- const test_schema = {
22
- name:"book",
23
- description:"Test schema 1",
24
- schema: {
25
- $schema: "http://json-schema.org/draft-07/schema#",
26
- type: "object",
27
- properties: {
28
- title: {
29
- type: "string",
30
- minLength: 1,
31
- description: "The title of the book",
32
- },
33
- author: {
34
- type: "string",
35
- minLength: 1,
36
- description: "The author of the book",
37
- },
38
- isbn: {
39
- type: "string",
40
- pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
41
- description: "The ISBN of the book, can be 10 or 13 digits",
42
- },
43
- publicationYear: {
44
- type: "integer",
45
- minimum: 1450,
46
- maximum: 2024,
47
- description:
48
- "The year the book was published (between 1450 and 2024)",
49
- },
50
- genre: {
51
- type: "string",
52
- enum: [
53
- "Fiction",
54
- "Non-Fiction",
55
- "Science",
56
- "History",
57
- "Fantasy",
58
- "Biography",
59
- "Children",
60
- "Mystery",
61
- "Horror",
62
- ],
63
- description: "The genre of the book",
64
- },
65
- language: {
66
- type: "string",
67
- description: "The language of the book",
68
- default: "English",
69
- },
70
- publisher: {
71
- type: "string",
72
- description: "The publisher of the book",
73
- minLength: 1,
74
- },
75
- pages: {
76
- type: "integer",
77
- minimum: 1,
78
- description: "The number of pages in the book",
79
- },
80
- secret: {
81
- type: "string",
82
- description: "Super secret related to the book",
83
- minLength: 1,
84
- },
85
- },
86
- required: ["title", "author", "isbn", "publicationYear", "genre"],
87
- additionalProperties: false,
88
- },
89
- settings : {
90
- primary_keys:['title','author'],
91
- encrypted_fields:['secret'],
92
- non_editable_fields:[],
93
- single_record:false
94
- }
95
- };
96
-
97
-
98
- await database1.ready(); // Ensure the database is ready before running tests
17
+ // let doc_obj = get_pdb_doc("test_database_27","qwertyuiopaqwsde1254")
18
+ // let database1 = new BeanBagDB(doc_obj);
19
+ // // await database.ready()
20
+ // // let a = await database.create("schema",schema_docs_invalid[0])
21
+
22
+ // const test_schema = {
23
+ // name:"book",
24
+ // description:"Test schema 1",
25
+ // schema: {
26
+ // $schema: "http://json-schema.org/draft-07/schema#",
27
+ // type: "object",
28
+ // properties: {
29
+ // title: {
30
+ // type: "string",
31
+ // minLength: 1,
32
+ // description: "The title of the book",
33
+ // },
34
+ // author: {
35
+ // type: "string",
36
+ // minLength: 1,
37
+ // description: "The author of the book",
38
+ // },
39
+ // isbn: {
40
+ // type: "string",
41
+ // pattern: "^(97(8|9))?\\d{9}(\\d|X)$",
42
+ // description: "The ISBN of the book, can be 10 or 13 digits",
43
+ // },
44
+ // publicationYear: {
45
+ // type: "integer",
46
+ // minimum: 1450,
47
+ // maximum: 2024,
48
+ // description:
49
+ // "The year the book was published (between 1450 and 2024)",
50
+ // },
51
+ // genre: {
52
+ // type: "string",
53
+ // enum: [
54
+ // "Fiction",
55
+ // "Non-Fiction",
56
+ // "Science",
57
+ // "History",
58
+ // "Fantasy",
59
+ // "Biography",
60
+ // "Children",
61
+ // "Mystery",
62
+ // "Horror",
63
+ // ],
64
+ // description: "The genre of the book",
65
+ // },
66
+ // language: {
67
+ // type: "string",
68
+ // description: "The language of the book",
69
+ // default: "English",
70
+ // },
71
+ // publisher: {
72
+ // type: "string",
73
+ // description: "The publisher of the book",
74
+ // minLength: 1,
75
+ // },
76
+ // pages: {
77
+ // type: "integer",
78
+ // minimum: 1,
79
+ // description: "The number of pages in the book",
80
+ // },
81
+ // secret: {
82
+ // type: "string",
83
+ // description: "Super secret related to the book",
84
+ // minLength: 1,
85
+ // },
86
+ // },
87
+ // required: ["title", "author", "isbn", "publicationYear", "genre"],
88
+ // additionalProperties: false,
89
+ // },
90
+ // settings : {
91
+ // primary_keys:['title','author'],
92
+ // encrypted_fields:['secret'],
93
+ // non_editable_fields:[],
94
+ // single_record:false
95
+ // }
96
+ // };
97
+
98
+
99
+ // await database1.ready(); // Ensure the database is ready before running tests
99
100
 
100
- try {
101
- //console.log(test_schema)
102
- let a = await database1.create("schema",test_schema)
103
-
104
- } catch (error) {
105
- console.log("error in before")
106
- console.log(error)
107
- }
108
-
109
- const book1 = {
110
- title: "Harry Potter",
111
- author: "J.K. Rowling",
112
- isbn: "9780439139601",
113
- publicationYear: 1999,
114
- genre: "Fantasy",
115
- publisher: "ABC DEF",
116
- secret: "Super secret 1"
117
- };
118
-
119
- let d
120
- try {
121
- d = await database1.create("book", book1,{link:"sample1"});
122
- console.log(d)
123
- let rec = await database1.read({"_id":d._id});
124
- console.log(rec)
125
-
126
- let e = await database1.create("book", {...book1,title:"Something"},{link:"sample2"});
127
- console.log(e)
128
-
129
- } catch (error) {
130
- console.log(error)
131
- throw error
132
- }
133
-
134
-
135
- try {
136
- let s = await database1.search({selector:{}})
137
- console.log(s.docs.length)
138
- //console.log( JSON.stringify(s,null,2))
139
- } catch (error) {
140
- console.log(error)
141
- }
142
-
143
- })()
101
+ // try {
102
+ // //console.log(test_schema)
103
+ // let a = await database1.create("schema",test_schema)
104
+
105
+ // } catch (error) {
106
+ // console.log("error in before")
107
+ // console.log(error)
108
+ // }
109
+
110
+ // const book1 = {
111
+ // title: "Harry Potter",
112
+ // author: "J.K. Rowling",
113
+ // isbn: "9780439139601",
114
+ // publicationYear: 1999,
115
+ // genre: "Fantasy",
116
+ // publisher: "ABC DEF",
117
+ // secret: "Super secret 1"
118
+ // };
119
+
120
+ // let d
121
+ // try {
122
+ // d = await database1.create("book", book1,{link:"sample1"});
123
+ // console.log(d)
124
+ // let rec = await database1.read({"_id":d._id});
125
+ // console.log(rec)
126
+
127
+ // let e = await database1.create("book", {...book1,title:"Something"},{link:"sample2"});
128
+ // console.log(e)
129
+
130
+ // } catch (error) {
131
+ // console.log(error)
132
+ // throw error
133
+ // }
134
+
135
+
136
+ // try {
137
+ // let s = await database1.search({selector:{}})
138
+ // console.log(s.docs.length)
139
+ // //console.log( JSON.stringify(s,null,2))
140
+ // } catch (error) {
141
+ // console.log(error)
142
+ // }
143
+
144
+
145
+ let database; // this is the global db object
146
+ let doc_obj = get_pdb_doc("test_database_40", "qwertyuiopaqwsde1254");
147
+ database = new BeanBagDB(doc_obj);
148
+ await database.ready(); // Ensure the database is ready before running tests
149
+ await database.load_plugin("txtcmd",text_command)
150
+ console.log()
151
+ let command = await database.plugins["txtcmd"].parse_and_run("new/schema")
152
+ console.log(command)
153
+ let command2 = await database.plugins["txtcmd"].parse_and_run("new")
154
+ console.log(command2)
155
+ let command3 = await database.plugins["txtcmd"].parse_and_run("open/link/thunder-kangchenjunga-mango")
156
+ console.log(command3)
157
+ let command4 = await database.plugins["txtcmd"].parse_and_run("tool/info")
158
+ console.log(command4)
159
+ })()
160
+
161
+
162
+