New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

xpress-mongo

Package Overview
Dependencies
Maintainers
1
Versions
149
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xpress-mongo - npm Package Compare versions

Comparing version 0.0.13 to 0.0.14

89

DataTypes.js

@@ -0,1 +1,3 @@

const {ObjectID} = require('mongodb');
class ModelDataType {

@@ -13,2 +15,7 @@ constructor($default = undefined) {

/**
* Set Type Validator
* @param {function|{or: Array}|{and: Array}} validator
* @return {ModelDataType}
*/
validator(validator = () => true) {

@@ -18,2 +25,12 @@ this.schema.validator = validator;

}
validatorError(error) {
this.schema.validationError = error;
return this;
}
cast(cast) {
this.schema.cast = cast;
return this;
}
}

@@ -23,3 +40,5 @@

required: false,
validator: () => true
validator: () => true,
validationError: () => 'Validation Error',
cast: null,
};

@@ -32,3 +51,11 @@

const isBoolean = (v) => typeof v === 'boolean';
const isObject = (v) => (v && typeof v === 'object');
const isArray = (v) => Array.isArray(v);
const isDate = (v) => v instanceof Date;
const isNumber = (v) => !isNaN(v);
isObject(null);
/**

@@ -48,7 +75,49 @@ * DataTypes

ObjectId: () => {
return new ModelDataType(null)
.required(true);
return new ModelDataType(undefined)
.validator({
or: [isString, isObject]
})
.cast((val, key) => {
if (typeof val === "object" && ObjectID.isValid(val)) {
return val
}
try {
return new ObjectID(val);
} catch (e) {
throw TypeError(`(${key}) is not valid Mongodb-ObjectID`);
}
})
.validatorError((key) => `(${key}) is not a Mongodb-ObjectID`);
},
/**
* Array
* @param def
* @return {ModelDataType}
* @constructor
*/
Array: (def = () => ([])) => {
return new ModelDataType(def)
.validator(isArray)
.validatorError((key) => `(${key}) is not an Array`);
},
/**
* Object
* @param def
* @return {ModelDataType}
* @constructor
*/
Object: (def = () => ({})) => {
return new ModelDataType(def)
.validator(isObject)
.validatorError((key) => `(${key}) is not an Object`);
},
/**
* String

@@ -61,3 +130,4 @@ * @param def

return new ModelDataType(def)
.validator(isString);
.validator(isString)
.validatorError((key) => `(${key}) is not a String`);
},

@@ -73,3 +143,5 @@

return new ModelDataType(def)
.validator(isBoolean);
.validator(isBoolean)
.validatorError((key) => `(${key}) is not a Boolean`);
},

@@ -85,3 +157,4 @@

return new ModelDataType(def)
.validator(isString);
.validator(isDate)
.validatorError((key) => `(${key}) is not a Date`);
},

@@ -97,5 +170,7 @@

return new ModelDataType(def)
.validator(isNaN)
.validator(isNumber)
.cast((v) => Number(v))
.validatorError((key) => `(${key}) is not a Number`);
}
}
};

@@ -23,2 +23,39 @@ /**

module.exports = {defaultValue};
/**
* RunOrValidation
* @description
* Run validators and stop if any is true
* @param {*} value
* @param {[]} validators
* @return {boolean}
*/
function runOrValidation(value, validators = []) {
for (const validator of validators) {
if (validator(value) === true) return true
}
return false;
}
/**
* RunAndValidation
* @description
* Run validators and stop if any is false
* @param {*} value
* @param {[]} validators
* @return {boolean}
*/
function runAndValidation(value, validators = []) {
for (const validator of validators) {
if (!validator(value)) return false
}
return true;
}
module.exports = {
defaultValue,
runOrValidation,
runAndValidation
};

2

package.json
{
"name": "xpress-mongo",
"version": "0.0.13",
"version": "0.0.14",
"description": "Light Weight ODM for mongoDb",

@@ -5,0 +5,0 @@ "main": "index.js",

const Database = require('./connection');
const ContactSchema = is => ({
user_id: is.ObjectId(),
first_name: is.String().required(),
user_id: is.ObjectId().required(),
first_name: is.String(),
last_name: is.String().required(),
phone: is.String(),
created_at: is.Date()
phone: is.String().required(),
created_at: is.Date().required()
});

@@ -15,3 +14,3 @@

super();
this.setSchema(ContactSchema);
this.useSchema(ContactSchema);
}

@@ -21,15 +20,30 @@ }

