Comparing version 0.0.15 to 0.0.16
@@ -162,15 +162,55 @@ var util = require('util'), | ||
var tasks = []; | ||
if (this.fetchMetadata) { | ||
tasks.push(function fetchMetadataTask(next) { | ||
this.fetchMetadata(function fetchMetadataTaskCallback(err, metadata) { | ||
if (err) { return next(err); } | ||
if (metadata) { | ||
this.metadata = _.merge(this.metadata || {}, metadata); | ||
} | ||
next(); | ||
}.bind(this)); | ||
}.bind(this)); | ||
} | ||
else { | ||
// no metadata, let's just make an empty one | ||
tasks.push(function metadataTask(next) { | ||
if (!this.metadata) { | ||
this.metadata = { schema: undefined }; | ||
} | ||
next(); | ||
}.bind(this)); | ||
} | ||
if (this.fetchConfig) { | ||
tasks.push(function fetchConfigTask(next){ | ||
this.fetchConfig(function fetchConfigTaskCallback(err,config){ | ||
tasks.push(function fetchConfigTask(next) { | ||
this.fetchConfig(function fetchConfigTaskCallback(err, config) { | ||
if (err) { return next(err); } | ||
// basically, the construtors config should override | ||
// basically, the constructors config should override | ||
// our default config from the connector | ||
this.config = _.merge(config,this.config); | ||
next(); | ||
this.config = _.merge(config, this.config); | ||
var possibleErr = this.validateConfig(); | ||
if (possibleErr !== true) { | ||
next(possibleErr); | ||
} | ||
else { | ||
next(); | ||
} | ||
}.bind(this)); | ||
}.bind(this)); | ||
} | ||
else { | ||
tasks.push(function configTask(next) { | ||
if (!this.config) { | ||
this.config = {}; | ||
} | ||
var possibleErr = this.validateConfig(); | ||
if (possibleErr !== true) { | ||
next(possibleErr); | ||
} | ||
else { | ||
next(); | ||
} | ||
}.bind(this)); | ||
} | ||
if (this._connect) { | ||
tasks.push(function connectTask(next){ | ||
tasks.push(function connectTask(next) { | ||
this._connect(next); | ||
@@ -180,8 +220,7 @@ }.bind(this)); | ||
if (this.fetchSchema) { | ||
tasks.push(function fetchSchemaTask(next){ | ||
this.fetchSchema(function fetchSchemaTaskCallback(err,schema){ | ||
tasks.push(function fetchSchemaTask(next) { | ||
this.fetchSchema(function fetchSchemaTaskCallback(err, schema) { | ||
if (err) { return next(err); } | ||
if (schema) { | ||
// hold it temporarily | ||
this._schema = _.merge(this.schema||{}, schema); | ||
this.metadata = _.merge(this.metadata || {}, { schema: schema }); | ||
} | ||
@@ -192,29 +231,3 @@ next(); | ||
} | ||
if (this.fetchMetadata) { | ||
tasks.push(function fetchMetadataTask(next){ | ||
this.fetchMetadata(function fetchMetadataTaskCallback(err,metadata){ | ||
if (err) { return next(err); } | ||
if (metadata) { | ||
this.metadata = _.merge(this.metadata||{}, metadata); | ||
this.metadata.schema = this._schema; | ||
} | ||
else { | ||
this.metadata = _.merge(this.metadata||{}, {schema: this._schema}); | ||
} | ||
delete this._schema; | ||
next(); | ||
}.bind(this)); | ||
}.bind(this)); | ||
} | ||
else { | ||
// no metadata, let's just make one with schema | ||
tasks.push(function metadataTask(next){ | ||
if (!this.metadata || !this.metadata.schema){ | ||
this.metadata = _.merge(this.metadata||{}, {schema: this._schema}); | ||
delete this._schema; | ||
} | ||
next(); | ||
}.bind(this)); | ||
} | ||
async.series(tasks, function connectCallback(err){ | ||
async.series(tasks, function connectCallback(err) { | ||
if (err) { return callback(err); } | ||
@@ -225,1 +238,31 @@ this.connected = true; | ||
}; | ||
/** | ||
* Validates whether or not the config for this connector is valid, based on its metadata. | ||
* @returns {boolean} True if the config is valid, otherwise an Error. | ||
*/ | ||
Connector.prototype.validateConfig = function validateConfig() { | ||
var metadata = this.metadata, | ||
config = this.config || {}; | ||
if (!metadata || !metadata.fields || !metadata.fields.length) { | ||
return true; | ||
} | ||
for (var i = 0; i < metadata.fields.length; i++) { | ||
var field = metadata.fields[i]; | ||
if (!config[field.name]) { | ||
if (field.required) { | ||
return new Error(field.name + ' is a required config property for the ' + this.name + ' connector!'); | ||
} | ||
if (field.default !== undefined) { | ||
config[field.name] = field.default; | ||
} | ||
} | ||
else if (field.validator && !field.validator.test(config[field.name])) { | ||
return new Error('The value "' + config[field.name] + '" for ' + field.name + ' is invalid for the ' + this.name + ' connector!'); | ||
} | ||
} | ||
return true; | ||
}; |
{ | ||
"name": "api-orm", | ||
"version": "0.0.15", | ||
"version": "0.0.16", | ||
"description": "API Builder ORM", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -231,2 +231,63 @@ var should = require('should'), | ||
it("should support validating config from schema", function(next){ | ||
var MyConnector = orm.Connector.extend({ | ||
name: 'MyConnector', | ||
fetchMetadata: function(callback) { | ||
callback(null, { | ||
fields: [ | ||
{ | ||
name: 'url', | ||
required: true, | ||
default: '', | ||
validator: new RegExp( | ||
"^" + | ||
// protocol identifier (optional) + // | ||
"(?:(?:https?:)?//)?" + | ||
// user:pass authentication (optional) | ||
"(?:\\S+(?::\\S*)?@)?" + | ||
// host (optional) + domain + tld | ||
"(?:(?!-)[-a-z0-9\\u00a1-\\uffff]*[a-z0-9\\u00a1-\\uffff]+(?!./|\\.$)\\.?){2,}" + | ||
// server port number (optional) | ||
"(?::\\d{2,5})?" + | ||
// resource path (optional) | ||
"(?:/\\S*)?" + | ||
"$", "i" | ||
) | ||
} | ||
] | ||
}); | ||
} | ||
}); | ||
var connector = new MyConnector(); | ||
connector.connect(function(err) { | ||
should(err).be.ok; | ||
should(err.message).containEql('url is a required config property'); | ||
connector = new MyConnector({ | ||
url: '' | ||
}); | ||
connector.connect(function(err) { | ||
should(err).be.ok; | ||
should(err.message).containEql('url is a required config property'); | ||
connector = new MyConnector({ | ||
url: 'ht://bad' | ||
}); | ||
connector.connect(function(err) { | ||
should(err).be.ok; | ||
should(err.message).containEql('for url is invalid for the'); | ||
connector = new MyConnector({ | ||
url: 'http://a.good.com/url/for/the/config' | ||
}); | ||
connector.connect(function(err) { | ||
should(err).be.not.ok; | ||
next(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it("should support only fetchConfig method", function(callback){ | ||
@@ -276,3 +337,3 @@ var MyConnector = orm.Connector.extend({ | ||
should(err).not.be.ok; | ||
should(connector.metadata).be.an.object; | ||
should(connector.metadata).be.an.Object; | ||
should(connector.metadata).have.property('schema'); | ||
@@ -279,0 +340,0 @@ should(connector.metadata.schema).have.property('foo','bar'); |
Sorry, the diff of this file is not supported yet
98124
3228