ask-cli-x
Version:
Alexa Skills Kit (ASK) Command Line Interfaces
190 lines (189 loc) • 8.31 kB
JavaScript
;
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;
}