0.0.2 • Published 5 years ago

schema-from-object v0.0.2

Weekly downloads
4
License
ISC
Repository
github
Last release
5 years ago

schema-from-object

Browser-compatibility-bundled Node.js module for generating data validation schemas.

  • Supply a 'sample' object representing a data type and a Schema is automatically generated.
  • Browserify bundled for browser as well, except it can't persist data to disk when executed in the browser.
  • It comes in two variants - one is synchronous and the other returns async promises . No callback support, but I can add it later.
  • Somewhat standardized/popular schema types that the module can make: A GENERIC one, MYSQL, JSON, MONGOOSE, GOOGLE BIG-QUERY and CLICKHOUSE.
  • Support for supplying whole object arrays of any size with varying properties to any extent. The schema generated will just add any property or nested object that it comes across as they accumulate while iterating the passed object-array.
  • There is no max nesting depth for the structure. Everything will be parsed.

Install

$ npm install schema-from-object --save

Why

These are very simple schemas. Probably most relevant for projects with strict data structures or trying out ideas before data structures get too complex. I've used this module sometimes in relation to de-/serializing complex object structures in a hurry, and other little things where it can be handy and quick to implement.

Usage

The bare minimum. Require/import it, pass object.

var SchemaFromObject = require('schema-from-object');
var anyObj = { key: 'val', c: 4 };
var jsonSchema = SchemaFromObject.sync(anyObj);
console.log(jsonSchema);

Credits

  • I didn't really do much here except make a wrapper that I liked to use better and add the multiple objects' accumulating properties in the array interation-thing, which is just a detail. But I thought I might as well share it, but credit goes over there: https://github.com/Nijikokun/generate-schema

Usage Extended

Here's a data object with quite a few types.

DEMO DATA OBJECT - used in the below samples

const obj = {};
obj.age = 27;
obj.name = 'Peter';
obj.lastSeen = new Date();
obj.decimal = 21.521;
obj.onFire = true;
obj.func = () => {
   console.log();
}
obj.normal = new RegExp(/abc/, 'gmi');
obj.deep = {
   structure: {
      further: {
         arrStuff: ['cans', 2, new Date()];
      }
   }
};
class NotNativeType { 
   constructor(id) { 
      this.id = id; 
      this.name = 'Nayme'; 
      this.arr = [ {}, false ]; 
   } 
}
obj.classy = new NotNativeType('eye-d');

Example #1 - Synchronous JSON Schema generation from single object

const mySchema SchemaFromObject.sync(obj);

/*

   Hypothetical console.log(mySchema) here, which prints:
  
 {
   "json": {
      "$schema": "http://json-schema.org/draft-04/schema#",
      "type": "object",
      "properties": {
         "age": {
            "type": "number"
         },
         "name": {
            "type": "string"
         },
         "lastSeen": {
            "type": "string",
            "format": "date-time"
         },
         "decimal": {
            "type": "number"
         },
         "onFire": {
            "type": "boolean"
         },
         "func": {
            "type": "string"
         },
         "normal": {
            "type": "string"
         },
         "deep": {
            "type": "object",
            "properties": {
               "structure": {
                  "type": "object",
                  "properties": {
                     "further": {
                        "type": "object",
                        "properties": {
                           "arrStuff": {
                              "type": "array",
                              "items": {
                                 "oneOf": [
                                    {
                                       "type": "string"
                                    },
                                    {
                                       "type": "string"
                                    },
                                    {
                                       "type": "number"
                                    },
                                    {
                                       "type": "string",
                                       "format": "date-time"
                                    }
                                 ]
                              }
                           }
                        }
                     }
                  }
               }
            }
         },
         "classy": {
            "type": "notnativetype"
         }
      }
   }
}
 
*/

Example #2 - Same again, but all schema-types included and then saved to disk (sync).

//available schema-types
let schemaTypes = [
   'generic',
   'mysql',
   'json',
   'mysql',
   'mongoose',
   'bigquery',
   'clickhouse'
];

//for each one
const allSchemas = SchemaFromObject.sync(obj, schemaTypes);
for (let i in allSchemas) {
   
   //To local disk
   const dir = 'c:/' + schemaTypes[i] + '.json';
   fs.writeFileSync(dir, JSON.stringify(allSchemas[i],null,3));
   
   //print to console
   console.log(allSchemas[ i ]);
   console.log();console.log();
}

Example #3 - Async function for mongoose schema as a thennable

let schemaTypes = [ 'mongoose' ]

SchemaFromObject.async(obj, schemaTypes)
   .then(arrSchemas => {
      console.log(arrSchemas)
   }).catch(err => {
      console.error(err)
   });

Example #4 - Async / await MYSQL Schema.

async () => { console.log(

      await SchemaFromObject.async(obj, ['mysql']);

)}

Example #5 - Synchronous object array "property-accumulation" -Schema

/*
   -------------------------------------------------------------
   An array of objects that don't have all identical properties. A schema will be created that fits
   every object-variant in that array. So not very strict, but making sure the schema will not claim
   existing data to be invalid or won't get serialized or whichever context you use schemas in.
   That was the idea behind adding this option anyway :)
 */

const people = [
   { name: 'Jean-Luc Picard', age: 59 , favBook: 'lotr'},
   { name: 'William Riker', age: 29, favBook: 'bla' },
   { name: 'Deanna Troi', age: 28, favBand: 'zep' },
   { name: 'Worf', age: 24, favAlbum: 'wish you were here' },
   { name: 'Stephen Spielberg', age: 4, favBook: 'bla' }
];

// Note that it's the same method call as the previous examples even though here, we're parsing obj-arrays. The parser will see that it's an array and proceed.

console.log(JSON.stringify(SchemaFromObject.sync(people),null,3));

/*  THE ABOVE PRINTS:
-------------------------------------------------------------
"properties": {
   "name": {
      "type": "string"
   },
   "age": {
      "type": "number"
   },
   "favBook": {
      "type": "string"
   },
   "favBand": {
      "type": "string"
   },
   "favAlbum": {
      "type": "string"
   }
}
*/