beanbagdb 0.5.80 → 0.6.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beanbagdb",
3
- "version": "0.5.80",
3
+ "version": "0.6.1",
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
@@ -85,6 +85,68 @@ export class BeanBagDB {
85
85
  //////////////////// Setup methods /////////////////////////////////////
86
86
  ////////////////////////////////////////////////////////////////////////
87
87
 
88
+ /**
89
+ * This is the list of methods that are compatible with JSON-REST API. Each command either has no params or takes just one json param as input
90
+ */
91
+ static rest_enabled = {
92
+ "ready":{
93
+ use: "Makes the database ready to use"
94
+ },
95
+ "metadata":{
96
+ use: "Returns metadata related to the current BeanBagDB instance "
97
+ },
98
+ "initialize_app":{
99
+ use:"To install/initialize an external app",
100
+ input: "{...app_data}"
101
+ },
102
+ "update_indexes":{
103
+ use:"Updates the indexes in the database for better searching"
104
+ },
105
+ "create":{
106
+ input:"{schema,data,meta}",
107
+ use:"Creates a new doc"
108
+
109
+ },
110
+ "read":{
111
+ input:"{criteria,include_schema:false}",
112
+ use:"Returns a doc. 3 ways to search for a doc : by _id, by link or by the primary key of the schema "
113
+ },
114
+ "update":{
115
+ input:"{criteria,updates}",
116
+ use:"Updates a document"
117
+ },
118
+ "delete":{
119
+ input:"{criteria}",
120
+ use:"Deletes a doc"
121
+ },
122
+ "search":{
123
+ input:"{criteria:{selector:{...}}}",
124
+ use:"To search in the database"
125
+ },
126
+ "get":{
127
+ input:"{type,criteria}",
128
+ use:"Returns special types of documents "
129
+ },
130
+ "create_edge":{
131
+ input:"{node1:{..criteria},node2:{..criteria},edge_name,edge_label}",
132
+ use:"Creates a new edge in the system's simple directed graph "
133
+ },
134
+ "util_get_now_unix_timestamp":{
135
+ use:"Returns the current UNIX timestamp"
136
+ },
137
+ "util_validate_data":{
138
+ input:"{schema:{},data:{}}",
139
+ use:"Validate the given data against the given schema and returns errors/validated doc"
140
+ },
141
+ "util_validate_schema_object":{
142
+ input:"{...schema_object...}",
143
+ use:"Validated the schema document without inserting it in the DB"
144
+
145
+ },
146
+ "util_generate_random_link":{
147
+ use:"Returns a random link"
148
+ }
149
+ }
88
150
  /**
89
151
  * Database object metadata
90
152
  * @typedef {Object} DBMetaData
@@ -162,8 +224,8 @@ export class BeanBagDB {
162
224
  // this works on its own but is usually called by ready automatically if required
163
225
  // check for schema_scehma : if yes, check if latest and upgrade if required, if no create a new schema doc
164
226
  try {
165
- let app_data = await this.initialize_db(sys_sch.default_app)
166
- console.log(app_data)
227
+ let app_data = await this.initialize_app(sys_sch.default_app)
228
+ // console.log(app_data)
167
229
  this.meta.beanbagdb_version_db = this._version;
168
230
  this.active = true;
169
231
  return app_data
@@ -175,14 +237,23 @@ export class BeanBagDB {
175
237
 
176
238
  }
177
239
 
178
- async initialize_db(app_data){
179
- // app_data : meta(name,description), schemas[] , default_records:[]
180
- // TODO check if add_data is valid
240
+ /**
241
+ * Install/Updates an app in the database.
242
+ * This should be called before using any
243
+ * @param {Object} app_data
244
+ */
245
+ async initialize_app(app_data_input){
181
246
  // calculate the app_version
247
+ if(!app_data_input){throw new Error("app_data_input is required")}
248
+ let app_data = this.util_validate_data({schema:sys_sch.app_data_schema,data:app_data_input})
182
249
  let latest_version = 0
183
- app_data.schemas.map(sch=>{latest_version = latest_version + sch.version})
250
+ app_data.schemas.map(sch=>{
251
+ latest_version = latest_version + sch.version
252
+ // update the source of schemas to the app
253
+ sch["settings"]["install_source"] = `app:${app_data.app_id}`
254
+ })
184
255
  app_data.records.map(sch=>{latest_version = latest_version + sch.version})
185
-
256
+
186
257
 
187
258
  // check if app setting record exists
188
259
  let version_search = await this.db_api.search({
@@ -191,6 +262,7 @@ export class BeanBagDB {
191
262
 
192
263
  let update_required = true
193
264
  let doc
265
+
194
266
  if (version_search.docs.length > 0) {
195
267
  doc = version_search.docs[0];
196
268
  if(doc["data"]["value"]["version"] == latest_version){
@@ -212,7 +284,7 @@ export class BeanBagDB {
212
284
  steps.push(`checking.${schema_name}`)
213
285
  try {
214
286
  // console.log(schema_name)
215
- let schema1 = await this.get("schema",{name:schema_name})
287
+ let schema1 = await this.get({type:"schema",criteria:{name:schema_name}})
216
288
  if (schema1["data"]["version"] != schema_data.version) {
217
289
  steps.push(`old.${schema_name}.v.${schema1["data"]["version"]}`);
218
290
  let full_doc = await this.db_api.get(schema1["_id"]);
@@ -257,7 +329,7 @@ export class BeanBagDB {
257
329
  const record_title = app_data.records[index]["title"]
258
330
  steps.push(`checking.records.${record_title}`)
259
331
  try {
260
- let new_doc = await this.create(schema_name,schema_data,app_data.records[index]["meta"])
332
+ let new_doc = await this.create({schema:schema_name,data:schema_data,meta:app_data.records[index]["meta"]})
261
333
  steps.push(`doc.${record_title}.created`)
262
334
  } catch (error) {
263
335
  if(!(error instanceof DocCreationError)){
@@ -266,10 +338,11 @@ export class BeanBagDB {
266
338
  }
267
339
  }
268
340
 
269
- let app_doc = { ... app_data.meta, version: latest_version}
341
+ let app_doc = { ... app_data.meta,app_id: app_data.app_id ,version: latest_version}
270
342
  try {
271
343
  // modify the app setting doc
272
- await this.modify_setting(app_data.meta.name,app_doc,"update")
344
+ // console.log(app_doc,)
345
+ await this.modify_setting(app_data.app_id,app_doc,"update")
273
346
 
274
347
  // add a new log
275
348
  let new_log_doc = this._get_blank_doc("system_log")
@@ -316,20 +389,28 @@ export class BeanBagDB {
316
389
  * This method validates the input data and schema before inserting a new document into the database.
317
390
  *
318
391
  * @async
319
- * @param {string} schema - The schema name for the document, e.g., "contact".
320
- * @param {object} data - The document data, e.g., { "name": "", "mobile": "", ... }.
321
- * @param {object} [meta={}] - Optional metadata associated with the document.
322
- * @param {object} [settings={}] - Optional settings that may affect document creation behavior.
392
+
393
+ * @param {object} input - The document details, e.g.,{ schema:"name",data: { "name": "", "mobile": "", ... }}.
394
+ * @param {string} [input.schema] - The schema name for the document, e.g., "contact".
395
+ * @param {object} [input.data={}] - the data for the document.
396
+ * @param {object} [input.meta={}] - Optional metadata associated with the document.
323
397
  * @returns {Promise<{id: string}>} - A promise that resolves with the newly inserted document's ID.
324
398
  * @throws {Error} - Throws an error if insertion checks fail or if there is an issue with the database operation.
325
399
  */
326
- async create(schema, data, meta = {}, settings = {}) {
400
+ async create(input) {
327
401
  this._check_ready_to_use();
328
- if(!schema){throw new DocCreationError(`No schema provided`)}
329
- if(schema=="setting_edge"){throw new DocCreationError("This type of record can only be created through the create_edge api")}
330
- if(Object.keys(data).length==0){throw new DocCreationError(`No data provided`)}
402
+
403
+ let v_errors = []
404
+ if(!input.schema){v_errors.push("schema is required")}
405
+ if(!input.data){v_errors.push("data is required")}
406
+ if(v_errors.length>0){
407
+ throw new DocCreationError(`${v_errors.join(",")}.`)
408
+ }
409
+
410
+ if(input.schema=="setting_edge"){throw new DocCreationError("This type of record can only be created through the create_edge api")}
411
+ if(Object.keys(input.data).length==0){throw new DocCreationError(`No data provided`)}
331
412
  try {
332
- let doc_obj = await this._insert_pre_checks(schema, data,meta, settings);
413
+ let doc_obj = await this._insert_pre_checks(input.schema, input.data,input?.meta||{}, input?.settings||{});
333
414
  let new_rec = await this.db_api.insert(doc_obj);
334
415
  return {_id:new_rec["id"],_rev : new_rec["rev"] ,...doc_obj};
335
416
  } catch (error) {
@@ -352,15 +433,14 @@ export class BeanBagDB {
352
433
  * @param {string} [criteria.link] - A unique link identifier for the document.
353
434
  * @param {string} [criteria.schema] - The schema name used when searching by primary keys.
354
435
  * @param {Object} [criteria.data] - Data object containing the schema's primary keys for search.
355
- *
356
- * @param {boolean} [include_schema=false] - Whether to include the schema object in the returned result.
436
+ * @param {string} [criteria.include_schema] - Whether to include the schema object in the returned result.
357
437
  *
358
438
  * @returns {Promise<Object>} - Returns an object with the document (`doc`) and optionally the schema (`schema`).
359
439
  *
360
440
  * @throws {DocNotFoundError} If no document is found for the given criteria.
361
441
  * @throws {ValidationError} If invalid search criteria are provided.
362
442
  */
363
- async read(criteria, include_schema = false) {
443
+ async read(criteria) {
364
444
  // todo : decrypt doc
365
445
  this._check_ready_to_use()
366
446
  let obj = { doc: null }
@@ -376,7 +456,7 @@ export class BeanBagDB {
376
456
  if (linkSearch.docs.length == 0) {throw new DocNotFoundError(BeanBagDB.error_codes.doc_not_found)}
377
457
  obj.doc = linkSearch.docs[0];
378
458
  } else if (criteria.hasOwnProperty("schema") & criteria.hasOwnProperty("data")) {
379
- data_schema = await this.get("schema",{"name":criteria.schema})
459
+ data_schema = await this.get({type:"schema",criteria:{"name":criteria.schema}})
380
460
  let A = data_schema["data"]["settings"]["primary_keys"];
381
461
  let search_criteria = { schema: criteria.schema };
382
462
  A.forEach((itm) => {
@@ -392,11 +472,14 @@ export class BeanBagDB {
392
472
  throw new ValidationError(`Invalid criteria to read a document. Valid ways : {"schema":"schema_name","data":{...primary key}} or {"_id":""} or {"link":""} `)
393
473
  }
394
474
  if (!data_schema){
395
- data_schema = await this.get("schema",{"name":obj.doc.schema})
475
+ data_schema = await this.get({type:"schema",criteria:{"name":obj.doc.schema}})
396
476
  }
397
- if(include_schema) {obj.schema = data_schema["data"]}
477
+
478
+ if(criteria.include_schema) {obj.schema = data_schema["data"]}
479
+
398
480
  // decrypt the document
399
481
  obj.doc = await this._decrypt_doc(data_schema["data"], obj.doc)
482
+
400
483
  return obj;
401
484
  }
402
485
 
@@ -413,11 +496,12 @@ export class BeanBagDB {
413
496
  * - Yes, but a validation check ensures that primary key policies are not violated before the update is applied.
414
497
  *
415
498
  *
416
- * @param {Object} doc_search_criteria - The criteria used to search for the document (e.g., {"_id": "document_id"}, {"link": "some_link"}, {"schema": "schema_name", "data": {primary_key_fields}}).
417
- * @param {String} rev_id - The document's revision ID (`_rev`) used for version control and conflict detection.
418
- * @param {Object} updates - The updated values for the document, structured as `{data: {}, meta: {}}`. Only the fields to be updated need to be provided.
419
- * @param {String} [update_source="api"] - Identifies the source of the update (default: "api").
420
- * @param {Boolean} [save_conflict=true] - If `true`, conflicting updates will be saved separately in case of revision mismatches.
499
+ * @param {Object} params - Object to fetch and update data
500
+ * @param {Object} [params.criteria] - The criteria used to search for the document (e.g., {"_id": "document_id"}, {"link": "some_link"}, {"schema": "schema_name", "data": {primary_key_fields}}).
501
+ * @param {Object} [params.updates] - The updated values for the document, structured as `{data: {}, meta: {}}`. Only the fields to be updated need to be provided.
502
+ * @param {String} [params.rev_id] - The document's revision ID (`_rev`) used for version control and conflict detection.
503
+ * @param {String} [params.update_source="api"] - Identifies the source of the update (default: "api").
504
+ * @param {Boolean} [params.save_conflict=true] - If `true`, conflicting updates will be saved separately in case of revision mismatches.
421
505
  *
422
506
  * **Behavior**:
423
507
  * - Retrieves the document based on the provided search criteria.
@@ -436,11 +520,24 @@ export class BeanBagDB {
436
520
  * @throws {DocUpdateError} - If a document with conflicting primary keys already exists.
437
521
  * @throws {ValidationError} - If the provided data or metadata is invalid according to the schema.
438
522
  */
439
- async update(doc_search_criteria, updates, rev_id="", update_source = "api", save_conflict = true) {
523
+ async update(params) {
524
+
440
525
  this._check_ready_to_use();
526
+
527
+ const {
528
+ criteria,
529
+ updates,
530
+ rev_id = "",
531
+ update_source = "api",
532
+ save_conflict = true
533
+ } = params;
534
+
535
+ if(!criteria){throw new DocUpdateError("Doc search criteria not provided")}
536
+ if(!updates){throw new DocUpdateError("No updates provided")}
537
+
441
538
  // making a big assumption here : primary key fields cannot be edited
442
539
  // so updating the doc will not generate primary key conflicts
443
- let req_data = await this.read(doc_search_criteria, true);
540
+ let req_data = await this.read({...criteria, include_schema: true});
444
541
  let schema = req_data.schema;
445
542
  let full_doc = req_data.doc;
446
543
  // @TODO fix this : what to do if the rev id does not match
@@ -467,7 +564,7 @@ export class BeanBagDB {
467
564
  // todo : what if additionalField are allowed ??
468
565
  let updated_data = { ...full_doc.data, ...allowed_updates };
469
566
 
470
- updated_data = this.util_validate_data(schema.schema, updated_data);
567
+ updated_data = this.util_validate_data({schema:schema.schema,data: updated_data});
471
568
 
472
569
  // primary key check if multiple records can be created
473
570
  if (schema.settings["primary_keys"].length > 0) {
@@ -494,7 +591,7 @@ export class BeanBagDB {
494
591
  let m_sch = sys_sch.editable_metadata_schema;
495
592
  let editable_fields = Object.keys(m_sch["properties"]);
496
593
  let allowed_meta = this.util_filter_object(updates.meta, editable_fields);
497
- allowed_meta = this.util_validate_data(m_sch, allowed_meta);
594
+ allowed_meta = this.util_validate_data({schema:m_sch, data:allowed_meta});
498
595
  // if update has a link ,then check if it already exists
499
596
  if (allowed_meta.link){
500
597
  let search = await this.search({ selector: {"meta.link":allowed_meta.link} })
@@ -525,50 +622,7 @@ export class BeanBagDB {
525
622
  }
526
623
 
527
624
 
528
- /**
529
- * Check if the setting with the given name exists. New record created if not found. If found data is updated based on the updated_mode and the data type of the existing data
530
- * If existing value is an array, and update_mode is append "value" is appended to the current value array.
531
- * if existing value is an object, update_mode "append" will update fields that exists in the new object,
532
- * for both data types, new value is replaced in update_mode : "replace"
533
- * @param {string} name The name of the setting
534
- * @param {object} value Value to be modified
535
- * @param {string} mode
536
- */
537
- async modify_setting(name,value,update_mode){
538
- if(!name||!value||!update_mode){
539
- throw new DocUpdateError("All 3 inputs (setting name, value and update_mode) are required")
540
- }
541
- let doc_search = await this.db_api.search({
542
- selector: { schema: "system_setting", "data.name": name },
543
- });
544
-
545
- if (!["append", "update"].includes(update_mode)) {
546
- throw new DocUpdateError("Invalid update_mode");
547
- }
548
625
 
549
- if (doc_search.docs.length > 0) {
550
- // doc already exists,
551
- let doc = { ...doc_search.docs[0] };
552
- if (Array.isArray(value)) {
553
- doc.data.value = update_mode === "append" ? [...doc.data.value, value] : value; // "update" mode replaces the value
554
- } else {
555
- doc.data.value = update_mode === "append" ? { ...doc.data.value, ...value } : value; // "update" mode replaces the value
556
- }
557
- // finally update it
558
- doc["meta"]["updated_on"] = this.util_get_now_unix_timestamp();
559
- // caution : db api is being used directly
560
- await this.db_api.update(doc);
561
- return doc;
562
-
563
- } else {
564
- // doc does not exists, generate a new one
565
- let new_log_doc = this._get_blank_doc("system_setting")
566
- new_log_doc.data = {value, name}
567
- await this.db_api.insert(new_log_doc);
568
-
569
-
570
- }
571
- }
572
626
 
573
627
  /**
574
628
  * Deletes a document from the database by its ID.
@@ -580,7 +634,7 @@ export class BeanBagDB {
580
634
  async delete(criteria) {
581
635
  this._check_ready_to_use();
582
636
  let doc = await this.read(criteria)
583
- const delete_blocked = ["schema","setting","key"]
637
+ const delete_blocked = ["schema","system_setting","system_log"]
584
638
  if (delete_blocked.includes(doc.schema)){
585
639
  throw new Error(`Deletion of ${doc.schema} doc is not support yet.`)
586
640
  }
@@ -616,9 +670,11 @@ export class BeanBagDB {
616
670
  * for a given schema. It handles system-related data and throws errors for invalid document types
617
671
  * or if the document is not found.
618
672
  *
619
- * @param {String} special_doc_type - The type of special document to fetch. Supported types include:
673
+ * @param {Object} [input={}] - Criteria used to search for the special document.
674
+
675
+ * @param {String} input.type - The type of special document to fetch. Supported types include:
620
676
  * - 'schema': Retrieves a schema document based on the criteria provided.
621
- * @param {Object} [criteria={}] - Criteria used to search for the special document.
677
+ * @param {Object} [input.criteria={}] - Criteria used to search for the special document.
622
678
  * For example, to search for a schema, the criteria should include the name.
623
679
  *
624
680
  * @throws {ValidationError} Throws if the `special_doc_type` is not recognized.
@@ -626,7 +682,8 @@ export class BeanBagDB {
626
682
  *
627
683
  * @returns {Object} The fetched special document based on the type and criteria.
628
684
  */
629
- async get(special_doc_type,criteria={}){
685
+ async get(input){
686
+
630
687
  // this method returns special types of documents such as schema doc, or a blank doc for a given schema and other system related things
631
688
  const fetch_docs = {
632
689
  // to return schema object for the given name
@@ -666,14 +723,19 @@ export class BeanBagDB {
666
723
 
667
724
  }
668
725
  }
669
- if(Object.keys(fetch_docs).includes(special_doc_type)){
670
- let data = await fetch_docs[special_doc_type](criteria)
726
+ if(!input.type){throw new ValidationError("No type provided. Must be: "+Object.keys(fetch_docs).join(","))}
727
+ if(Object.keys(fetch_docs).includes(input.type)){
728
+ let data = await fetch_docs[input.type](input?.criteria||{})
671
729
  return data
672
730
  }else{
673
- throw new ValidationError("Invalid special doc type. Must be : "+Object.keys(fetch_docs).join(","))
731
+ throw new ValidationError("Invalid name. Must be : "+Object.keys(fetch_docs).join(","))
674
732
  }
675
733
  }
676
734
 
735
+
736
+ //////////////////// methods for special use , requires to be called using the class (rather than the rest api)
737
+
738
+
677
739
  /**
678
740
  * To load a plugin in the current BeanBagDB instance.
679
741
  * Plug_module has to be loaded manually first. It must export an object containing fields: `actions` and `schema`.
@@ -705,6 +767,51 @@ export class BeanBagDB {
705
767
  // }
706
768
  }
707
769
 
770
+ /**
771
+ * Check if the setting with the given name exists. New record created if not found. If found data is updated based on the updated_mode and the data type of the existing data
772
+ * If existing value is an array, and update_mode is append "value" is appended to the current value array.
773
+ * if existing value is an object, update_mode "append" will update fields that exists in the new object,
774
+ * for both data types, new value is replaced in update_mode : "replace"
775
+ * @param {string} name The name of the setting
776
+ * @param {object} value Value to be modified
777
+ * @param {string} mode
778
+ */
779
+ async modify_setting(name,value,update_mode){
780
+ if(!name||!value||!update_mode){
781
+ throw new DocUpdateError("All 3 inputs (setting name, value and update_mode) are required")
782
+ }
783
+ let doc_search = await this.db_api.search({
784
+ selector: { schema: "system_setting", "data.name": name },
785
+ });
786
+
787
+ if (!["append", "update"].includes(update_mode)) {
788
+ throw new DocUpdateError("Invalid update_mode");
789
+ }
790
+
791
+ if (doc_search.docs.length > 0) {
792
+ // doc already exists,
793
+ let doc = { ...doc_search.docs[0] };
794
+ if (Array.isArray(value)) {
795
+ doc.data.value = update_mode === "append" ? [...doc.data.value, value] : value; // "update" mode replaces the value
796
+ } else {
797
+ doc.data.value = update_mode === "append" ? { ...doc.data.value, ...value } : value; // "update" mode replaces the value
798
+ }
799
+ // finally update it
800
+ doc["meta"]["updated_on"] = this.util_get_now_unix_timestamp();
801
+ // caution : db api is being used directly
802
+ await this.db_api.update(doc);
803
+ return doc;
804
+
805
+ } else {
806
+ // doc does not exists, generate a new one
807
+ let new_log_doc = this._get_blank_doc("system_setting")
808
+ new_log_doc.data = {value, name}
809
+ await this.db_api.insert(new_log_doc);
810
+
811
+
812
+ }
813
+ }
814
+
708
815
  ///////////////////////////////////////////////////////////
709
816
  //////////////// simple directed graph ////////////////////////
710
817
  //////////////////////////////////////////////////////////
@@ -717,7 +824,8 @@ export class BeanBagDB {
717
824
  * @param {*} edge_label
718
825
  * @returns {Object}
719
826
  */
720
- async create_edge(node1,node2,edge_name,edge_label=""){
827
+ async create_edge(input){
828
+ const {node1,node2,edge_name,edge_label=""} = input
721
829
  this._check_ready_to_use();
722
830
  if(!edge_name){throw new ValidationError("edge_name required")}
723
831
  if(Object.keys(node1)==0){throw new ValidationError("node1 required")}
@@ -762,7 +870,7 @@ async create_edge(node1,node2,edge_name,edge_label=""){
762
870
  }
763
871
 
764
872
  if(errors.length==0){
765
- let edge = await this.create("system_edge",{node1: node1id , node2: node1id ,edge_name:edge_name })
873
+ let edge = await this.create({schema:"system_edge",data:{node1: node1id , node2: node1id ,edge_name:edge_name }})
766
874
  return edge
767
875
  }else{
768
876
  throw new RelationError(errors)
@@ -771,8 +879,8 @@ async create_edge(node1,node2,edge_name,edge_label=""){
771
879
  } catch (error) {
772
880
  if(error instanceof DocNotFoundError){
773
881
  let doc = {node1:"*",node2:"*",name:edge_name,label:edge_label}
774
- let new_doc = await this.create("system_edge_constraint",doc)
775
- let edge = await this.create("system_edge",{node1: n1.doc._id,node2: n2.doc._id,edge_name:edge_name })
882
+ let new_doc = await this.create({schema:"system_edge_constraint",data:doc})
883
+ let edge = await this.create({schema:"system_edge",data:{node1: n1.doc._id,node2: n2.doc._id,edge_name:edge_name }})
776
884
  return edge
777
885
  }else{
778
886
  throw error
@@ -841,7 +949,7 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
841
949
  const schema_data = schemas[index]
842
950
  steps.push(`checking.${schema_name}`)
843
951
  try {
844
- let schema1 = await this.get("schema",{name:schema_name})
952
+ let schema1 = await this.get({type:"schema",criteria:{name:schema_name}})
845
953
  if (schema1["data"]["version"] != schema_data.version) {
846
954
  steps.push(`old.${schema_name}.v.${schema1["data"]["version"]}`);
847
955
  let full_doc = await this.db_api.get(schema1["_id"]);
@@ -935,13 +1043,16 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
935
1043
  if (!schema_name) {
936
1044
  throw new Error("Schema name not provided for the blank doc");
937
1045
  }
1046
+ let dt = this.util_get_now_unix_timestamp()
1047
+ let title = `${schema_name} document - ${dt}`
938
1048
  let doc = {
939
1049
  data: {},
940
1050
  meta: {
941
- created_on: this.util_get_now_unix_timestamp(),
1051
+ created_on: dt,
942
1052
  tags: [],
943
1053
  app: {},
944
1054
  link: this.util_generate_random_link(), // there is a link by default. overwrite this if user provided one but only before checking if it is unique
1055
+ title: title
945
1056
  },
946
1057
  schema: schema_name,
947
1058
  };
@@ -957,7 +1068,7 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
957
1068
  * @returns {Object}
958
1069
  */
959
1070
  _get_blank_schema_doc(schema_name, schema_object, data) {
960
- let new_data = this.util_validate_data(schema_object, data);
1071
+ let new_data = this.util_validate_data({schema:schema_object, data});
961
1072
  let obj = this._get_blank_doc(schema_name);
962
1073
  obj["data"] = new_data;
963
1074
  return obj;
@@ -980,7 +1091,6 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
980
1091
  console.log(error)
981
1092
  throw new EncryptionError([{message:error.message}])
982
1093
  }
983
-
984
1094
  }
985
1095
 
986
1096
  /**
@@ -1032,11 +1142,11 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
1032
1142
  // validate data
1033
1143
  if(!schemaDoc.active){throw new DocCreationError(`The schema "${schema}" is not active`)}
1034
1144
 
1035
- let new_data = this.util_validate_data(schemaDoc.schema, data);
1145
+ let new_data = this.util_validate_data({schema:schemaDoc.schema, data});
1036
1146
 
1037
1147
  // validate meta
1038
1148
  if(Object.keys(meta).length>0){
1039
- meta = this.util_validate_data(sys_sch.editable_metadata_schema, meta)
1149
+ meta = this.util_validate_data({schema:sys_sch.editable_metadata_schema, data:meta})
1040
1150
  }
1041
1151
 
1042
1152
 
@@ -1094,29 +1204,14 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
1094
1204
  */
1095
1205
  util_get_now_unix_timestamp() {return Math.floor(Date.now() / 1000)}
1096
1206
 
1097
- /**
1098
- * Validates that the required fields are present in the provided object.
1099
- *
1100
- * @param {string[]} requiredFields - An array of field names that are required.
1101
- * @param {object} obj - The object to check for the required fields.
1102
- * @throws {ValidationError} If any of the required fields are missing, an error is thrown.
1103
- */
1207
+
1104
1208
  util_check_required_fields(requiredFields, obj) {
1105
1209
  for (const field of requiredFields) {
1106
1210
  if (!obj[field]) {throw new ValidationError(`The field ${field} is required.`)}
1107
1211
  }
1108
1212
  }
1109
1213
 
1110
- /**
1111
- * Filters an object, returning a new object that only contains the specified fields.
1112
- *
1113
- * @param {Object} obj - The object to filter.
1114
- * @param {Array<String>} fields - An array of field names to retain in the filtered object.
1115
- *
1116
- * @returns {Object} - A new object containing only the fields that exist in `obj` from the `fields` array.
1117
- *
1118
- * **Example**:
1119
- *
1214
+ /** Filters an object, returning a new object that only contains the specified fields.
1120
1215
  * const data = { name: "Alice", age: 25, location: "NY" };
1121
1216
  * const result = util_filter_object(data, ["name", "age"]);
1122
1217
  * // result: { name: "Alice", age: 25 }
@@ -1130,7 +1225,6 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
1130
1225
  }, {});
1131
1226
  }
1132
1227
 
1133
-
1134
1228
  /**
1135
1229
  * Validates a data object against a provided JSON schema and returns a valid data object (with default value for missing field for which default values are defined in the schema )
1136
1230
  * It relies on the external API provided by the user
@@ -1138,8 +1232,11 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
1138
1232
  * @param {Object} data_obj - The data object to validate
1139
1233
  * @throws {Error} If the data object does not conform to the schema
1140
1234
  */
1141
- util_validate_data(schema_obj, data_obj) {
1142
- const { valid, validate , data} = this.utils.validate_schema(schema_obj,data_obj)
1235
+ util_validate_data(input) {
1236
+ if(!input.schema){throw new ValidationError("schema is required")}
1237
+ if(!input.data){throw new ValidationError("data is required")}
1238
+
1239
+ const { valid, validate , data} = this.utils.validate_schema(input.schema,input.data)
1143
1240
  if (!valid) {
1144
1241
  throw new ValidationError(validate.errors);
1145
1242
  }else{
@@ -1258,7 +1355,7 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
1258
1355
  * "banana-earth-rain".
1259
1356
  *
1260
1357
  */
1261
- util_generate_random_link(type=1) {
1358
+ util_generate_random_link(input={type:1}) {
1262
1359
  const options = {
1263
1360
  0:()=>{
1264
1361
  // prettier-ignore
@@ -1272,7 +1369,7 @@ async _upgrade_schema_in_bulk(schemas,log_upgrade=false,log_message="Schema Upgr
1272
1369
 
1273
1370
  }
1274
1371
  }
1275
- return options[type]()
1372
+ return options[input.type]()
1276
1373
  }
1277
1374
  }
1278
1375