const UserSchema = is => ({
type: is.String().required(),
email: is.String().required(),
first_name: is.String().required(),
last_name: is.String().required(),
verified: is.Boolean(),
updated_at: is.Date(),
created_at: is.Date()
verified: is.Boolean().required(),
updated_at: is.Date().required(),
address: is.String(),
created_at: is.Date().required()
});
const GuestSchema = is => ({
type: is.String().required(),
first_name: is.String().required(),
last_name: is.String(),
guestId: is.String().required(),
created_at: is.Date().required()
});
class Users extends Database.model("users") {
constructor() {
super();
this.setSchema(UserSchema);
this.addSchema('GuestSchema', GuestSchema);
this.addSchema('UserSchema', UserSchema);
this.useSchema('UserSchema');
}

@@ -56,6 +70,6 @@

*/
module.exports.Users = Users;
exports.Users = Users;
/**
* @type {typeof Contacts| typeof XMongoModel}
*/
module.exports.Contacts = Contacts;
exports.Contacts = Contacts;

@@ -1,14 +0,38 @@

const {Client} = require('../index');
const mongodb = require('mongodb');
const {Users, Contacts} = require('./models');
const Chance = require('chance');
const chance = new Chance();
mongodb.MongoClient.connect(
'mongodb://localhost/test_model',
{useNewUrlParser: true, useUnifiedTopology: true}
).then(async client => {
const Database = Client(client).useDb('test_model');
const UserModel = Database.model('users');
async function run() {
/**
* Async Space
*/
console.log(await UserModel.findOne())
}).catch(err => {
console.log(err);
// const guest = new Users().useSchema('UserS').set({
// type: 'guest',
// first_name: 'Hello',
// last_name: 'World',
// guestId: chance.guid()
// });
// const contact = await Contacts.findById('5e5b92f6d7fd524b7ce4fade');
//
// contact.set('job', 39);
// console.log(await contact.save());
// console.log(guest.data);
// const user = new Users().useSchema('UserSchema').set({
// email: chance.email()
// });
/**
* End Async Space
*/
}
run().then(() => {
process.exit();
}).catch(e => {
console.log(e);
process.exit();
});

@@ -73,3 +73,3 @@ const GenerateModel = require('./XMongoModel');

const connection = this.db.collection(collection);
return GenerateModel(connection, collection)
return GenerateModel(connection)
}

@@ -76,0 +76,0 @@ }

const XMongoUsing = require('./XMongoUsing');
const {ObjectID} = require('mongodb');
const {is, ModelDataType} = require('./DataTypes');
const {defaultValue} = require('./fns/inbuilt');
const {
defaultValue,
runOrValidation,
runAndValidation
} = require('./fns/inbuilt');
const {diff} = require('deep-object-diff');

@@ -33,2 +39,9 @@ const ObjectCollection = require('object-collection');

write: true,
enumerable: false,
configurable: true,
});
Object.defineProperty(this, 'schemaStore', {
value: {},
write: true,
enumerable: false

@@ -72,2 +85,3 @@ });

