UNPKG

ask-cli-x

Version:

Alexa Skills Kit (ASK) Command Line Interfaces

190 lines (189 loc) 8.31 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.isSmapiError = exports.SmapiClientLateBound = void 0; const querystring_1 = __importDefault(require("querystring")); const authorization_controller_1 = __importDefault(require("../../controllers/authorization-controller")); const dynamic_config_1 = __importDefault(require("../../utils/dynamic-config")); const http_client_1 = __importDefault(require("../http-client")); const account_linking_1 = __importDefault(require("./resources/account-linking")); const catalog_1 = __importDefault(require("./resources/catalog")); const history_1 = __importDefault(require("./resources/history")); const isp_1 = __importDefault(require("./resources/isp")); const manifest_1 = __importDefault(require("./resources/manifest")); const interaction_model_1 = __importDefault(require("./resources/interaction-model")); const private_skill_1 = __importDefault(require("./resources/private-skill")); const skill_package_1 = __importDefault(require("./resources/skill-package")); const skill_1 = __importDefault(require("./resources/skill")); const test_1 = __importDefault(require("./resources/test")); const vendor_1 = __importDefault(require("./resources/vendor")); const evaluations_1 = __importDefault(require("./resources/evaluations")); const alexa_hosted_1 = __importDefault(require("./resources/alexa-hosted")); const beta_test_1 = __importDefault(require("./resources/beta-test")); const publishing_1 = __importDefault(require("./resources/publishing")); const task_1 = __importDefault(require("./resources/task")); const JSON_PROPERTIES = ["_links"]; /** * Class for Alexa Skill Management API Service (SMAPI) client * * Late bound to decouple the behavior from the user provided configuration of debug and profile. */ class SmapiClientLateBound { constructor() { this._smapiRequest = this._smapiRequest.bind(this); } withConfiguration(configuration) { const smapiRequest = (apiName, method, version, urlPath, queryParams, headers, payload, callback) => this._smapiRequest(configuration, apiName, method, version, urlPath, queryParams, headers, payload, callback); return { profile: configuration.profile, doDebug: configuration.doDebug, skill: { ...(0, skill_1.default)(smapiRequest), manifest: (0, manifest_1.default)(smapiRequest), interactionModel: (0, interaction_model_1.default)(smapiRequest), accountLinking: (0, account_linking_1.default)(smapiRequest), privateSkill: (0, private_skill_1.default)(smapiRequest), history: (0, history_1.default)(smapiRequest), test: (0, test_1.default)(smapiRequest), evaluations: (0, evaluations_1.default)(smapiRequest), alexaHosted: (0, alexa_hosted_1.default)(smapiRequest), betaTest: (0, beta_test_1.default)(smapiRequest), publishing: (0, publishing_1.default)(smapiRequest), }, skillPackage: (0, skill_package_1.default)(smapiRequest), vendor: (0, vendor_1.default)(smapiRequest), isp: (0, isp_1.default)(smapiRequest), catalog: (0, catalog_1.default)(smapiRequest), task: (0, task_1.default)(smapiRequest), }; } _smapiRequest(configuration, apiName, method, version, urlPath, queryParams, headers, payload, callback) { if (!callback) { return new Promise((resolve, reject) => { this._smapiRequest(configuration, apiName, method, version, urlPath, queryParams, headers, payload, (err, response) => { if (err) { return reject(err); } resolve(response); }); }); } const qs = querystring_1.default.stringify(queryParams) && `?${querystring_1.default.stringify(queryParams)}`; const smapiEndpoint = dynamic_config_1.default.smapiBaseUrl; const authorizationController = new authorization_controller_1.default({ auth_client_type: "LWA", doDebug: configuration.doDebug, }); authorizationController.tokenRefreshAndRead(configuration.profile, (tokenErr, token) => { if (tokenErr) { return callback(tokenErr); } const requestOptions = { url: `${smapiEndpoint}/${version}/${urlPath}${qs}`, method, headers: { ...headers, authorization: token, }, body: payload, json: !!payload, }; http_client_1.default.request(requestOptions, apiName, configuration.doDebug, (reqErr, reqResponse) => { if (reqErr) { return callback(reqErr); } _normalizeSmapiResponse(reqResponse, (normalizeErr, smapiResponse) => { callback(normalizeErr, normalizeErr ? null : smapiResponse); }); }); }); } } exports.SmapiClientLateBound = SmapiClientLateBound; /** * Class for Alexa Skill Management API Service (SMAPI) client * * Requires profile and debug flag. * * @deprecated use SmapiClientLateBound */ class SmapiClient { constructor(_configuration) { const smapiClientLateBound = new SmapiClientLateBound().withConfiguration(_configuration); this.skill = smapiClientLateBound.skill; this.catalog = smapiClientLateBound.catalog; this.isp = smapiClientLateBound.isp; this.skillPackage = smapiClientLateBound.skillPackage; this.vendor = smapiClientLateBound.vendor; this.task = smapiClientLateBound.task; this.profile = _configuration.profile; this.doDebug = _configuration.doDebug; } } exports.default = SmapiClient; function isSmapiError(response) { return response.statusCode >= 300; } exports.isSmapiError = isSmapiError; /** * Common function to validate and normalize SMAPI response. * @param {Object} reqResponse the response from SMAPI * @param {Function} callback (error, { statusCode, body, headers }) */ function _normalizeSmapiResponse(reqResponse, callback) { let parsedResponseBody; try { _validateSmapiResponse(reqResponse); //@ts-ignore parsedResponseBody = _cleanResponseBody(reqResponse.body); } catch (validateErr) { return callback(validateErr); } callback(null, { statusCode: reqResponse.statusCode, body: parsedResponseBody, headers: reqResponse.headers, }); } /** * Validate SMAPI's response * 1. If SMAPI response doesn't contain error object but status code >= 300 * 2. If SMAPI response body is valid JSON object * * @param {Object} reqResponse the response from SMAPI */ function _validateSmapiResponse(reqResponse) { if (reqResponse.statusCode >= 300 && !reqResponse.body) { throw `[Fatal]: SMAPI error code ${reqResponse.statusCode}. No response body from the service request.`; } try { if (reqResponse.body && typeof reqResponse.body === "string") { reqResponse.body = JSON.parse(reqResponse.body); } } catch (parseErr) { throw `[Fatal]: Failed to parse SMAPI's response. Please run again with --debug to check more details.\nError: ${parseErr}`; } } /** * function to clean up properties (such as _links) from the response body. * @param {Object} reqResponseBody */ function _cleanResponseBody(reqResponseBody) { if (reqResponseBody) { Object.keys(reqResponseBody).forEach((key) => { if (JSON_PROPERTIES.includes(key)) { const { [key]: k, ...rest } = reqResponseBody; return rest; } else if (typeof reqResponseBody[key] === "object") { return { ...reqResponseBody, [key]: _cleanResponseBody(reqResponseBody[key]) }; } return; }); } return reqResponseBody; }