Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

moltyjs

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

moltyjs - npm Package Compare versions

Comparing version 0.4.2 to 0.5.0

19

CHANGELOG.md

@@ -35,2 +35,19 @@ ## [Unreleased]

## [0.5.0] - 2017-12-27
### Changed
* Document constructor now return a Promise due the validation function on the Schema fields which can be async functions. The validation checking is done at the moment you create the Document.
* Passed the entire data payload normalized to the validate function instead of the value of the field is validating. In case further checking are neccesary.
* Documentaion about:
* Create a new Document
* Schema option fields
* Promise functions
## [0.4.3] - 2017-12-27
### Fixed
* Added support for async functions in the Schema fields validation function.
## [0.4.2] - 2017-12-27

@@ -242,2 +259,4 @@

[0.5.0]: https://github.com/Yonirt/moltyjs/compare/v0.4.3...v0.5.0
[0.4.3]: https://github.com/Yonirt/moltyjs/compare/v0.4.2...v0.4.3
[0.4.2]: https://github.com/Yonirt/moltyjs/compare/v0.4.1...v0.4.2

@@ -244,0 +263,0 @@ [0.4.1]: https://github.com/Yonirt/moltyjs/compare/v0.4.0...v0.4.1

167

lib/model.js
'use strict';
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const mongoClient = require('./clients/mongoClient');
const Document = require('./document');
var _require = require('./validators');
var _require = require('await-to-js');
const isValidType = _require.isValidType,
isObject = _require.isObject,
isArray = _require.isArray,
isEmptyValue = _require.isEmptyValue,
isString = _require.isString,
isInEnum = _require.isInEnum,
isNumber = _require.isNumber;
const to = _require.to;
var _require2 = require('./validators');
const isValidType = _require2.isValidType,
isObject = _require2.isObject,
isArray = _require2.isArray,
isEmptyValue = _require2.isEmptyValue,
isString = _require2.isString,
isInEnum = _require2.isInEnum,
isNumber = _require2.isNumber;
class Model {

@@ -46,2 +54,4 @@ /**

this._normalizedPayload = null;
mongoClient.addModel(this);

@@ -99,14 +109,24 @@ }

new(payload, tenant) {
if (!tenant) throw new Error('Tenant name is required, got ' + tenant);
var _this = this;
// Check if paylaod field names are correct
this._validatePayloadFieldNames(payload, this._schemaNormalized);
// Normalize the payload with the model schema
let data = this._normalizePayload(payload, this._schemaNormalized);
return _asyncToGenerator(function* () {
if (!tenant) throw new Error('Tenant name is required, got ' + tenant);
// Validate all the values
this._validatePayloadFieldValues(data, this._schemaNormalized, tenant);
// Check if paylaod field names are correct
_this._validatePayloadFieldNames(payload, _this._schemaNormalized);
// Normalize the payload with the model schema
_this._normalizedPayload = _this._normalizePayload(payload, _this._schemaNormalized);
// Returning the new document created
return new Document(data, this._preHooks, this._postHooks, this._methods, this._schemaOptions, this._modelName, this._discriminator, tenant);
try {
// Validate all the values
yield _this._validatePayloadFieldValues(_this._normalizedPayload, _this._schemaNormalized, tenant);
// Returning the new document created
return new Document(_this._normalizedPayload, _this._preHooks, _this._postHooks, _this._methods, _this._schemaOptions, _this._modelName, _this._discriminator, tenant);
} catch (err) {
throw err;
} finally {
_this._normalizedPayload = null;
}
})();
}

@@ -204,47 +224,88 @@

_validatePayloadFieldValues(payload, schema, tenant = null) {
Object.keys(schema).forEach(key => {
// No required values
if (payload[key] === undefined && !schema[key].required) return;
var _this2 = this;
// Objects nested
if (!schema[key].type && isObject(payload[key])) {
payload[key] = this._validatePayloadFieldValues(payload[key], schema[key]);
return;
}
return _asyncToGenerator(function* () {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
// Validation type
if (!isValidType(payload[key], schema[key].type)) {
throw new Error('Unsuported value (' + payload[key] + ') for type ' + schema[key].type);
}
try {
for (var _iterator = Object.keys(schema)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
const key = _step.value;
// Reg exp validation
if (schema[key].match && isString(payload[key]) && !schema[key].match.test(payload[key])) {
throw new Error('Value assigned to ' + key + ' does not match the regex/string ' + schema[key].match.toString() + '. Value was ' + payload[key]);
}
// No required values
if (payload[key] === undefined && !schema[key].required) continue;
// Enum validation
if (!isInEnum(schema[key].enum, payload[key])) {
throw new Error('Value assigned to ' + key + ' should be in enum [' + schema[key].enum.join(', ') + '], got ' + payload[key]);
}
// Objects nested
if (!schema[key].type && isObject(payload[key])) {
payload[key] = _this2._validatePayloadFieldValues(payload[key], schema[key]);
continue;
}
// Min value validation
if (isNumber(schema[key].min) && payload[key] < schema[key].min) {
throw new Error('Value assigned to ' + key + ' is less than min, ' + schema[key].min + ', got ' + payload[key]);
}
// Validation type
if (!isValidType(payload[key], schema[key].type)) {
throw new Error('Unsuported value (' + payload[key] + ') for type ' + schema[key].type);
}
// Max value validation
if (isNumber(schema[key].max) && payload[key] > schema[key].max) {
throw new Error('Value assigned to ' + key + ' is less than max, ' + schema[key].max + ', got ' + payload[key]);
}
// Reg exp validation
if (schema[key].match && isString(payload[key]) && !schema[key].match.test(payload[key])) {
throw new Error('Value assigned to ' + key + ' does not match the regex/string ' + schema[key].match.toString() + '. Value was ' + payload[key]);
}
// Max lenght validation
if (schema[key].maxlength && isString(payload[key]) && payload[key].length > schema[key].maxlength) {
throw new Error('Value assigned to ' + key + ' is bigger than ' + schema[key].maxlength.toString() + '. Value was ' + payload[key].length);
}
// Enum validation
if (!isInEnum(schema[key].enum, payload[key])) {
throw new Error('Value assigned to ' + key + ' should be in enum [' + schema[key].enum.join(', ') + '], got ' + payload[key]);
}
// Custom validation
if (typeof schema[key].validate === 'function' && !schema[key].validate(mongoClient, tenant, payload[key])) {
throw new Error('Value assigned to ' + key + ' failed custom validator. Value was ' + payload[key]);
// Min value validation
if (isNumber(schema[key].min) && payload[key] < schema[key].min) {
throw new Error('Value assigned to ' + key + ' is less than min, ' + schema[key].min + ', got ' + payload[key]);
}
// Max value validation
if (isNumber(schema[key].max) && payload[key] > schema[key].max) {
throw new Error('Value assigned to ' + key + ' is less than max, ' + schema[key].max + ', got ' + payload[key]);
}
// Max lenght validation
if (schema[key].maxlength && isString(payload[key]) && payload[key].length > schema[key].maxlength) {
throw new Error('Value assigned to ' + key + ' is bigger than ' + schema[key].maxlength.toString() + '. Value was ' + payload[key].length);
}
// Custom validation
if (typeof schema[key].validate === 'function') {
let error, isValid;
if (schema[key].validate.constructor.name === 'AsyncFunction') {
var _ref = yield to(schema[key].validate(mongoClient, tenant, _this2._normalizedPayload));
var _ref2 = _slicedToArray(_ref, 2);
error = _ref2[0];
isValid = _ref2[1];
} else {
isValid = schema[key].validate(mongoClient, tenant, _this2._normalizedPayload);
}
if (!isValid || error) {
let err = new Error('Value assigned to ' + key + ' failed custom validator. Value was ' + payload[key]);
err.code = 'VALIDATION_FAILED';
throw err;
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
})();
}

@@ -251,0 +312,0 @@

{
"name": "moltyjs",
"version": "0.4.2",
"version": "0.5.0",
"description": "A tiny ODM for MongoDB with multy tenancy support.",

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

@@ -114,3 +114,3 @@ [![npm version](https://badge.fury.io/js/moltyjs.svg)](https://badge.fury.io/js/moltyjs)

* _maxlength_: Optional, maximum length of a **String**
* _validate_: Optional, function to perform a custom validation. Value of the field, connection instance and tenant name is passing through the function args:
* _validate_: Optional, function to perform a custom validation. Payload of the document, connection instance and tenant name is passing through the function args:

@@ -123,9 +123,10 @@ ```javascript

type: String,
validate: async (connection, tenant, value) => {
validate: async (connection, tenant, payload) => {
const exists = await connection.find(tenant, 'TestModel', {
job: value,
job: payload.job,
});
// If the document already exists we
// propagate an error returning false
// propagate an error with error.code = 'VALIDATION_FAILED'
// by returning false
if (exists) return false;

@@ -308,3 +309,3 @@

### `.new(payload, tenant)`
### `.new(payload, tenant) {Promise}`

@@ -316,3 +317,3 @@ ```javascript

newDoc = TestModel.new(
newDoc = await TestModel.new(
{

@@ -324,3 +325,3 @@ email: 'test@moltyjs.com',

'test',
);
); // Document // Error
```

@@ -381,3 +382,3 @@

### `insertOne(doc, options = {})`
### `insertOne(doc, options = {}) {Promise}`

@@ -395,3 +396,3 @@ * {Document} `doc` Document instance object

### `insertMany(docs, options = {})`
### `insertMany(docs, options = {}) {Promise}`

@@ -417,3 +418,3 @@ * [{Document}] `docs` Array of Document instances of the same model and for the same tenant

### `find(tenant, collection, query = {}, options = {})`
### `find(tenant, collection, query = {}, options = {}) {Promise}`

@@ -443,3 +444,3 @@ * {String} `tanant` Tenant name

### `updateOne(tenant, collection, filter, payload, options = {})`
### `updateOne(tenant, collection, filter, payload, options = {}) {Promise}`

@@ -446,0 +447,0 @@ ```javascript

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