Comparing version 1.0.2 to 1.1.0
@@ -54,17 +54,8 @@ const {merge} = require('./util') | ||
// capture dependencies in a closure | ||
;(function(serviceName, serviceDef, dependencies) { | ||
// add a handle to our newly-resolved dependencies | ||
serviceDef.dependencies = dependencies | ||
const baseServiceIndex = serviceDef.callStack.length - 1 | ||
// grab a reference to the raw service as-defined | ||
const f = serviceDef.callStack[baseServiceIndex] | ||
// inject the dependencies into the base service, | ||
// while leaving the rest of the callStack untouched | ||
serviceDef.callStack[baseServiceIndex] = function(args, done) { | ||
f.call(this, args, done, serviceDef.dependencies) | ||
} | ||
})(serviceName, serviceDef, dependencies) | ||
// inject the dependencies into the base service, | ||
// while leaving the rest of the callStack untouched | ||
const baseServiceIndex = serviceDef.callStack.length - 1 | ||
const f = serviceDef.callStack[baseServiceIndex] | ||
serviceDef.dependencies = dependencies | ||
f.dependencies = dependencies | ||
} | ||
@@ -71,0 +62,0 @@ |
@@ -1,2 +0,2 @@ | ||
const {getType} = require('./util') | ||
const {getType, isFunction} = require('./util') | ||
const chain = require('./chain') | ||
@@ -22,3 +22,3 @@ const lookupArgumentFilters = require('./lookupArgumentFilters') | ||
const context = {serviceName} | ||
if (getType(service) !== 'Function') | ||
if (!isFunction(service)) | ||
throw new ServiceDefinitionNoCallableError(context) | ||
@@ -29,4 +29,4 @@ | ||
// return wrapped service | ||
var wrapper = function(params, done, dependencies) { | ||
if (arguments.length === 1) { | ||
var wrapper = function(params, done) { | ||
if (arguments.length === 1 && isFunction(params)) { | ||
done = params | ||
@@ -37,3 +37,3 @@ params = {} | ||
// execute the call stack | ||
chain(this, serviceName, params, wrapper.callStack, done, dependencies) | ||
return chain(this, serviceName, params, wrapper.callStack, done) | ||
} | ||
@@ -50,3 +50,3 @@ | ||
wrapper.callStack.unshift(...(services || [])) | ||
} else if (getType(services) === 'Function') { | ||
} else if (isFunction(services)) { | ||
wrapper.callStack.unshift(services) | ||
@@ -53,0 +53,0 @@ } |
@@ -1,2 +0,2 @@ | ||
const {getType} = require('./util') | ||
const {getType, isPromise} = require('./util') | ||
const { | ||
@@ -9,18 +9,16 @@ InvalidArgumentsObjectError, | ||
module.exports = function( | ||
context, | ||
serviceName, | ||
input, | ||
stack, | ||
cb, | ||
dependencies | ||
context, serviceName, input, stack, cb | ||
) { | ||
// defaults | ||
if (!serviceName) { | ||
serviceName = 'Service' | ||
} | ||
if (!input) { | ||
input = {} | ||
} | ||
if (!serviceName) serviceName = 'Service' | ||
if (!input) input = {} | ||
// if no callback was provided, then return a promise | ||
let p | ||
if (!cb) { | ||
cb = function() {} | ||
p = new Promise((resolve, reject) => { | ||
cb = (err, results) => { | ||
err ? reject(err) : resolve(results) | ||
} | ||
}) | ||
} | ||
@@ -30,6 +28,3 @@ | ||
if (getType(input) !== 'Object') { | ||
context = { | ||
serviceName, | ||
input, | ||
} | ||
context = {serviceName, input} | ||
return cb(new InvalidArgumentsObjectError(context)) | ||
@@ -48,10 +43,15 @@ } | ||
// run next service | ||
stack[index].call(context, args, function(err, results) { | ||
if (!results) { | ||
results = {} | ||
} | ||
let hasBeenCalled = false | ||
const service = stack[index] | ||
const processResults = function(err, results) { | ||
// only call it once | ||
if (hasBeenCalled) return | ||
hasBeenCalled = true | ||
// Law guarantees to always output an object | ||
if (!results) results = {} | ||
if (getType(results) !== 'Object') { | ||
context = { | ||
serviceName: stack[index].serviceName || serviceName, | ||
serviceName: service.serviceName || serviceName, | ||
results, | ||
@@ -63,4 +63,24 @@ } | ||
if (err) return cb(err, results) | ||
// iterate the counter to run the next service | ||
callNext(index + 1, results) | ||
}) | ||
} | ||
// run current service | ||
let returnVal | ||
if (getType(service) === 'AsyncFunction') { | ||
returnVal = service.call(context, args, service.dependencies) | ||
} | ||
else { | ||
returnVal = service.call( | ||
context, args, processResults, service.dependencies | ||
) | ||
} | ||
// support promises/async services | ||
if (isPromise(returnVal)) { | ||
returnVal | ||
.catch(processResults) | ||
.then(results => processResults(null, results)) | ||
} | ||
} | ||
@@ -70,2 +90,5 @@ | ||
callNext(0, input) | ||
// return a promise if no callback was provided | ||
return p | ||
} |
@@ -48,2 +48,11 @@ let util | ||
}, | ||
isPromise(p) { | ||
return p != null | ||
&& util.getType(p.then) === 'Function' | ||
&& util.getType(p.catch) === 'Function' | ||
}, | ||
isFunction(f) { | ||
return ['Function', 'AsyncFunction'].includes(util.getType(f)) | ||
}, | ||
} |
{ | ||
"name": "law", | ||
"description": "Tools to create policy and validations for services.", | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"homepage": "http://github.com/TorchlightSoftware/law", | ||
@@ -6,0 +6,0 @@ "repository": "git://github.com/TorchlightSoftware/law.git", |
@@ -131,2 +131,26 @@ # Law | ||
## Promise Support | ||
As of 1.1.0, you can use promises and async functions with Law: | ||
```js | ||
module.exports = { | ||
required: ['sessionId'], | ||
optional: ['specialKey'], | ||
service: async ({sessionId, specialKey}) => | ||
({role: 'Supreme Commander'}) | ||
} | ||
``` | ||
When you call a Law service, if you don't pass a callback, you'll get a Promise: | ||
```js | ||
services | ||
.getRole({sessionId}) | ||
.then(results => console.debug(results)) | ||
.catch(err => {throw err}) | ||
``` | ||
Knock yourself out. | ||
## Dependencies (optional feature) | ||
@@ -133,0 +157,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
37432
724
263