Allow asteroid modules to define and validate options
This commit is contained in:
parent
fc8afa066e
commit
621b845978
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"module": "oracle-connection",
|
||||||
|
"options": {
|
||||||
|
"hostname": "127.0.0.1",
|
||||||
|
"port": 1234
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,4 +25,36 @@ A configuration then must define:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Where `some-model-module` is an existing `model` instance.
|
Where `some-model-module` is an existing `model` instance.
|
||||||
|
|
||||||
|
## AsteroidModule.options
|
||||||
|
|
||||||
|
Asteroid Modules may also describe the options they accept. This will validate the configuration and make sure users have supplied required information and in a way that the module can use to construct a working instance.
|
||||||
|
|
||||||
|
Here is an example options description for the [oracle database connection module](../connections/oracle-connection).
|
||||||
|
|
||||||
|
// must come after `inherits()`
|
||||||
|
OracleConnection.defineOption('hostname', 'string', {required: true});
|
||||||
|
OracleConnection.defineOption('port', 'number', {min: 10, max: 99999});
|
||||||
|
OracleConnection.defineOption('username', 'string');
|
||||||
|
OracleConnection.defineOption('password', 'string');
|
||||||
|
|
||||||
|
|
||||||
|
### AsteroidModule.defineOption(key, type, [options])
|
||||||
|
|
||||||
|
**key** the option name given in `config.json`.
|
||||||
|
|
||||||
|
**type** must be one of:
|
||||||
|
|
||||||
|
- string
|
||||||
|
- boolean
|
||||||
|
- number
|
||||||
|
- array
|
||||||
|
|
||||||
|
**options** depend on the type
|
||||||
|
|
||||||
|
{
|
||||||
|
required: true, // options are optional by default
|
||||||
|
min: 10, // minimum length or value
|
||||||
|
max: 100, // max length or value
|
||||||
|
}
|
|
@ -1,12 +0,0 @@
|
||||||
/**
|
|
||||||
* A generated `AsteroidModule` example...
|
|
||||||
*
|
|
||||||
* Examples should show a working module api
|
|
||||||
* and be used in tests to continously check
|
|
||||||
* they function as expected.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var AsteroidModule = require('../');
|
|
||||||
var asteroidModule = AsteroidModule.create();
|
|
||||||
|
|
||||||
asteroidModule.myMethod();
|
|
|
@ -27,7 +27,7 @@ function AsteroidModule(options) {
|
||||||
// throw an error if args are not supplied
|
// throw an error if args are not supplied
|
||||||
assert(typeof options === 'object', 'AsteroidModule requires an options object');
|
assert(typeof options === 'object', 'AsteroidModule requires an options object');
|
||||||
|
|
||||||
this.options = options;
|
this.options = validateOptions(options, this.constructor.optionsDefinition);
|
||||||
|
|
||||||
debug('created with options', options);
|
debug('created with options', options);
|
||||||
}
|
}
|
||||||
|
@ -36,4 +36,54 @@ function AsteroidModule(options) {
|
||||||
* Inherit from `Module`.
|
* Inherit from `Module`.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inherits(AsteroidModule, Module);
|
inherits(AsteroidModule, Module);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define an option of the given key/name with the provided type.
|
||||||
|
*/
|
||||||
|
|
||||||
|
AsteroidModule.defineOption = function (key, type, options) {
|
||||||
|
var od = this.optionsDefinition = this.optionsDefinition || {};
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
options.type = type;
|
||||||
|
|
||||||
|
od[key] = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateOptions(options, def) {
|
||||||
|
if(!def) {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(def).forEach(function (key) {
|
||||||
|
var val = options[key];
|
||||||
|
var keyDef = def[key] || {};
|
||||||
|
|
||||||
|
if(keyDef.required) {
|
||||||
|
assert(val, key + ' is required!');
|
||||||
|
}
|
||||||
|
|
||||||
|
// type
|
||||||
|
assert(typeof val == keyDef.type, key + ' must be a ' + keyDef.type);
|
||||||
|
|
||||||
|
// size / length
|
||||||
|
if(typeof val.length === 'number') {
|
||||||
|
if(keyDef.min) {
|
||||||
|
assert(val.length >= keyDef.min, key + ' length must be greater than or equal to ', keyDef.min);
|
||||||
|
}
|
||||||
|
if(keyDef.max) {
|
||||||
|
assert(val.length <= keyDef.min, key + ' length must be less than or equal to ', keyDef.max);
|
||||||
|
}
|
||||||
|
} else if(typeof val === 'number') {
|
||||||
|
if(keyDef.min) {
|
||||||
|
assert(val >= keyDef.min, key + ' must be greater than or equal to ', keyDef.min);
|
||||||
|
}
|
||||||
|
if(keyDef.max) {
|
||||||
|
assert(val <= keyDef.max, ' must be less than or equal to ', keyDef.max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ module.exports = Connection;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var AsteroidModule = require('asteroid-module')
|
var AsteroidModule = require('asteroid-module')
|
||||||
,
|
|
||||||
, debug = require('debug')('connection')
|
, debug = require('debug')('connection')
|
||||||
, util = require('util')
|
, util = require('util')
|
||||||
, inherits = util.inherits
|
, inherits = util.inherits
|
||||||
|
@ -26,6 +25,13 @@ function Connection(options) {
|
||||||
AsteroidModule.apply(this, arguments);
|
AsteroidModule.apply(this, arguments);
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
||||||
|
// inheriting connections must provide an adapter
|
||||||
|
// otherwise throw when this connection's adapter
|
||||||
|
// is used...
|
||||||
|
this.adapter = function () {
|
||||||
|
throw new Error('connection has not provided an adapter!');
|
||||||
|
}
|
||||||
|
|
||||||
debug('created with options', options);
|
debug('created with options', options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
.DS_Store
|
||||||
|
*.seed
|
||||||
|
*.log
|
||||||
|
*.csv
|
||||||
|
*.dat
|
||||||
|
*.out
|
||||||
|
*.pid
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
node_modules/
|
|
@ -0,0 +1,13 @@
|
||||||
|
# connection
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
Provides a base class for implementing access to a persistence layer.
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
#### hostname
|
||||||
|
#### port
|
||||||
|
#### database
|
||||||
|
#### username
|
||||||
|
#### password
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* A generated `Connection` example...
|
||||||
|
*
|
||||||
|
* Examples should show a working module api
|
||||||
|
* and be used in tests to continously check
|
||||||
|
* they function as expected.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Connection = require('../');
|
||||||
|
var connection = Connection.create();
|
||||||
|
|
||||||
|
connection.myMethod();
|
|
@ -0,0 +1,5 @@
|
||||||
|
/**
|
||||||
|
* connection ~ public api
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = require('./lib/connection');
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* Expose `OracleConnection`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = OracleConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Connection = require('asteroid-module')
|
||||||
|
, debug = require('debug')('connection')
|
||||||
|
, util = require('util')
|
||||||
|
, inherits = util.inherits
|
||||||
|
, assert = require('assert');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new `OracleConnection` with the given `options`.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {Connection}
|
||||||
|
*/
|
||||||
|
|
||||||
|
function OracleConnection(options) {
|
||||||
|
AsteroidModule.apply(this, arguments);
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
debug('created with options', options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `AsteroidModule`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
inherits(OracleConnection, Connection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
OracleConnection.defineOption('hostname', 'string', {required: true});
|
||||||
|
OracleConnection.defineOption('port', 'number', {min: 10, max: 99999});
|
||||||
|
OracleConnection.defineOption('username', 'string');
|
||||||
|
OracleConnection.defineOption('password', 'string');
|
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
"name": "oracle-connection",
|
||||||
|
"description": "connection",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"jugglingdb-oracle": "latest",
|
||||||
|
"debug": "latest"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"mocha": "latest"
|
||||||
|
}
|
||||||
|
}
|
24
node_modules/connections/oracle-connection/test/connection.test.js
generated
vendored
Normal file
24
node_modules/connections/oracle-connection/test/connection.test.js
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
var Connection = require('../');
|
||||||
|
|
||||||
|
describe('Connection', function(){
|
||||||
|
var connection;
|
||||||
|
|
||||||
|
beforeEach(function(){
|
||||||
|
connection = new Connection;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.myMethod', function(){
|
||||||
|
// example sync test
|
||||||
|
it('should <description of behavior>', function() {
|
||||||
|
connection.myMethod();
|
||||||
|
});
|
||||||
|
|
||||||
|
// example async test
|
||||||
|
it('should <description of behavior>', function(done) {
|
||||||
|
setTimeout(function () {
|
||||||
|
connection.myMethod();
|
||||||
|
done();
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,5 @@
|
||||||
|
/**
|
||||||
|
* connection test setup and support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
assert = require('assert');
|
Loading…
Reference in New Issue