Socket
Socket
Sign inDemoInstall

waterline-schema

Package Overview
Dependencies
1
Maintainers
2
Versions
51
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.8 to 0.1.9

.editorconfig

10

lib/waterline-schema.js

@@ -6,7 +6,6 @@

var _ = require('lodash'),
Attributes = require('./waterline-schema/attributes'),
ForeignKeys = require('./waterline-schema/foreignKeys'),
JoinTables = require('./waterline-schema/joinTables'),
References = require('./waterline-schema/references');
var Attributes = require('./waterline-schema/attributes');
var ForeignKeys = require('./waterline-schema/foreignKeys');
var JoinTables = require('./waterline-schema/joinTables');
var References = require('./waterline-schema/references');

@@ -41,2 +40,3 @@ /**

return this.schema;
};

@@ -6,5 +6,5 @@

var _ = require('lodash'),
utils = require('./utils'),
hasOwnProperty = utils.object.hasOwnProperty;
var _ = require('lodash');
var utils = require('./utils');
var hop = utils.object.hasOwnProperty;

@@ -38,5 +38,5 @@ /**

for(var key in collections) {
var collection = this.normalize(collections[key].prototype, connections, defaults),
conns = _.cloneDeep(collection.connection),
attributes = _.cloneDeep(collection.attributes);
var collection = this.normalize(collections[key].prototype, connections, defaults);
var conns = _.cloneDeep(collection.connection);
var attributes = _.cloneDeep(collection.attributes);

@@ -56,2 +56,3 @@ this.stripFunctions(attributes);

return this.attributes;
}

@@ -69,2 +70,3 @@

Attributes.prototype.normalize = function(collection, connections, defaults) {
this.normalizeIdentity(collection);

@@ -75,2 +77,3 @@ this.setDefaults(collection, defaults);

return collection;
};

@@ -93,7 +96,7 @@

if(!hasOwnProperty(collection, 'connection')) {
if(!hop(collection, 'connection')) {
collection.connection = '';
}
if(!hasOwnProperty(collection, 'attributes')) {
if(!hop(collection, 'attributes')) {
collection.attributes = {};

@@ -109,10 +112,10 @@ }

// Override default settings with user defined defaults
if(hasOwnProperty(defaults, 'autoPK')) defaultSettings.autoPK = defaults.autoPK;
if(hasOwnProperty(defaults, 'autoCreatedAt')) defaultSettings.autoCreatedAt = defaults.autoCreatedAt;
if(hasOwnProperty(defaults, 'autoUpdatedAt')) defaultSettings.autoUpdatedAt = defaults.autoUpdatedAt;
if(hop(defaults, 'autoPK')) defaultSettings.autoPK = defaults.autoPK;
if(hop(defaults, 'autoCreatedAt')) defaultSettings.autoCreatedAt = defaults.autoCreatedAt;
if(hop(defaults, 'autoUpdatedAt')) defaultSettings.autoUpdatedAt = defaults.autoUpdatedAt;
// Override defaults with collection defined values
if(hasOwnProperty(collection, 'autoPK')) defaultSettings.autoPK = collection.autoPK;
if(hasOwnProperty(collection, 'autoCreatedAt')) defaultSettings.autoCreatedAt = collection.autoCreatedAt;
if(hasOwnProperty(collection, 'autoUpdatedAt')) defaultSettings.autoUpdatedAt = collection.autoUpdatedAt;
if(hop(collection, 'autoPK')) defaultSettings.autoPK = collection.autoPK;
if(hop(collection, 'autoCreatedAt')) defaultSettings.autoCreatedAt = collection.autoCreatedAt;
if(hop(collection, 'autoUpdatedAt')) defaultSettings.autoUpdatedAt = collection.autoUpdatedAt;

@@ -128,2 +131,3 @@ var flags = {

}
};

@@ -139,3 +143,4 @@

Attributes.prototype.normalizeIdentity = function(collection) {
if(hasOwnProperty(collection, 'tableName') && !hasOwnProperty(collection, 'identity')) {
if(hop(collection, 'tableName') && !hop(collection, 'identity')) {
collection.identity = collection.tableName.toLowerCase();

@@ -145,5 +150,6 @@ }

// Require an identity so the object key can be set
if(!hasOwnProperty(collection, 'identity')) {
if(!hop(collection, 'identity')) {
throw new Error('A Collection must include an identity or tableName attribute');
}
};

@@ -163,8 +169,10 @@

Attributes.prototype.autoAttributes = function(collection, connections) {
var attributes = collection.attributes,
pk = false;
var attributes = collection.attributes;
var pk = false;
var mainConnection;
// Check to make sure another property hasn't set itself as a primary key
for(var key in attributes) {
if(attributes[key].hasOwnProperty('primaryKey')) pk = true;
if(hop(attributes[key], 'primaryKey')) pk = true;
}

@@ -185,6 +193,12 @@

// Check if the adapter used in the collection specifies the primary key format
var mainConnection = Array.isArray(collection.connection) ? collection.connection[0] : collection.connection;
if(hasOwnProperty(connections, mainConnection)) {
if(Array.isArray(collection.connection)) {
mainConnection = collection.connection[0];
}
else {
mainConnection = collection.connection;
}
if(hop(connections, mainConnection)) {
var connection = connections[mainConnection];
if(hasOwnProperty(connection._adapter, 'pkFormat')) {
if(hop(connection._adapter, 'pkFormat')) {
attributes.id.type = connection._adapter.pkFormat;

@@ -208,2 +222,3 @@ }

}
};

@@ -219,5 +234,7 @@

Attributes.prototype.stripFunctions = function(attributes) {
for(var attribute in attributes) {
if(typeof attributes[attribute] === 'function') delete attributes[attribute];
}
};

@@ -233,5 +250,7 @@

Attributes.prototype.stripProperties = function(attributes) {
for(var attribute in attributes) {
this.stripProperty(attributes[attribute]);
}
};

@@ -247,2 +266,3 @@

Attributes.prototype.stripProperty = function(properties) {
for(var prop in properties) {

@@ -252,2 +272,3 @@ if(utils.reservedWords.indexOf(prop) > -1) continue;

}
};

@@ -263,2 +284,3 @@

Attributes.prototype.validatePropertyNames = function(attributes) {
for(var attribute in attributes) {

@@ -273,2 +295,3 @@

}
};

@@ -6,5 +6,5 @@

var _ = require('lodash'),
utils = require('./utils'),
hasOwnProperty = utils.object.hasOwnProperty;
var _ = require('lodash');
var utils = require('./utils');
var hop = utils.object.hasOwnProperty;

@@ -26,2 +26,3 @@ /**

function ForeignKeys(collections) {
collections = collections || {};

@@ -35,2 +36,3 @@ this.collections = _.clone(collections);

return collections;
}

@@ -48,4 +50,7 @@

for(var attribute in attributes) {
if(!attributes[attribute].model) continue;
// We only care about adding foreign key values to attributes
// with a `model` key
if(!hop(attributes[attribute], 'model')) continue;
var modelName = attributes[attribute].model.toLowerCase();

@@ -78,5 +83,7 @@ var primaryKey = this.findPrimaryKey(modelName);

ForeignKeys.prototype.findPrimaryKey = function(collection) {
if(!this.collections[collection]) {
throw new Error('Trying to access a collection ' + collection + ' that is not defined.');
}
if(!this.collections[collection].attributes) {

@@ -91,3 +98,3 @@ throw new Error('Collection, ' + collection + ', has no attributes defined.');

if(!hasOwnProperty(attribute, 'primaryKey')) continue;
if(!hop(attribute, 'primaryKey')) continue;

@@ -106,2 +113,3 @@ primaryKey = {

return primaryKey;
};

@@ -122,4 +130,6 @@

ForeignKeys.prototype.buildColumnName = function(key, attribute) {
if(hasOwnProperty(attribute, 'columnName')) return attribute.columnName;
if(hop(attribute, 'columnName')) return attribute.columnName;
return key;
};

@@ -6,5 +6,5 @@

var _ = require('lodash'),
utils = require('./utils'),
hasOwnProperty = utils.object.hasOwnProperty;
var _ = require('lodash');
var utils = require('./utils');
var hop = utils.object.hasOwnProperty;

@@ -27,11 +27,17 @@ /**

function JoinTables(collections) {
var self = this;
var joinTables;
collections = collections || {};
this.collections = _.cloneDeep(collections);
this.tables = {};
this.collections = _.cloneDeep(collections);
// Build Up Join Tables
for(var collection in collections) {
var joinTables = this.buildJoins(collection);
// Parse the collection's attributes and create join tables
// where needed for collections
joinTables = this.buildJoins(collection);
this.uniqueTables(joinTables);

@@ -52,2 +58,3 @@

return _.extend(this.collections, this.tables);
}

@@ -64,6 +71,9 @@

JoinTables.prototype.buildJoins = function(collection) {
var attributes = this.collections[collection].attributes,
collectionAttributes = this.mapCollections(attributes),
tables = [];
var self = this;
var tables = [];
var attributes = this.collections[collection].attributes;
var collectionAttributes = this.mapCollections(attributes);
// If there are no collection attributes return an empty array

@@ -73,58 +83,40 @@ if(Object.keys(collectionAttributes).length === 0) return [];

// For each collection attribute, inspect it to build up a join table if needed.
for(var attribute in collectionAttributes) {
collectionAttributes.forEach(function(attribute) {
var table = self.parseAttribute(collection, attribute);
if(table) tables.push(self.buildTable(table));
});
// Check the collection it references to see if this is a one-to-many or many-to-many
// relationship. If it's a one-to-many we don't need to build up a join table.
var attr = collectionAttributes[attribute];
return tables;
// Ensure the attribute has a `via` property
if(!hasOwnProperty(attr, 'via')) {
throw new Error('Collection ' + collection + ' has an association attribute that is missing a '+
'`via` property. Any associations with a `collection` attribute must specify a `via` option ' +
'that points to another attribute. Update the attribute: ' + attribute + ' and add a `via` property');
}
};
// Check if this is a hasManyThrough attribute, if so a join table doesn't need to be created
if(hasOwnProperty(attr, 'through')) continue;
/**
* Find Has Many attributes for a given set of attributes.
*
* @param {Object} attributes
* @return {Object}
* @api private
*/
// Normalize `collection` property name to lowercased version
attr.collection = attr.collection.toLowerCase();
JoinTables.prototype.mapCollections = function(attributes) {
var child = this.collections[attr.collection];
var collectionAttributes = [];
// Ensure the `via` exists on the child.
if(!hasOwnProperty(child.attributes, attr.via)) {
throw new Error('Collection ' + collection + ' has a `via` attribute which is missing from the ' +
'collection ' + attr.collection);
}
for(var attribute in attributes) {
if(!hop(attributes[attribute], 'collection')) continue;
collectionAttributes.push({ key: attribute, val: attributes[attribute] });
}
// If the associated attribute is a foreign key, ignore it
if(hasOwnProperty(child.attributes[attr.via], 'foreignKey')) continue;
return collectionAttributes;
// Build up an object that can be used to build a join table
var tableAttributes = {
column_one: {
collection: collection.toLowerCase(),
attribute: attribute,
via: attr.via
},
column_two: {
collection: attr.collection,
attribute: attr.via,
via: attribute
}
};
// Build join tables
tables = tables.concat(this.buildTable(tableAttributes));
}
return tables;
};
/**
* Find Has Many attributes for a given set of attributes.
* Parse Collection Attributes
*
* @param {Object} attributes
* Check the collection the attribute references to see if this is a one-to-many or many-to-many
* relationship. If it's a one-to-many we don't need to build up a join table.
*
* @param {String} collectionName
* @param {Object} attribute
* @return {Object}

@@ -134,11 +126,55 @@ * @api private

JoinTables.prototype.mapCollections = function(attributes) {
var collectionAttributes = {};
JoinTables.prototype.parseAttribute = function(collectionName, attribute) {
for(var attribute in attributes) {
if(!hasOwnProperty(attributes[attribute], 'collection')) continue;
collectionAttributes[attribute] = attributes[attribute];
var error = '';
var attr = attribute.val;
// Check if this is a hasManyThrough attribute,
// if so a join table doesn't need to be created
if(hop(attr, 'through')) return;
// Normalize `collection` property name to lowercased version
attr.collection = attr.collection.toLowerCase();
// Grab the associated collection and ensure it exists
var child = this.collections[attr.collection];
if(!child) {
error = 'Collection ' + collectionName + ' has an attribute named ' + attribute.key + ' that is ' +
'pointing to a collection named ' + attr.collection + ' which doesn\'t exist. You must ' +
' first create the ' + attr.collection + ' collection.';
throw new Error(error);
}
return collectionAttributes;
// If the attribute has a `via` key, check if it's a foreign key. If so this is a one-to-many
// relationship and no join table is needed.
if(hop(attr, 'via') && hop(child.attributes[attr.via], 'foreignKey')) return;
// If no via is specified, look and see if there is a connection on the other side of the
// association that points to the attribute. If so we should automatically link these two
// sides together. If not a name needs to be created for the other column
// in the join table. Use the attribute key and the associated collection name
// which will be unique.
var childLink = this.searchForAttribute(attr.collection, 'via', attribute.key);
if(childLink) attr.via = childLink;
if(!hop(attr, 'via')) attr.via = attribute.key + '_' + attr.collection;
// Build up an object that can be used to build a join table
var tableAttributes = {
column_one: {
collection: collectionName.toLowerCase(),
attribute: attribute.key,
via: attr.via
},
column_two: {
collection: attr.collection,
attribute: attr.via,
via: attribute.key
}
};
return tableAttributes;
};

@@ -149,3 +185,3 @@

*
* @apram {Object} columns
* @param {Object} columns
* @return {Object}

@@ -156,4 +192,4 @@ * @api private

JoinTables.prototype.buildTable = function(columns) {
var table = {};
var c1 = columns.column_one;

@@ -178,3 +214,3 @@ var c2 = columns.column_two;

// Add each foreign key as an attribute
// Set a primary key (should probably be refactored)
table.attributes = {

@@ -188,2 +224,3 @@ id: {

// Add each foreign key as an attribute
table.attributes[c1.collection + '_' + c1.attribute] = this.buildForeignKey(c1, c2);

@@ -196,2 +233,3 @@ table.attributes[c2.collection + '_' + c2.attribute] = this.buildForeignKey(c2, c1);

return table;
};

@@ -217,2 +255,3 @@

return c2.collection + '_' + c2.attribute + '__' + c1.collection + '_' + c1.attribute;
};

@@ -232,2 +271,3 @@

var c2 = this.collections[columns.column_two.collection];
var dominantCollection;

@@ -239,3 +279,3 @@ // Don't require a dominant collection on self-referencing associations

var dominantCollection = this.searchForAttribute(columns.column_one.collection, 'dominant');
dominantCollection = this.searchForAttribute(columns.column_one.collection, 'dominant');
if(dominantCollection) return c1.connection;

@@ -252,2 +292,3 @@

return false;
};

@@ -260,2 +301,3 @@

* @param {String} attributeName
* @param {String} value (optional)
* @return {String}

@@ -265,12 +307,16 @@ * @api private

JoinTables.prototype.searchForAttribute = function(collectionName, attributeName) {
var collection = this.collections[collectionName],
matching;
JoinTables.prototype.searchForAttribute = function(collectionName, attributeName, value) {
var collection = this.collections[collectionName];
var matching;
var properties;
Object.keys(collection.attributes).forEach(function(key) {
var properties = collection.attributes[key];
if(hasOwnProperty(properties, attributeName)) matching = key;
properties = collection.attributes[key];
if(!value && hop(properties, attributeName)) matching = key;
if(hop(properties, attributeName) && properties[attributeName] === value) matching = key;
});
return matching;
};

@@ -288,2 +334,3 @@

JoinTables.prototype.buildForeignKey = function(column_one, column_two) {
var primaryKey = this.findPrimaryKey(column_one.collection);

@@ -302,2 +349,3 @@ var columnName = (column_one.collection + '_' + column_one.attribute);

};
};

@@ -313,2 +361,3 @@

JoinTables.prototype.uniqueTables = function(tables) {
var self = this;

@@ -328,5 +377,6 @@

if(hasOwnProperty(self.tables, table.identity)) return;
if(hop(self.tables, table.identity)) return;
if(add) self.tables[table.identity] = table;
});
};

@@ -343,5 +393,11 @@

JoinTables.prototype.findPrimaryKey = function(collection) {
var primaryKey = null;
var attribute;
var error;
if(!this.collections[collection]) {
throw new Error('Trying to access a collection ' + collection + ' that is not defined.');
}
if(!this.collections[collection].attributes) {

@@ -351,8 +407,6 @@ throw new Error('Collection, ' + collection + ', has no attributes defined.');

var primaryKey = null;
for(var key in this.collections[collection].attributes) {
var attribute = this.collections[collection].attributes[key];
attribute = this.collections[collection].attributes[key];
if(!hasOwnProperty(attribute, 'primaryKey')) continue;
if(!hop(attribute, 'primaryKey')) continue;

@@ -366,3 +420,3 @@ primaryKey = {

if(!primaryKey) {
var error = 'Trying to create an association on a model that doesn\'t have a Primary Key.';
error = 'Trying to create an association on a model that doesn\'t have a Primary Key.';
throw new Error(error);

@@ -372,2 +426,3 @@ }

return primaryKey;
};

@@ -382,2 +437,3 @@

JoinTables.prototype.linkAttributes = function() {
for(var collection in this.collections) {

@@ -387,2 +443,3 @@ var attributes = this.collections[collection].attributes;

}
};

@@ -401,3 +458,3 @@

for(var attribute in attributes) {
if(!hasOwnProperty(attributes[attribute], 'collection')) continue;
if(!hop(attributes[attribute], 'collection')) continue;

@@ -413,2 +470,5 @@ var attr = attributes[attribute];

// If the table doesn't know about the other side ignore updating anything
if(!hop(joined.table.attributes, collection + '_' + attribute)) continue;
this.collections[collection].attributes[attribute] = {

@@ -420,2 +480,3 @@ collection: joined.table.identity,

}
};

@@ -434,6 +495,7 @@

JoinTables.prototype.markCustomJoinTables = function(collection) {
var attributes = this.collections[collection].attributes;
for(var attribute in attributes) {
if(!hasOwnProperty(attributes[attribute], 'through')) continue;
if(!hop(attributes[attribute], 'through')) continue;

@@ -453,2 +515,3 @@ var linkedCollection = attributes[attribute].through;

}
};

@@ -466,8 +529,9 @@

JoinTables.prototype.findReference = function(parent, collection) {
var attributes = this.collections[collection].attributes,
reference;
var attributes = this.collections[collection].attributes;
var reference;
for(var attribute in attributes) {
if(!hasOwnProperty(attributes[attribute], 'foreignKey')) continue;
if(!hasOwnProperty(attributes[attribute], 'references')) continue;
if(!hop(attributes[attribute], 'foreignKey')) continue;
if(!hop(attributes[attribute], 'references')) continue;
if(attributes[attribute].references !== parent) continue;

@@ -480,2 +544,3 @@

return reference;
};

@@ -494,5 +559,6 @@

JoinTables.prototype.findJoinTable = function(parent, child, via) {
var join = false,
tableCollection;
var join = false;
var tableCollection;
for(var table in this.tables) {

@@ -506,3 +572,3 @@ var tables = this.tables[table].tables;

if(!hasOwnProperty(this.tables[table].attributes, column)) continue;
if(!hop(this.tables[table].attributes, column)) continue;

@@ -515,2 +581,3 @@ join = true;

return { join: join, table: tableCollection };
};

@@ -6,5 +6,5 @@

var _ = require('lodash'),
utils = require('./utils'),
hasOwnProperty = utils.object.hasOwnProperty;
var _ = require('lodash');
var utils = require('./utils');
var hop = utils.object.hasOwnProperty;

@@ -27,2 +27,3 @@ /**

function References(collections) {
collections = collections || {};

@@ -36,2 +37,3 @@ this.collections = _.clone(collections);

return this.collections;
}

@@ -47,7 +49,8 @@

References.prototype.addKeys = function(collection) {
var attributes = this.collections[collection].attributes,
reference;
var attributes = this.collections[collection].attributes;
var reference;
for(var attribute in attributes) {
if(!hasOwnProperty(attributes[attribute], 'collection')) continue;
if(!hop(attributes[attribute], 'collection')) continue;

@@ -60,3 +63,3 @@ // If references have already been configured, continue on

// Check For HasMany Through
if(hasOwnProperty(attributes[attribute], 'through')) {
if(hop(attributes[attribute], 'through')) {
reference = this.findReference(attributes[attribute].collection.toLowerCase(), attributes[attribute].through.toLowerCase());

@@ -79,2 +82,3 @@ if(!reference) continue;

}
};

@@ -98,9 +102,9 @@

var attributes = this.collections[collection].attributes,
reference,
matchingAttributes = [];
var attributes = this.collections[collection].attributes;
var reference;
var matchingAttributes = [];
for(var attr in attributes) {
if(!hasOwnProperty(attributes[attr], 'foreignKey')) continue;
if(!hasOwnProperty(attributes[attr], 'references')) continue;
if(!hop(attributes[attr], 'foreignKey')) continue;
if(!hop(attributes[attr], 'references')) continue;
if(attributes[attr].references !== parent) continue;

@@ -122,3 +126,3 @@

if(matchingAttributes.length > 1) {
if(!hasOwnProperty(attribute, 'via')) {
if(!hop(attribute, 'via')) {
throw new Error('Multiple foreign keys were found on ' + collection + '. You need to specify a ' +

@@ -129,4 +133,4 @@ 'foreign key to use by adding in the `via` property to the collection association');

// Find the collection attribute used in the `via` property
var via = false,
viaName;
var via = false;
var viaName;

@@ -150,2 +154,3 @@ matchingAttributes.forEach(function(attr) {

return reference;
};
{
"name": "waterline-schema",
"description": "The core schema builder used in the Waterline ORM.",
"version": "0.1.8",
"version": "0.1.9",
"contributors": [

@@ -6,0 +6,0 @@ {

@@ -49,3 +49,2 @@ var JoinTables = require('../lib/waterline-schema/joinTables'),

var obj = new JoinTables(collections);
assert(obj.bar_foos__foo_bars);

@@ -52,0 +51,0 @@ assert(obj.bar_foos__foo_bars.identity === 'bar_foos__foo_bars');

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc