UNPKG

@jargon/platform-sdk-core

Version:

Core components of the Jargon Platform SDK for node.js

268 lines 10.1 kB
"use strict"; 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