alexa-ability
Advanced tools
Comparing version 0.6.1 to 0.7.0
'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
@@ -24,6 +22,8 @@ | ||
var _flattenDeep = require('lodash/flattenDeep'); | ||
var _flattenDeep2 = _interopRequireDefault(_flattenDeep); | ||
var _Request = require('./Request'); | ||
var _getEventName = require('./getEventName'); | ||
var _defaultHandlers = require('./defaultHandlers'); | ||
@@ -39,2 +39,4 @@ | ||
var _getEventName = require('./getEventName'); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
@@ -69,3 +71,4 @@ | ||
this._middleware = []; | ||
this._handlers = _extends({}, _defaultHandlers.handlers); | ||
this._onError = null; | ||
this._handlers = {}; | ||
@@ -91,11 +94,28 @@ if (options.applicationId) { | ||
key: 'on', | ||
value: function on(event, handler) { | ||
value: function on(event) { | ||
for (var _len = arguments.length, _handlers = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
_handlers[_key - 1] = arguments[_key]; | ||
} | ||
var handlers = (0, _flattenDeep2.default)(_handlers); | ||
var currentHandlers = this._handlers[event] || []; | ||
(0, _assert2.default)(typeof event === 'string', 'Expected string for event type'); | ||
(0, _assert2.default)(typeof handler === 'function', 'Expected function for event handler'); | ||
if (this._handlers[event]) oLog('overwrote handler for event: ' + event);else oLog('added handler for event: ' + event); | ||
(0, _assert2.default)(handlers.length, 'Expected at least one handler'); | ||
handlers.forEach(function (handler) { | ||
(0, _assert2.default)(typeof handler === 'function', 'Expected function for event handler'); | ||
}); | ||
this._handlers[event] = handler; | ||
oLog('adding ' + handlers.length + ' handlers to ' + event + ' event'); | ||
this._handlers[event] = [].concat(currentHandlers, handlers); | ||
oLog('current ' + this._handlers[event].length + ' handlers for ' + event + ' event'); | ||
return this; | ||
} | ||
}, { | ||
key: 'onError', | ||
value: function onError(handler) { | ||
this._onError = handler; | ||
return this; | ||
} | ||
}, { | ||
key: 'handle', | ||
@@ -105,3 +125,14 @@ value: function handle(event) { | ||
var type = (0, _getEventName.getEventName)(event); | ||
// get possible handlers | ||
// it's fine if `handler` is null or undefined | ||
// it'll all be caught by the `unhandledEvent` handler | ||
var eventName = (0, _getEventName.getEventName)(event); | ||
var errHandler = this._onError || _defaultHandlers.defaultHandlers.errorHandler; | ||
var defHandler = this._handlers[e.unhandledEvent] || _defaultHandlers.defaultHandlers.defaultHandler; | ||
var handler = eventName ? this._handlers[eventName] : null; | ||
// log | ||
if (handler) hLog('handling event: ' + eventName);else hLog('no handler found for event: "' + eventName + '".'); | ||
// build request object and attach listeners | ||
var req = new _Request.Request(event); | ||
@@ -115,18 +146,27 @@ req.on('finished', function () { | ||
// get possible handlers | ||
var errHandler = this._handlers[e.error]; | ||
var defHandler = this._handlers[e.unhandledEvent]; | ||
var handler = this._handlers[type] || defHandler; | ||
// iterate over the stack of middleware and handlers | ||
// kind of like express does | ||
var index = 0; | ||
var stack = [].concat(this._middleware, handler, defHandler); | ||
// log | ||
if (this._handlers[type]) hLog('handling event: ' + type);else hLog('no handler found for event: "' + type + '".'); | ||
// if we ever reach this function then everything has failed | ||
function done(err) { | ||
// halt execution early if response has been sent | ||
if (req.sent) { | ||
warnSent(); | ||
return; | ||
} | ||
var index = 0; | ||
var stack = [].concat(this._middleware, handler); | ||
// just fail | ||
if (err) { | ||
req.fail(err); | ||
return; | ||
} | ||
next(); | ||
req.fail(new Error('Unhandled event.')); | ||
} | ||
return req; | ||
// this function gives up execution to the next handler | ||
function next(err) { | ||
// halt execution early if response has been sent | ||
if (req.sent) { | ||
@@ -137,15 +177,25 @@ warnSent(); | ||
// uhoh, try error handler once | ||
if (err) { | ||
hLog('executing error handler'); | ||
(0, _resolve.resolve)(errHandler, done, err, req); | ||
(0, _resolve.resolve)(errHandler, done, err, req, done); | ||
return; | ||
} | ||
// no more handlers? fail | ||
if (index >= stack.length) { | ||
done(); | ||
return; | ||
} | ||
var fn = stack[index++]; | ||
if (!fn) { | ||
hLog('executing unhandledEvent handler'); | ||
(0, _resolve.resolve)(defHandler, done, req); | ||
// invalid handler? just skip it.. | ||
if (typeof fn !== 'function') { | ||
hLog('invalid handler %s', fn); | ||
next(); | ||
return; | ||
} | ||
// all's well! try the handler | ||
hLog('executing function <' + (fn.name || 'anonymous') + '>'); | ||
@@ -155,16 +205,5 @@ (0, _resolve.resolve)(fn, next, req); | ||
// if we ever reach this function then everything has failed | ||
function done(err) { | ||
if (req.sent) { | ||
warnSent(); | ||
return; | ||
} | ||
if (err) { | ||
req.emit('failed', err); | ||
return; | ||
} | ||
req.emit('failed', new Error('Unhandled event.')); | ||
} | ||
// start execution | ||
next(); | ||
return req; | ||
} | ||
@@ -171,0 +210,0 @@ }]); |
'use strict'; | ||
var _handlers; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.handlers = undefined; | ||
exports.defaultHandlers = undefined; | ||
@@ -18,14 +16,5 @@ var _debug = require('debug'); | ||
var _standardEvents = require('./standardEvents'); | ||
var e = _interopRequireWildcard(_standardEvents); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } | ||
var dLog = (0, _debug2.default)('alexa-ability:defaultEventHandler'); | ||
var uLog = (0, _debug2.default)('alexa-ability:unknownEventHandler'); | ||
var eLog = (0, _debug2.default)('alexa-ability:defaultErrorHandler'); | ||
@@ -38,12 +27,13 @@ | ||
var handlers = exports.handlers = (_handlers = {}, _defineProperty(_handlers, e.unhandledEvent, function defaultEventHandler(req, next) { | ||
dLog('unhandled request', req); | ||
next(new Error('No event handler found.')); | ||
}), _defineProperty(_handlers, e.unknownEvent, function unknownEventHandler(req, next) { | ||
uLog('unknown request', req); | ||
next(new Error('Unknown request type.')); | ||
}), _defineProperty(_handlers, e.error, function defaultErrorHandler(err, req, next) { | ||
eLog('unhandled error', err); | ||
noErrHandlerWarning(); | ||
next(err); | ||
}), _handlers); | ||
var defaultHandlers = exports.defaultHandlers = { | ||
defaultHandler: function defaultIntentHandler(req, next) { | ||
dLog('unhandled request', req); | ||
next(new Error('No intent handler found.')); | ||
}, | ||
errorHandler: function defaultErrorHandler(err, req, next) { | ||
eLog('unhandled error', err); | ||
noErrHandlerWarning(); | ||
next(err); | ||
} | ||
}; |
@@ -41,4 +41,4 @@ 'use strict'; | ||
default: | ||
return e.unknownEvent; | ||
return null; | ||
} | ||
} |
@@ -18,6 +18,6 @@ 'use strict'; | ||
var _alexaSsml = require('alexa-ssml'); | ||
var _events = require('events'); | ||
var _toSpeechResponse = require('./toSpeechResponse'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -41,3 +41,6 @@ | ||
_this.sent = false; | ||
_this.isNew = (0, _get2.default)(event, 'session.new', false); | ||
_this.isEnding = !!(0, _get2.default)(event, 'request.reason'); | ||
_this.reason = (0, _get2.default)(event, 'request.reason', null); | ||
_this.version = (0, _get2.default)(event, 'version', '1.0'); | ||
@@ -62,3 +65,3 @@ _this.session = (0, _get2.default)(event, 'session.attributes', {}); | ||
value: function say(type, value) { | ||
this._res.outputSpeech = toSpeechResponse(type, value); | ||
this._res.outputSpeech = (0, _toSpeechResponse.toSpeechResponse)(type, value); | ||
return this; | ||
@@ -80,3 +83,3 @@ } | ||
this._res.reprompt = { | ||
outputSpeech: toSpeechResponse(type, value) | ||
outputSpeech: (0, _toSpeechResponse.toSpeechResponse)(type, value) | ||
}; | ||
@@ -120,10 +123,2 @@ return this; | ||
return Request; | ||
}(_events.EventEmitter); | ||
function toSpeechResponse(_type, _content) { | ||
var type = _content === undefined ? undefined : _type; | ||
var content = _content === undefined ? _type : _content; | ||
var isTag = !!(0, _get2.default)(content, 'tag'); | ||
return isTag || type === 'ssml' ? { type: 'SSML', ssml: isTag ? (0, _alexaSsml.renderToString)(content) : content } : { type: 'PlainText', text: content }; | ||
} | ||
}(_events.EventEmitter); |
@@ -12,6 +12,2 @@ 'use strict'; | ||
var unknownEvent = exports.unknownEvent = 'unknownEvent'; | ||
var error = exports.error = 'error'; | ||
var launch = exports.launch = 'launch'; | ||
@@ -18,0 +14,0 @@ |
{ | ||
"name": "alexa-ability", | ||
"version": "0.6.1", | ||
"version": "0.7.0", | ||
"description": "An Alexa skills framework for node", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -18,2 +18,3 @@ # alexa-ability [![Build Status](https://travis-ci.org/nickclaw/alexa-ability.svg?branch=master)](https://travis-ci.org/nickclaw/alexa-ability) | ||
// runs first for every request | ||
app.use(function(req, next) { | ||
@@ -24,3 +25,4 @@ logRequest(req); | ||
ability.on(events.launch, function(req) { | ||
// handle LaunchRequest | ||
ability.on(events.launch, function(req, next) { | ||
const speech = ( | ||
@@ -35,3 +37,14 @@ <speak> | ||
// handle SessionEndedRequest | ||
ability.on(events.end, function(req, next) { | ||
console.log(`Session ended because: ${req.reason}`); | ||
req.send('Goodbye!'); | ||
}); | ||
// handle uncaught errors | ||
ability.onError(function(err, req, next) { | ||
req.say('Uhoh, something went wrong'); | ||
}); | ||
// handle intent | ||
ability.on('MeaningOfLifeIntent', function(req, next) { | ||
@@ -44,7 +57,3 @@ asyncRequest(function(err) { | ||
ability.on(events.error, function(err, req, next) { | ||
req.say('Uhoh, something went wrong'); | ||
}); | ||
// export as a lambda handler | ||
export const handler = handleAbility(ability); | ||
@@ -77,5 +86,8 @@ ``` | ||
##### `Ability.prototype.on(event, handler) -> ability` | ||
Add an event handler to the ability. The handler function will be called with a request instance as the first argument and a "next" function that can be used to pass errors down. | ||
##### `Ability.prototype.on(intent, ...handlers) -> ability` | ||
Add an intent handler to the ability. The handler functions will be called with a request instance as the first argument and a "next" function to be called when the handler is done. | ||
##### `Ability.prototype.onError(handler) -> ability` | ||
Add an error handler to the ability. This handler will be called with the error as the first argument, the request as the second, and the next function as the third. | ||
##### `Ability.prototype.handle(event, callback) -> request` | ||
@@ -98,2 +110,12 @@ Handle an event, this function expects the JSON object from the Alexa request and a node style callback. | ||
##### `request.isEnding` | ||
A boolean value indicating whether this session is ending. | ||
Returns true if the event type is `SessionEndedRequest`. | ||
##### `request.reason` | ||
A string value if `request.isEnding` is `true`. Can be one of three reasons: | ||
* `USER_INITIATED`: The user explicitly ended the session | ||
* `ERROR`: An error occurred that caused the session to end | ||
* `EXCEEDED_MAX_REPROMPTS`: The user either did not respond or responded with an utterance that did not match any of the intents defined in your voice interface. | ||
##### `request.version` | ||
@@ -167,6 +189,4 @@ The version specifier for the request with the value defined as: “1.0” | ||
##### Default Events | ||
##### Internal Events | ||
* `events.unhandledEvent`: No event handler found | ||
* `events.unknownEvent`: Handle unknown request types | ||
* `events.error`: Handle all errors | ||
* `events.launch`: Corresponds to `LaunchRequest` | ||
@@ -173,0 +193,0 @@ * `events.end`: Corresponds to `SessionEndedRequest` |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
196
29121
14
459
1