@jargon/platform-sdk-core
Version:
Core components of the Jargon Platform SDK for node.js
268 lines • 10.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JargonRemoteResourceManager = exports.JargonDevEndpoints = exports.JargonEndpoints = void 0;
const https = __importStar(require("https"));
/** Production Jargon endpoints */
exports.JargonEndpoints = {
'aws-us-east-1': 'cs-aws-us-east-1.jargoncontent.net',
'aws-eu-west-1': 'cs-aws-eu-west-1.jargoncontent.net',
'aws-ap-northeast-1': 'cs-aws-ap-northeast-1.jargoncontent.net'
};
/** Jargon development endpoints - not for public use */
exports.JargonDevEndpoints = {
'dev-aws-us-east-1': 'cs-aws-us-east-1.jargon-content.org'
};
const apiVersion = 'v2020-01-01';
class JargonRemoteResourceManager {
constructor(locale, _platform, _agent, options) {
this.locale = locale;
this._platform = _platform;
this._agent = _agent;
this._contentInterfaceId = options.contentInterfaceId;
this._endpoint = options.endpoint;
this._projectId = options.projectId;
this._tag = options.tag;
this._logFunc = options.logFunc || console.log;
this._logTimings = options.logTimings === true;
}
_convertParams(params) {
const contentParams = {};
for (const key in params) {
// Treating param as any to handle JS applications that won't have the benefit
// of the typescript compiler
const param = params[key];
if (typeof param === 'number' || typeof param === 'string' || typeof param === 'boolean' || param instanceof Date) {
contentParams[key] = { stringVal: param.toString() };
}
else if (param.key) {
const item = this._convertRenderItem(param, 'string');
contentParams[key] = { itemVal: item };
}
else {
// Non-render-item object
contentParams[key] = { stringVal: JSON.stringify(param) };
}
}
return contentParams;
}
_convertRenderItem(item, type) {
const contentItem = {
type: type,
key: item.key
};
if (item.params) {
contentItem.params = this._convertParams(item.params);
}
return contentItem;
}
async render(item) {
const rendered = await this.renderBatch([item]);
return rendered[0];
}
async renderBatch(items) {
const response = await this.getContent(items.map(item => this._convertRenderItem(item, 'string')));
const strings = [];
for (const item of response.items) {
if (item.status === 'found') {
strings.push(item.stringVal);
}
else if (item.status === 'not_found') {
throw new Error(`string ${item.key} not found for locale ${this.locale}`);
}
else if (item.status === 'param_not_found') {
throw new Error(`not able to find parameters in request for string ${item.key}`);
}
}
return strings;
}
async renderObject(item) {
const response = await this.getContent([this._convertRenderItem(item, 'object')]);
if (response.items.length !== 1) {
throw new Error('Unexpected response from content sever');
}
const i = response.items[0];
if (i.status === 'found') {
return JSON.parse(i.objectVal);
}
else if (i.status === 'not_found') {
throw new Error(`object ${i.key} not found for locale ${this.locale}`);
}
else if (i.status === 'param_not_found') {
throw new Error(`not able to find parameters in request for object ${i.key}`);
}
throw new Error('Unexpected response status from content sever');
}
async renderResponse(item) {
const content = await this.getContent([this._convertRenderItem(item, 'response')]);
if (content.items.length !== 1) {
throw new Error('Unexpected response from content sever');
}
const i = content.items[0];
if (i.status === 'found') {
return this._convertResponse(i);
}
else if (i.status === 'not_found') {
throw new Error(`object ${i.key} not found for locale ${this.locale}`);
}
else if (i.status === 'param_not_found') {
throw new Error(`not able to find parameters in request for object ${i.key}`);
}
throw new Error('Unexpected response status from content sever');
}
async renderAll(items) {
const cis = items.map(i => this._convertRenderItem(i, i.type));
const resp = await this.getContent(cis);
const results = [];
for (const r of resp.items) {
const key = r.key;
const type = r.type;
let res;
if (r.status !== 'found') {
res = r;
}
else if (type === 'string') {
const srr = {
key,
type,
status: 'found',
result: r.stringVal
};
res = srr;
}
else if (type === 'response') {
const rrr = {
key,
type,
status: 'found',
result: this._convertResponse(r)
};
res = rrr;
}
else if (type === 'object') {
const orr = {
key,
type,
status: 'found',
result: JSON.parse(r.objectVal)
};
res = orr;
}
else {
throw new Error(`unexpected response type ${type}`);
}
results.push(res);
}
return results;
}
selectedVariation(item) {
return Promise.reject(new Error('Not implemented for remote content management.'));
}
selectedVariations() {
return Promise.reject(new Error('Not implemented for remote content management.'));
}
_convertResponse(item) {
const val = item.responseVal;
const rv = {};
if (val.speech) {
rv.speech = { content: val.speech };
}
if (val.reprompt) {
rv.reprompt = { content: val.reprompt };
}
if (this._platform === 'ActionsOnGoogle') {
if (val.googleCard) {
rv.googleCard = { content: val.googleCard };
}
if (val.googleSuggestions) {
rv.googleSuggestions = { content: val.googleSuggestions };
}
}
else if (this._platform === 'Alexa') {
if (val.alexaCard) {
rv.alexaCard = { content: val.alexaCard };
}
if (val.alexaDirectives) {
rv.alexaDirectives = {};
for (const k in val.alexaDirectives) {
rv.alexaDirectives[k] = { content: val.alexaDirectives[k] };
}
}
}
return rv;
}
async getContent(items) {
const request = {
projectId: this._projectId,
contentInterfaceId: this._contentInterfaceId,
locale: this.locale,
tag: this._tag,
platform: this._platform,
items: items
};
// TODO: refactor common JSON HTTP logic out when we add analytics calls
const start = Date.now();
return new Promise((resolve, reject) => {
const postData = JSON.stringify(request);
const options = {
hostname: this._endpoint,
path: `/${apiVersion}/get-content`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};
const httpRequest = https.request(options, (res) => {
res.setEncoding('utf8');
let buf = '';
res.on('error', err => reject(err));
res.on('data', (data) => {
if (res.statusCode === 200) {
buf += data;
}
else {
const error = data.toString();
reject(new Error(error));
}
});
res.on('end', () => {
if (res.statusCode === 200) {
if (this._logTimings) {
this._logFunc(`getContent(${JSON.stringify(items)}) ${Date.now() - start}`);
}
const response = JSON.parse(buf);
resolve(response);
}
});
});
httpRequest.on('error', (err => reject(err)));
httpRequest.write(postData, (error => {
if (error) {
reject(error);
}
}));
httpRequest.end();
});
}
}
exports.JargonRemoteResourceManager = JargonRemoteResourceManager;
//# sourceMappingURL=jrrm.js.map