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

thinky

Package Overview
Dependencies
Maintainers
1
Versions
129
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

thinky - npm Package Compare versions

Comparing version 1.15.0 to 1.15.1

lib/schema.js

212

lib/model.js
var util = require(__dirname+'/util.js');
var schemaUtil = require(__dirname+'/schema.js');
var Document = require(__dirname+'/document.js');

@@ -14,5 +15,11 @@ var EventEmitter = require('events').EventEmitter;

util.validateSchema(schema)
schemaUtil.validateSchema(schema)
this._schema = schema;
this.virtualFields = [];
schemaUtil.getVirtualFields(schema, [], this.virtualFields);
this.defaultFields = [];
schemaUtil.getDefaultFields(schema, [], this.defaultFields);
this.needToGenerateFields = (this.defaultFields.length+this.virtualFields.length) !== 0;
// We want a deep copy

@@ -45,2 +52,3 @@ options = options || {};

this._joins = {};
this._localKeys = {}; // key used as a foreign key by another model

@@ -83,10 +91,14 @@ // This is to track joins that were not directly called by this model but that we still need

}
doc = util.deepCopy(doc);
doc.__proto__ = new Document(model, options);
// We create a deepcopy only if doc was already used to create a document
if (doc instanceof Document) {
doc = util.deepCopy(doc);
}
util.changeProto(doc, new Document(model, options));
// Make joins
for(var key in proto._joins) {
util.loopKeys(proto._joins, function(joins, key) {
if (doc[key] != null) {
if (proto._joins[key].type === 'hasOne') {
doc[key] = new proto._joins[key].model(doc[key], options);
if (joins[key].type === 'hasOne') {
doc[key] = new joins[key].model(doc[key], options);

@@ -106,4 +118,4 @@ doc.__proto__._hasOne[key] = {

}
else if (proto._joins[key].type === 'belongsTo') {
doc[key] = new proto._joins[key].model(doc[key], options);
else if (joins[key].type === 'belongsTo') {
doc[key] = new joins[key].model(doc[key], options);

@@ -120,7 +132,7 @@ if (doc[key].__proto__._parents._belongsTo[doc._getModel()._name] == null) {

}
else if (proto._joins[key].type === 'hasMany') {
else if (joins[key].type === 'hasMany') {
doc.__proto__._hasMany[key] = []
for(var i=0; i<doc[key].length; i++) {
doc[key][i] = new proto._joins[key].model(doc[key][i], options);
doc[key][i] = new joins[key].model(doc[key][i], options);
doc.__proto__._hasMany[key].push({

@@ -141,7 +153,7 @@ doc: doc[key][i],

}
else if (proto._joins[key].type === 'hasAndBelongsToMany') {
else if (joins[key].type === 'hasAndBelongsToMany') {
doc.__proto__._links[model._joins[key].link] = {}
for(var i=0; i<doc[key].length; i++) {
doc[key][i] = new proto._joins[key].model(doc[key][i], options);
doc[key][i] = new joins[key].model(doc[key][i], options);

@@ -161,4 +173,6 @@ doc.__proto__._links[model._joins[key].link][doc[key][i][model._joins[key].rightKey]] = true;

}
});
if (proto.needToGenerateFields === true) {
doc._generateDefault();
}
doc.__proto__._generateDefault.apply(doc)

@@ -193,3 +207,3 @@ var promises = [];

// the constructor and the instance of Model
for(var key in EventEmitter.prototype) {
util.loopKeys(EventEmitter.prototype, function(emitter, key) {
(function(_key) {

@@ -200,3 +214,3 @@ model[_key] = function() {

})(key)
}
});

@@ -257,13 +271,2 @@

/*
* Make a shallow copy of docValues in doc
*/
Model.prototype.create = function(docValues) {
var doc = {};
for(var key in docValues) {
doc[key] = docValues[key];
}
return doc;
}
/*
* Return the options of the model -- call from an instance of Model

@@ -420,2 +423,3 @@ */

}
joinedModel._getModel()._localKeys[rightKey] = true;

@@ -519,3 +523,4 @@ options = options || {};

type: 'belongsTo'
}
};
self._getModel()._localKeys[leftKey] = true;

@@ -618,4 +623,5 @@ joinedModel._getModel()._reverseJoins[fieldDoc] = {

type: 'hasMany'
}
};
joinedModel._getModel()._localKeys[rightKey] = true;
options = options || {};

@@ -910,63 +916,65 @@ if (options.init !== false) {

}
}
};
// Import rethinkdbdash methods
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__;
for(var key in Term) {
if ((Term.hasOwnProperty(key)) && (key !== 'run') && (key[0] !== '_')) {
(function(key) {
switch (key) {
case 'orderBy':
Model.prototype[key] = function() {
var query = new Query(this);
if ((arguments.length === 1)
&& (typeof arguments[0] === 'string')
&& (this._getModel()._indexes[arguments[0]] === true)) {
(function() {
// Import rethinkdbdash methods
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__;
util.loopKeys(Term, function(Term, key) {
if ((Term.hasOwnProperty(key)) && (key !== 'run') && (key[0] !== '_')) {
(function(key) {
switch (key) {
case 'orderBy':
Model.prototype[key] = function() {
var query = new Query(this);
if ((arguments.length === 1)
&& (typeof arguments[0] === 'string')
&& (this._getModel()._indexes[arguments[0]] === true)) {
query = query[key]({index: arguments[0]});
query = query[key]({index: arguments[0]});
return query;
}
else {
query = query[key].apply(query, arguments);
return query;
}
}
else {
query = query[key].apply(query, arguments);
return query;
}
}
break;
case 'filter':
Model.prototype[key] = function() {
var query = new Query(this);
if ((arguments.length === 1)
&& (util.isPlainObject(arguments[0]))) {
break;
case 'filter':
Model.prototype[key] = function() {
var query = new Query(this);
if ((arguments.length === 1)
&& (util.isPlainObject(arguments[0]))) {
// Optimize a filter with an object
// We replace the first key that match an index name
var filter = arguments[0];
// Optimize a filter with an object
// We replace the first key that match an index name
var filter = arguments[0];
var keys = Object.keys(filter).sort(); // Lexicographical order
for(var i=0 ; i<keys.length; i++) {
var index = keys[i];
var keys = Object.keys(filter).sort(); // Lexicographical order
for(var i=0 ; i<keys.length; i++) {
var index = keys[i];
if (this._getModel()._indexes[index] === true) { // Index found
query = query.getAll(filter[index], {index: index});
delete filter[index];
break;
if (this._getModel()._indexes[index] === true) { // Index found
query = query.getAll(filter[index], {index: index});
delete filter[index];
break;
}
}
}
query = query[key].apply(query, arguments);
return query;
}
query = query[key].apply(query, arguments);
return query;
break;
default:
Model.prototype[key] = function() {
var query = new Query(this);
query = query[key].apply(query, arguments);
return query;
}
}
break;
default:
Model.prototype[key] = function() {
var query = new Query(this);
query = query[key].apply(query, arguments);
return query;
}
}
})(key);
}
}
})(key);
}
});
})();

@@ -1328,18 +1336,8 @@ Model.prototype.getJoin = function() {

Model.prototype.pre = function(ev, isAsync, fn) {
if (arguments.length === 2) {
if (typeof isAsync !== 'function') {
throw new Error("Second argument to `pre` must be a function if only two arguments are provided.")
}
fn = isAsync;
isAsync = false;
Model.prototype.pre = function(ev, fn) {
if (typeof fn !== "function") {
throw new Error("Second argument to `pre` must be a function");
}
else if (arguments.length === 3) {
if (typeof isAsync !== 'boolean') {
throw new Error("Second argument to `pre` must be a boolean if three arguments are provided.")
}
if (typeof fn !== 'function') {
throw new Error("Third argument to `pre` must be a function if three arguments are provided.")
}
if (fn.length > 1) {
throw new Error("Second argument to `pre` must be a function with at most one argument.");
}

@@ -1349,23 +1347,12 @@ if (Array.isArray(this._pre[ev]) === false) {

}
if (isAsync === true) {
this._getModel()._async[ev] = true;
}
this._getModel()._async[ev] = this._getModel()._async[ev] || (fn.length === 1)
this._getModel()._pre[ev].push(fn);
}
Model.prototype.post = function(ev, isAsync, fn) {
if (arguments.length === 2) {
if (typeof isAsync !== 'function') {
throw new Error("Second argument to `post` must be a function if only two arguments are provided.")
}
fn = isAsync;
isAsync = false;
Model.prototype.post = function(ev, fn) {
if (typeof fn !== "function") {
throw new Error("Second argument to `pre` must be a function");
}
else if (arguments.length === 3) {
if (typeof isAsync !== 'boolean') {
throw new Error("Second argument to `post` must be a boolean if three arguments are provided.")
}
if (typeof fn !== 'function') {
throw new Error("Third argument to `post` must be a function if three arguments are provided.")
}
if (fn.length > 1) {
throw new Error("Second argument to `pre` must be a function with at most one argument.");
}

@@ -1375,9 +1362,6 @@ if (Array.isArray(this._post[ev]) === false) {

}
if (isAsync === true) {
this._getModel()._async[ev] = true;
}
this._getModel()._async[ev] = this._getModel()._async[ev] || (fn.length === 1)
this._getModel()._post[ev].push(fn);
}
module.exports = Model;

@@ -11,10 +11,9 @@ var Promise = require('bluebird');

this._r = model._getModel()._thinky.r;
for (var key in model._staticMethods) {
(function(key) {
self[key] = function() {
return model._staticMethods[key].apply(self, arguments);
util.loopKeys(model._getModel()._staticMethods, function(staticMethods, key) {
(function(_key) {
self[_key] = function() {
return staticMethods[_key].apply(self, arguments);
};
})(key);
}
});
}

@@ -51,7 +50,5 @@

var fullOptions = {groupFormat: 'raw'}
for(var key in options) {
if (options.hasOwnProperty(key)) {
fullOptions[key] = options[key]
}
}
util.loopKeys(options, function(options, key) {
fullOptions[key] = options[key]
});
if (parse !== true) {

@@ -130,10 +127,3 @@ fullOptions.cursor = true;

}
if (typeof callback === 'function') {
p.then(function(result) {
callback(null, result);
}).error(function(error) {
callback(error);
});
}
return p;
return p.nodeify(callback);
}

@@ -176,4 +166,4 @@

for(var key in joins) {
if (((getAll === true) || (key in modelToGet)) && ((getAll === false) || (gotModel[joins[key].model.getTableName()] !== true))) {
util.loopKeys(joins, function(joins, key) {
if (util.recurse(key, joins, modelToGet, getAll, gotModel)) {
if (joins[key].type === 'hasOne') {

@@ -289,3 +279,3 @@ self._query = self._query.merge(function(doc) {

}
}
});

@@ -297,24 +287,29 @@ return self;

throw new Error("The method `then` is not defined on Query. Did you forgot `.run()` or `.execute()`?")
}
};
// Import rethinkdbdash methods
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__;
for(var key in Term) {
if ((Term.hasOwnProperty(key)) && (key !== 'run') && (key[0] !== '_')) {
if (key === 'get') {
(function(key) {
Query.prototype[key] = function() {
return new Query(this._model, this._query[key].apply(this._query, arguments)).default(this._r.error("The query did not find a document and returned null."));
}
})(key);
(function() {
// Import rethinkdbdash methods
var Term = require('rethinkdbdash')({pool: false}).expr(1).__proto__;
util.loopKeys(Term, function(Term, key) {
// Note: We suppose that no method has an empty name
if ((key !== 'run') && (key[0] !== '_')) {
if (key === 'get') {
(function(key) {
Query.prototype[key] = function() {
return new Query(this._model, this._query[key].apply(this._query, arguments)).default(this._r.error("The query did not find a document and returned null."));
}
})(key);
}
else {
(function(key) {
Query.prototype[key] = function() {
// Create a new query to let people fork it
return new Query(this._model, this._query[key].apply(this._query, arguments));
}
})(key);
}
}
else {
(function(key) {
Query.prototype[key] = function() {
return new Query(this._model, this._query[key].apply(this._query, arguments));
}
})(key);
}
}
}
});
})();

@@ -321,0 +316,0 @@ Query.prototype.toString = function() {

@@ -87,5 +87,5 @@ var rethinkdbdash = require('rethinkdbdash');

options = options || {};
for(var key in options) {
util.loopKeys(options, function(options, key) {
fullOptions[key] = options[key];
}
});

@@ -144,1 +144,7 @@ if (self.models[name] !== undefined) {

}
// Internal use only, to speed up testing
Thinky.prototype._clean = function() {
this.models = {};
}
var util = require('util');
var Promise = require('bluebird');
var EventEmitter = require('events').EventEmitter;

@@ -9,82 +10,2 @@ function isPlainObject(obj) {

function validateSchema(schema, prefix) {
// Validate a schema and add the field _enum if needed
prefix = prefix || '';
if (isPlainObject(schema)) {
for(var key in schema) {
if (Array.isArray(schema[key])) {
validateSchema(schema[key], prefix+'['+key+']');
}
else if (isPlainObject(schema[key])) {
if (schema[key].hasOwnProperty('_type')) {
if ((schema[key]._type !== String)
&& (schema[key]._type !== Number)
&& (schema[key]._type !== Boolean)
&& (schema[key]._type !== Date)
&& (schema[key]._type !== Buffer)
&& (schema[key]._type !== Object)
&& (schema[key]._type !== Array)
&& (schema[key]._type !== 'Point')
&& (schema[key]._type !== 'virtual')) {
throw new Error("The field `_type` must be `String`/`Number`/`Boolean`/`Date`/`Buffer`/`Object`/`Array`/`'virtual'`/`'Point'` for "+prefix+"["+key+"]");
}
// Add the set with the valid values for an enum
if (Array.isArray(schema[key].enum)) {
schema[key]._enum = {}
for(var i=0; i<schema[key].enum.length; i++) {
schema[key]._enum[schema[key].enum[i]] = true;
}
}
}
else {
validateSchema(schema[key], prefix+'['+key+']');
}
}
else if ((schema[key] !== String)
&& (schema[key] !== Number)
&& (schema[key] !== Boolean)
&& (schema[key] !== Date)
&& (schema[key] !== Buffer)
&& (schema[key] !== Object)
&& (schema[key] !== Array)
&& (schema[key] !== 'Point')
&& (schema[key] !== 'virtual')) {
throw new Error("The value must be `String`/`Number`/`Boolean`/`Date`/`Buffer`/`Object`/`Array`/`'virtual'`/`'Point'` for "+prefix+"["+key+"]");
}
}
}
else if (Array.isArray(schema)) {
if (schema.length > 1) {
throw new Error("An array in a schema can have at most one element. Found "+schema.length+" elements in "+prefix)
}
else if (schema.length === 1) {
if (isPlainObject(schema[0])) {
validateSchema(schema[0], prefix+'[0]');
}
else if (Array.isArray(schema[0])) {
validateSchema(schema[0], prefix+'[0]');
}
else{
if ((schema[0] !== String)
&& (schema[0] !== Number)
&& (schema[0] !== Boolean)
&& (schema[0] !== Date)
&& (schema[0] !== Buffer)
&& (schema[0] !== Object)
&& (schema[0] !== Array)
&& (schema[0] !== 'Point')) {
throw new Error("The field `_type` must be `String`/`Number`/`Boolean`/`Date`/`Buffer`/`Object`/`Array`/`'Point'` in "+prefix);
}
}
}
}
else {
throw new Error("The schema must be a plain object.")
}
}
util.validateSchema = validateSchema;
// Obviously not a real deep copy...

@@ -100,7 +21,7 @@ function deepCopy(value) {

result = {};
for(var key in value) {
if (value.hasOwnProperty(key)) {
result[key] = deepCopy(value[key]);
loopKeys(value, function(_value, key) {
if (_value.hasOwnProperty(key)) {
result[key] = deepCopy(_value[key]);
}
}
});
return result;

@@ -121,31 +42,3 @@ }

function undefinedField(prefix) {
throw new Error("Value for "+prefix+" must be defined.")
}
util.undefinedField = undefinedField;
function strictType(prefix, expected) {
throw new Error("Value for "+prefix+" must be a "+expected+".")
}
util.strictType = strictType;
function extraField(prefix, key) {
if (prefix === '') {
throw new Error("Extra field `"+key+"` not allowed.")
}
else {
throw new Error("Extra field `"+key+"` in "+prefix+" not allowed.")
}
}
util.extraField = extraField;
function looseType(prefix, expected) {
throw new Error("Value for "+prefix+" must be a "+expected+" or null.")
}
util.looseType = looseType;
function pseudoTypeError(type, missingField, prefix) {
throw new Error("The raw "+type+" object for "+prefix+" is missing the required field "+missingField+".")
}
util.pseudoTypeError = pseudoTypeError;
function tryCatch(toTry, handleError) {

@@ -167,10 +60,17 @@ try{

var preHooks = options.preHooks;
if (Array.isArray(preHooks) === false) {
preHooks = [];
}
var postHooks = options.postHooks;
if (Array.isArray(postHooks) === false) {
postHooks = [];
}
var doc = options.doc; // We need the doc to set the context of the hooks
var async = options.async || false;
var fn = options.fn; // The function that we are hook
var fnArgs = options.fnArgs;
if (async === true) {
return new Promise(function(resolve, reject) {
_hook({
_asyncHook({
resolve: resolve,

@@ -181,3 +81,4 @@ reject: reject,

doc: doc,
fn: fn
fn: fn,
fnArgs: fnArgs
});

@@ -187,88 +88,130 @@ });

else {
return _hook(options);
return _syncHook({
preHooks: preHooks,
postHooks: postHooks,
doc: doc,
fn: fn,
fnArgs: fnArgs
});
}
}
function _hook(options) {
var doc = options.doc;
function _syncHook(args) {
var preHooks = args.preHooks;
var postHooks = args.postHooks;
var fn = args.fn;
var doc = args.doc;
var fnArgs = args.fnArgs;
var preHooks = options.preHooks;
var postHooks = options.postHooks;
for(var i=0; i<preHooks.length; i++) {
preHooks[i].call(doc);
}
var result = fn.apply(doc, fnArgs);
for(var j=0; j<postHooks.length; j++) {
postHooks[j].call(doc);
}
return result;
}
function _asyncHook(args) {
// One of the hook, or the function is asynchronous, so we will
// always return a promise
// We only need to keep track of the result return/resolved for fn
var fn = options.fn;
var resolve = options.resolve;
var reject = options.reject;
var preHooks = args.preHooks;
var postHooks = args.postHooks;
var fn = args.fn;
var fnArgs = args.fnArgs;
var doc = args.doc;
var resolve = args.resolve;
var reject = args.reject;
var args = args.args;
var promise, result;
var result;
var hookIndex = 0;
var executePostHooks = function() {
if ((Array.isArray(postHooks)) && (hookIndex < postHooks.length)) {
postHooks[hookIndex].call(doc, function(err) {
if (err) {
if (typeof reject === 'function') {
return reject(err)
}
else {
throw err;
}
}
hookIndex++;
executePostHooks()
});
var nextPost = function() {
if (typeof resolve === "function") {
resolve(result);
}
return result;
}
var executeMain = function() {
result = fn.apply(doc, fnArgs);
if (result instanceof Promise) {
return result.then(function(res) {
result = res;
executeHooks(0, postHooks, doc, reject, nextPost);
}).error(reject);
}
else {
if (typeof resolve === 'function') {
resolve(result);
}
return executeHooks(0, postHooks, doc, reject, nextPost);
}
}
var executePreHooks = function() {
if ((Array.isArray(preHooks)) && (hookIndex < preHooks.length)) {
preHooks[hookIndex].call(doc, function(err) {
if (err) {
if (typeof reject === 'function') {
return reject(err)
}
else {
throw err;
}
}
hookIndex++;
executePreHooks()
var nextPre = function() {
tryCatch(executeMain, function (err) {
return reject(err);
});
}
return executeHooks(0, preHooks, doc, reject, nextPre);
}
util.hook = hook;
function executeHooks(hookIndex, hooks, doc, reject, next) {
if (hookIndex < hooks.length) {
if (hooks[hookIndex].length === 1) {
hooks[hookIndex].call(doc, function(err) {
if (err) return reject(err);
executeHooks(hookIndex+1, hooks, doc, reject, next)
});
}
else {
tryCatch(function() {
promise = fn.bind(doc)();
}, function(err) {
if (typeof reject === 'function') {
reject(err);
}
else {
throw err;
}
});
if (promise instanceof Promise) {
promise.then(function(res) {
result = res;
hookIndex = 0;
executePostHooks();
}).error(reject);
}
else {
result = promise;
hookIndex = 0;
executePostHooks();
}
hooks[hookIndex](doc);
executeHooks(hookIndex+1, hooks, doc, reject, next)
}
}
executePreHooks();
if ((typeof resolve !== 'function') && (promise instanceof Promise)) {
// No hook is asynchronous, but `fn` returned a promise
return promise;
else {
next();
}
}
util.hook = hook;
function loopKeys(obj, fn) {
if (isPlainObject(obj)) {
var keys = Object.keys(obj);
var result;
for(var i=0; i<keys.length; i++) {
result = fn(obj, keys[i]);
if (result === false) return;
}
}
}
util.loopKeys = loopKeys;
function changeProto(object, newProto) {
object.__proto__ = newProto;
}
util.changeProto = changeProto;
function recurse(key, joins, modelTo, all, done) {
return (util.isPlainObject(modelTo) && modelTo.hasOwnProperty(key))
|| ((all === true) && (done[joins[key].model.getTableName()] !== true))
}
util.recurse = recurse;
function bindEmitter(self) {
util.loopKeys(EventEmitter.prototype, function(emitter, key) {
var fn = emitter[key];
if (typeof fn === 'function') {
self[key] = function() {
var args = new Array(arguments.length);
for(var i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
fn.apply(self, args);
}
}
});
}
util.bindEmitter = bindEmitter;
module.exports = util;
{
"name": "thinky",
"version": "1.15.0",
"version": "1.15.1",
"description": "RethinkDB ORM for Node.js",

@@ -10,3 +10,3 @@ "main": "lib/thinky.js",

"scripts": {
"test": "mocha --check-leaks -t 30000"
"test": "mocha --check-leaks -t 5000"
},

@@ -13,0 +13,0 @@ "repository": {

@@ -73,3 +73,3 @@ # Thinky

```js
Post.get("0e4a6f6f-cc0c-4aa5-951a-fcfc480dd05a").getJoin().then(function(result) {
Post.get("0e4a6f6f-cc0c-4aa5-951a-fcfc480dd05a").getJoin().run().then(function(result) {
/*

@@ -109,6 +109,7 @@ result = {

### Roadmap
- Make the tests faster (by using less tables)
- Merge write queries into a unique one?
The roadmap is defined with the issues/feedback on GitHub. Checkout:
[https://github.com/neumino/thinky/issues](https://github.com/neumino/thinky/issues)
### Author

@@ -120,2 +121,3 @@ - Michel Tu -- orphee@gmail.com -- [blog](http://blog.justonepixel.com) -- [twitter](https://twitter.com/neumino)

- [colprog](https://github.com/colprog)
- [dulichan](https://github.com/dulichan)
- [flienteen](https://github.com/flienteen)

@@ -122,0 +124,0 @@ - [marshall007](https://github.com/marshall007)

Sorry, the diff of this file is too big to display

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