alexa-ssml-jsx
Advanced tools
Comparing version 1.3.1 to 1.4.0
@@ -5,237 +5,10 @@ 'use strict'; | ||
function chainable(validator) { | ||
const chainableValidator = (props, propName, tagName) => validator(props, propName, tagName); | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
chainableValidator.isRequired = (props, propName, tagName) => { | ||
if (!props || !props[propName]) { | ||
throw new Error(`Missing required prop "${propName}" on "${tagName}" tag.`); | ||
} else { | ||
return validator(props, propName, tagName); | ||
} | ||
}; | ||
var ssml = require('ssml-jsx'); | ||
var ssml__default = _interopDefault(ssml); | ||
return chainableValidator; | ||
} | ||
const renderToString$1 = ssml.renderToString; | ||
const _oneOf = (possibilities = []) => (props, propName, tagName) => { | ||
const value = props && props[propName]; | ||
if (value && possibilities.indexOf(value) < 0) { | ||
throw new Error(`Unsupported value "${value}" for prop "${propName}" on "${tagName}" tag. Supported values are: ${possibilities.join(', ')}.`); | ||
} | ||
}; | ||
const _match = regex => (props, propName, tagName) => { | ||
const value = props && props[propName]; | ||
if (value && !regex.exec(value)) { | ||
throw new Error(`Invalid value for prop "${propName}" on "${tagName}" tag. Expected "${value}" to match ${regex.toString()}.`); | ||
} | ||
}; | ||
const array = (props, propName, tagName) => { | ||
const value = props && props[propName]; | ||
if (!Array.isArray(value)) { | ||
throw new Error(`Invalid value for prop "${propName}" on "${tagName}" tag. Expected an array.`); | ||
} | ||
}; | ||
const none = (props, propName, tagName) => { | ||
if (props && props[propName]) { | ||
throw new Error(`Unexpected prop "${propName}" on "${tagName}" tag. Expected none.`); | ||
} | ||
}; | ||
var PropTypes = { | ||
array: chainable(array), | ||
match: regex => chainable(_match(regex)), | ||
none: chainable(none), | ||
oneOf: possibilities => chainable(_oneOf(possibilities)) | ||
}; | ||
/** | ||
* Represents a pause in the speech. Set the length of the pause with the strength or time attributes. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.2.3 | ||
*/ | ||
const Strengths = ['none', // No pause should be outputted. This can be used to remove a pause that would normally occur (such as after a period). | ||
'x-weak', // No pause should be outputted (same as none). | ||
'weak', // Treat adjacent words as if separated by a single comma (equivalent to medium). | ||
'medium', // Treat adjacent words as if separated by a single comma. | ||
'strong', // Make a sentence break (equivalent to using the <s> tag). | ||
'x-strong' // Make a paragraph break (equivalent to using the <p> tag). | ||
]; | ||
var breakTag = { | ||
type: 'break', | ||
propTypes: { | ||
strength: PropTypes.oneOf(Strengths), | ||
time: PropTypes.match(/(\d+)(m?s)?/), | ||
children: PropTypes.none | ||
} | ||
}; | ||
/** | ||
* Represents a paragraph. This tag provides extra-strong breaks before and after the tag. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.7 | ||
*/ | ||
var p = { | ||
type: 'p', | ||
propTypes: { | ||
children: PropTypes.array.isRequired | ||
} | ||
}; | ||
/** | ||
* Represents a sentence. This tag provides strong breaks before and after the tag. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.7 | ||
*/ | ||
var s = { | ||
type: 's', | ||
propTypes: { | ||
children: PropTypes.array.isRequired | ||
} | ||
}; | ||
/** | ||
* Indicate information on the type of text construct contained within the element. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.8 | ||
*/ | ||
const interpretations = ['characters', 'spell-out', // Spell out each letter | ||
'cardinal', 'number', // Interpret the value as a cardinal number | ||
'ordinal', // Interpret the value as an ordinal number | ||
'digits', // Spell each digit separately | ||
'fraction', // Interpret the value as a fraction | ||
'unit', // Interpret a value as a measurement | ||
'date', // Interpret the value as a date. Specify the format with the format attribute | ||
'time', // Interpret a value such as 1'21" as duration in minutes and seconds | ||
'telephone', // Interpret a value as a 7-digit or 10-digit telephone number | ||
'address', // Interpret a value as part of street address | ||
'interjection' // Interpret a value as an interjection | ||
]; | ||
const formats = ['mdy', 'dmy', 'ymd', 'md', 'dm', 'ym', 'my', 'd', 'm', 'y']; | ||
var sayAsTag = { | ||
type: 'say-as', | ||
propTypes: { | ||
children: PropTypes.array.isRequired, | ||
'interpret-as': PropTypes.oneOf(interpretations).isRequired, | ||
format: (props, propName, tagName) => { | ||
if (props['interpret-as'] === 'date') { | ||
const format = PropTypes.oneOf(formats).isRequired; | ||
return format(props, propName, tagName); | ||
} | ||
} | ||
} | ||
}; | ||
/** | ||
* This is the root element of an SSML document. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.1 | ||
*/ | ||
var speak = { | ||
type: 'speak', | ||
propTypes: { | ||
children: PropTypes.array.isRequired | ||
} | ||
}; | ||
var schema = { | ||
'break': breakTag, | ||
p, | ||
s, | ||
'say-as': sayAsTag, | ||
speak | ||
}; | ||
var validate = (({ name, propTypes = {} }, props) => { | ||
Object.keys(propTypes).forEach(key => { | ||
const validator = propTypes[key]; | ||
validator && validator(props, key, name); | ||
}); | ||
return props; | ||
}); | ||
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; }; | ||
function ssml$1(tagName, props, ...children) { | ||
const tag = throwIfUndefined(getTagDefinition(tagName), `Unsupported tag: "${tagName}"`); | ||
const hasProps = props || tag.defaultProps || children.length; | ||
const mergedProps = hasProps && _extends({}, tag.defaultProps, props, children.length && { children }); | ||
const validatedProps = validate(tag, mergedProps); | ||
return _extends({ type: tag.type }, validatedProps && { props: validatedProps }); | ||
} | ||
function throwIfUndefined(item, error) { | ||
if (!item) { | ||
throw new Error(error); | ||
} else { | ||
return item; | ||
} | ||
} | ||
function getTagDefinition(tag) { | ||
switch (typeof tag) { | ||
case 'string': | ||
return schema[tag]; | ||
case 'function': | ||
return _extends({}, tag, { type: tag }); | ||
default: | ||
return undefined; | ||
} | ||
} | ||
var _extends$1 = 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; }; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
const entries = object => Object.keys(object).map(key => [key, object[key]]); | ||
function renderToString(node, options = {}) { | ||
if (!node || node.type !== 'speak') { | ||
throw Error('Expected SSML to be surrounded in a <speak> tag.'); | ||
} | ||
return render(node, _extends$1({}, options, { root: true })); | ||
} | ||
function render(node, options = {}) { | ||
if (!node) { | ||
return ''; | ||
} | ||
if (Array.isArray(node)) { | ||
return node.map(child => render(child, _extends$1({}, options, { root: false }))).join(''); | ||
} | ||
if (typeof node.type === 'function') { | ||
return render(node.type(node.props), _extends$1({}, options, { root: false })); | ||
} | ||
if (typeof node === 'string') { | ||
return node; | ||
} | ||
var _ref = node.props || {}, | ||
_ref$children = _ref.children; | ||
const children = _ref$children === undefined ? [] : _ref$children, | ||
rest = _objectWithoutProperties(_ref, ['children']); | ||
if (node.type === 'speak' && !options.root) { | ||
return children.map(child => render(child, _extends$1({}, options, { root: false }))).join(''); | ||
} | ||
const props = entries(rest).reduce((state, [key, value]) => `${state} ${key}="${value}"`, ''); | ||
return children.length ? `<${node.type}${props}>${children.map(child => render(child, _extends$1({}, options, { root: false }))).join('')}</${node.type}>` : `<${node.type}${props}/>`; | ||
} | ||
exports['default'] = ssml$1; | ||
exports.renderToString = renderToString; | ||
exports['default'] = ssml__default; | ||
exports.renderToString = renderToString$1; |
@@ -5,237 +5,10 @@ 'use strict'; | ||
function chainable(validator) { | ||
const chainableValidator = (props, propName, tagName) => validator(props, propName, tagName); | ||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
chainableValidator.isRequired = (props, propName, tagName) => { | ||
if (!props || !props[propName]) { | ||
throw new Error(`Missing required prop "${propName}" on "${tagName}" tag.`); | ||
} else { | ||
return validator(props, propName, tagName); | ||
} | ||
}; | ||
var ssml = require('ssml-jsx'); | ||
var ssml__default = _interopDefault(ssml); | ||
return chainableValidator; | ||
} | ||
const renderToString$1 = ssml.renderToString; | ||
const _oneOf = (possibilities = []) => (props, propName, tagName) => { | ||
const value = props && props[propName]; | ||
if (value && possibilities.indexOf(value) < 0) { | ||
throw new Error(`Unsupported value "${value}" for prop "${propName}" on "${tagName}" tag. Supported values are: ${possibilities.join(', ')}.`); | ||
} | ||
}; | ||
const _match = regex => (props, propName, tagName) => { | ||
const value = props && props[propName]; | ||
if (value && !regex.exec(value)) { | ||
throw new Error(`Invalid value for prop "${propName}" on "${tagName}" tag. Expected "${value}" to match ${regex.toString()}.`); | ||
} | ||
}; | ||
const array = (props, propName, tagName) => { | ||
const value = props && props[propName]; | ||
if (!Array.isArray(value)) { | ||
throw new Error(`Invalid value for prop "${propName}" on "${tagName}" tag. Expected an array.`); | ||
} | ||
}; | ||
const none = (props, propName, tagName) => { | ||
if (props && props[propName]) { | ||
throw new Error(`Unexpected prop "${propName}" on "${tagName}" tag. Expected none.`); | ||
} | ||
}; | ||
var PropTypes = { | ||
array: chainable(array), | ||
match: regex => chainable(_match(regex)), | ||
none: chainable(none), | ||
oneOf: possibilities => chainable(_oneOf(possibilities)) | ||
}; | ||
/** | ||
* Represents a pause in the speech. Set the length of the pause with the strength or time attributes. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.2.3 | ||
*/ | ||
const Strengths = ['none', // No pause should be outputted. This can be used to remove a pause that would normally occur (such as after a period). | ||
'x-weak', // No pause should be outputted (same as none). | ||
'weak', // Treat adjacent words as if separated by a single comma (equivalent to medium). | ||
'medium', // Treat adjacent words as if separated by a single comma. | ||
'strong', // Make a sentence break (equivalent to using the <s> tag). | ||
'x-strong' // Make a paragraph break (equivalent to using the <p> tag). | ||
]; | ||
var breakTag = { | ||
type: 'break', | ||
propTypes: { | ||
strength: PropTypes.oneOf(Strengths), | ||
time: PropTypes.match(/(\d+)(m?s)?/), | ||
children: PropTypes.none | ||
} | ||
}; | ||
/** | ||
* Represents a paragraph. This tag provides extra-strong breaks before and after the tag. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.7 | ||
*/ | ||
var p = { | ||
type: 'p', | ||
propTypes: { | ||
children: PropTypes.array.isRequired | ||
} | ||
}; | ||
/** | ||
* Represents a sentence. This tag provides strong breaks before and after the tag. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.7 | ||
*/ | ||
var s = { | ||
type: 's', | ||
propTypes: { | ||
children: PropTypes.array.isRequired | ||
} | ||
}; | ||
/** | ||
* Indicate information on the type of text construct contained within the element. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.8 | ||
*/ | ||
const interpretations = ['characters', 'spell-out', // Spell out each letter | ||
'cardinal', 'number', // Interpret the value as a cardinal number | ||
'ordinal', // Interpret the value as an ordinal number | ||
'digits', // Spell each digit separately | ||
'fraction', // Interpret the value as a fraction | ||
'unit', // Interpret a value as a measurement | ||
'date', // Interpret the value as a date. Specify the format with the format attribute | ||
'time', // Interpret a value such as 1'21" as duration in minutes and seconds | ||
'telephone', // Interpret a value as a 7-digit or 10-digit telephone number | ||
'address', // Interpret a value as part of street address | ||
'interjection' // Interpret a value as an interjection | ||
]; | ||
const formats = ['mdy', 'dmy', 'ymd', 'md', 'dm', 'ym', 'my', 'd', 'm', 'y']; | ||
var sayAsTag = { | ||
type: 'say-as', | ||
propTypes: { | ||
children: PropTypes.array.isRequired, | ||
'interpret-as': PropTypes.oneOf(interpretations).isRequired, | ||
format: (props, propName, tagName) => { | ||
if (props['interpret-as'] === 'date') { | ||
const format = PropTypes.oneOf(formats).isRequired; | ||
return format(props, propName, tagName); | ||
} | ||
} | ||
} | ||
}; | ||
/** | ||
* This is the root element of an SSML document. | ||
* More info: https://www.w3.org/TR/speech-synthesis/#S3.1.1 | ||
*/ | ||
var speak = { | ||
type: 'speak', | ||
propTypes: { | ||
children: PropTypes.array.isRequired | ||
} | ||
}; | ||
var schema = { | ||
'break': breakTag, | ||
p, | ||
s, | ||
'say-as': sayAsTag, | ||
speak | ||
}; | ||
var validate = (({ name, propTypes = {} }, props) => { | ||
Object.keys(propTypes).forEach(key => { | ||
const validator = propTypes[key]; | ||
validator && validator(props, key, name); | ||
}); | ||
return props; | ||
}); | ||
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; }; | ||
function ssml$1(tagName, props, ...children) { | ||
const tag = throwIfUndefined(getTagDefinition(tagName), `Unsupported tag: "${tagName}"`); | ||
const hasProps = props || tag.defaultProps || children.length; | ||
const mergedProps = hasProps && _extends({}, tag.defaultProps, props, children.length && { children }); | ||
const validatedProps = validate(tag, mergedProps); | ||
return _extends({ type: tag.type }, validatedProps && { props: validatedProps }); | ||
} | ||
function throwIfUndefined(item, error) { | ||
if (!item) { | ||
throw new Error(error); | ||
} else { | ||
return item; | ||
} | ||
} | ||
function getTagDefinition(tag) { | ||
switch (typeof tag) { | ||
case 'string': | ||
return schema[tag]; | ||
case 'function': | ||
return _extends({}, tag, { type: tag }); | ||
default: | ||
return undefined; | ||
} | ||
} | ||
var _extends$1 = 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; }; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
const entries = object => Object.keys(object).map(key => [key, object[key]]); | ||
function renderToString(node, options = {}) { | ||
if (!node || node.type !== 'speak') { | ||
throw Error('Expected SSML to be surrounded in a <speak> tag.'); | ||
} | ||
return render(node, _extends$1({}, options, { root: true })); | ||
} | ||
function render(node, options = {}) { | ||
if (!node) { | ||
return ''; | ||
} | ||
if (Array.isArray(node)) { | ||
return node.map(child => render(child, _extends$1({}, options, { root: false }))).join(''); | ||
} | ||
if (typeof node.type === 'function') { | ||
return render(node.type(node.props), _extends$1({}, options, { root: false })); | ||
} | ||
if (typeof node === 'string') { | ||
return node; | ||
} | ||
var _ref = node.props || {}, | ||
_ref$children = _ref.children; | ||
const children = _ref$children === undefined ? [] : _ref$children, | ||
rest = _objectWithoutProperties(_ref, ['children']); | ||
if (node.type === 'speak' && !options.root) { | ||
return children.map(child => render(child, _extends$1({}, options, { root: false }))).join(''); | ||
} | ||
const props = entries(rest).reduce((state, [key, value]) => `${state} ${key}="${value}"`, ''); | ||
return children.length ? `<${node.type}${props}>${children.map(child => render(child, _extends$1({}, options, { root: false }))).join('')}</${node.type}>` : `<${node.type}${props}/>`; | ||
} | ||
exports['default'] = ssml$1; | ||
exports.renderToString = renderToString; | ||
exports['default'] = ssml__default; | ||
exports.renderToString = renderToString$1; |
{ | ||
"name": "alexa-ssml-jsx", | ||
"description": "Write SSML inline within javascript files using JSX", | ||
"version": "1.3.1", | ||
"version": "1.4.0", | ||
"repository": "https://github.com/cameronhunter/alexa/tree/master/packages/alexa-ssml-jsx", | ||
"author": "Cameron Hunter <hello@cameronhunter.co.uk>", | ||
"main": "build/index.min.js", | ||
"license": "MIT" | ||
"license": "MIT", | ||
"dependencies": { | ||
"ssml-jsx": "^1.4.0" | ||
} | ||
} |
# alexa-ssml-jsx | ||
Write SSML inline within JavaScript. | ||
You can use [SSML](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/speech-synthesis-markup-language-ssml-reference) | ||
directly by including `babel-plugin-transform-react-jsx` in your `.babelrc` and | ||
importing `ssml` from `alexa-ssml-jsx`. | ||
```json | ||
{ | ||
"plugins": [ | ||
["transform-react-jsx", { "pragma": "ssml" }] | ||
] | ||
} | ||
``` | ||
```javascript | ||
import ssml, { renderToString } from 'alexa-ssml-jsx'; | ||
const speech = ( | ||
<speak> | ||
<p>Hello world!</p> | ||
<break time='2s' /> | ||
<p>What would you like to do today?</p> | ||
</speak> | ||
); | ||
``` | ||
This is a shim package for [ssml-jsx](https://github.com/cameronhunter/alexa/tree/master/packages/ssml-jsx). It's | ||
possible that in the future, Amazon specific SSML additions will be added to this package instead of the base `ssml-jsx` | ||
package. |
@@ -1,4 +0,4 @@ | ||
import ssml from './ssml'; | ||
import ssml, { renderToString as rts } from 'ssml-jsx'; | ||
export default ssml; | ||
export renderToString from './renderToString'; | ||
export const renderToString = rts; |
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
1548
1
5
19
6
1
+ Addedssml-jsx@^1.4.0
+ Addedjs-tokens@4.0.0(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedprop-types@15.8.1(transitive)
+ Addedreact-is@16.13.1(transitive)
+ Addedssml-jsx@1.4.2(transitive)