/**

@@ -103,3 +117,3 @@ * Defined relationships

*/
XMongoModel.prototype.set = function (key, value) {
XMongoModel.prototype.set = function (key, value = undefined) {
if (typeof key === 'object' && value === undefined) {

@@ -135,2 +149,3 @@ for (const property in key) {

XMongoModel.prototype.setOriginal = function (data) {
data = _.cloneDeep(data);

@@ -147,3 +162,18 @@

/**
* Set multiple schemas and use them at anytime using `.setSchema`
* @param {string} name
* @param {Object} schema
* @return {XMongoModel}
*/
XMongoModel.prototype.addSchema = function (name, schema) {
// Save to schemaStore
this.schemaStore[name] = schema;
return this;
};
/**
* @callback schemaWithIs

@@ -158,9 +188,46 @@ * @param {is|*} raw

* if `schema` is undefined then `this.data` is used as schema object
* @param {schemaWithIs|Object} schema
* @param {schemaWithIs|Object|string} schema
* @returns {XMongoModel}
*
* @deprecated
*/
XMongoModel.prototype.setSchema = function (schema = undefined) {
console.log(`.setSchema is deprecated use .useSchema`);
return this.useSchema(schema);
};
/**
* Set Model Schema
*
* if `schema` is undefined then `this.data` is used as schema object
* @param {schemaWithIs|Object|String} schema
* @returns {XMongoModel}
*/
XMongoModel.prototype.useSchema = function (schema = undefined) {
// Redefine schema
Object.defineProperty(this, 'schema', {
value: {},
write: true,
enumerable: false,
configurable: true,
});
// Try to find schema from .schemaStore if string
if (typeof schema === "string") {
if (!this.schemaStore.hasOwnProperty(schema)) {
throw Error(`schemaStore does not have schema named: ${schema}`)
}
// Empty Data to remove any predefined schemas
if (!Object.keys(this.original).length) {
this.emptyData();
}
schema = this.schemaStore[schema] || {}
}
const schemaIsData = schema === undefined;
schema === undefined && (schema = this.data);
const newData = {_id: null};
const newData = {_id: this.id()};

@@ -289,5 +356,13 @@ // If schema is a function then call it and pass is.

if (id) {
const $set = this.changes();
let $set = this.changes();
if (!Object.keys($set).length) return resolve(false);
// Try to validate changes
try {
$set = {...$set, ...this.validate($set)};
} catch (e) {
return reject(e)
}
return collection.updateOne(

@@ -299,2 +374,9 @@ {_id: this.id()},

} else {
// Try to validate new data.
try {
this.emptyData(this.validate());
} catch (e) {
return reject(e)
}
return collection.insertOne(

@@ -318,7 +400,142 @@ this.data,

/**
* Validate
* @description
* Runs validation on this.data if data is undefined.
* @param data
* @return {{}}
*/
XMongoModel.prototype.validate = function (data = undefined) {
/**
* Checks if data was defined or not.
* @type {boolean}
*/
let customData = true;
/**
* If data is undefined, default to this.data
* And set customData to false.
*/
if (!data) {
data = this.data;
customData = false;
}
/**
* Stores validated keys and values.
* @type {{}}
*/
const validated = {};
/**
* Loop through all defined schemas and validate.
*/
for (const schemaKey in this.schema) {
/**
* If data doesnt have schemaKey we skip
* else throw Error if this is not a customData
*
* i.e else if data === this.data
*/
if (data.hasOwnProperty(schemaKey)) {
/**
* Schema Definition of current schema
* @type {*|ModelDataType}
*/
const schema = this.schema[schemaKey];
/**
* Current value of key being validated.
* @type {*}
*/
let dataValue = data[schemaKey];
/**
* If schema is required and dataValue is undefined
* Throw required error
*/
if (dataValue === undefined && schema['required'] === true) {
throw new TypeError(`(${schemaKey}) is required.`)
}
// validate using validator if value is not undefined
if (dataValue !== undefined) {
/**
* Holds type of validator.
* @type {"undefined"|"object"|"boolean"|"number"|"string"|"function"|"symbol"|"bigint"}
*/
let validatorType = typeof schema.validator;
/**
* Holds validator Error for schemaKey
* @type {string}
*/
const validatorError = schema.validationError(schemaKey);
/**
* If validatorType is 'function', run validator
* Throw error if validator returns false.
*
* Else if validatorType is 'object'
* validate the object received.
*/
if (validatorType === 'function' && !schema.validator(dataValue)) {
throw new TypeError(validatorError);
} else if (validatorType === 'object') {
// Get first key of object
validatorType = Object.keys(schema.validator)[0];
/**
* If validatorType === 'or' run `runOrValidation`,
* If validatorType === 'and' run `runAndValidation`
*/
if (validatorType === 'or' && !runOrValidation(dataValue, schema.validator['or'])) {
throw new TypeError(validatorError);
} else if (validatorType === 'and' && !runAndValidation(dataValue, schema.validator['and'])) {
throw new TypeError(validatorError);
}
}
/**
* Cast dataValue if schema.cast is defined and a function
*/
if (typeof schema['cast'] === 'function') {
dataValue = schema.cast(dataValue, schemaKey);
}
// Add to validated object
validated[schemaKey] = dataValue;
}
} else {
if (!customData)
throw new TypeError(`${schemaKey} is missing in data but defined in schema`)
}
}
// Add keys not in schema but in data and removed undefined values
for (const dataKey in data) {
const dataValue = data[dataKey];
if (!this.schema.hasOwnProperty(dataKey) && dataValue !== undefined) {
validated[dataKey] = dataValue
}
if (dataValue === undefined) {
delete data[dataKey];
}
}
// Return this way to retain original object structure
return {...data, ...validated};
};
/**
* Delete this
* @param writeConcern
* @returns {Promise}
*/
XMongoModel.prototype.delete = function (writeConcern) {
XMongoModel.prototype.delete = function () {
const _id = this.id();

@@ -442,3 +659,3 @@

XMongoModel.prototype.emptyData = function () {
XMongoModel.prototype.emptyData = function (replaceWith=undefined) {
this.data = {

@@ -448,2 +665,4 @@ _id: this.id()

if(replaceWith && typeof replaceWith === 'object') this.data = {...this.data, ...replaceWith};
return this;

@@ -450,0 +669,0 @@ };

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc