@tableau/taco-toolkit
Version:
Tableau Connector Toolkit
317 lines • 26.3 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EpsServiceImpl = exports.createExtractHandlerRequest = exports.parseConnectionData = exports.tryParseToJson = exports.createLaunchHandlerRequest = exports.mapToExtractResponse = exports.mapSecretsToObject = exports.toDefaultSize = void 0;
var eps_pb_1 = require("../proto/build/eps_pb");
var app_url_1 = require("../../eps-handlers/app-url");
var launch_1 = require("../../eps-handlers/launch");
var position_size_1 = require("../../../../types/position-size");
var eps_error_1 = require("../../../../types/eps-error");
var eps_logger_1 = require("../../../../logging/eps-logger");
var handler_utils_1 = require("../../eps-handlers/handler-utils");
var extract_handler_1 = require("../../eps-handlers/extract-handler");
function toDefaultSize(size) {
if (!size) {
return (0, position_size_1.parsePositionSize)({});
}
return (0, position_size_1.parsePositionSize)({ top: size.top, left: size.left, width: size.width, height: size.height });
}
exports.toDefaultSize = toDefaultSize;
function mapSecretsToObject(secrets, accessToken) {
//if auth type is oAuth then access token will be used
if (accessToken) {
return {
'access-token': accessToken,
};
}
if (secrets) {
return tryParseToJson(secrets, 'Secrets');
}
return undefined;
}
exports.mapSecretsToObject = mapSecretsToObject;
function mapToExtractResponse(response) {
var resp = new eps_pb_1.ExtractResponse();
if (response instanceof eps_error_1.EPSError) {
var message = response.message, epsErrorInfo = response.epsErrorInfo, connectorName = response.connectorName, status_1 = response.status;
resp.setStatus(status_1);
resp.setErrorMsg(message);
resp.setTableauError(epsErrorInfo.tableauError);
if (connectorName) {
resp.setConnectorName(connectorName);
}
}
else {
var _a = response, status_2 = _a.status, extractorType = _a.extractorType, connectionData = _a.connectionData, secrets = _a.secrets, port = _a.port, extractorId = _a.extractorId, connectorName = _a.connectorName;
resp.setStatus(status_2);
if (port) {
resp.setPort(port);
}
if (extractorId) {
resp.setExtractorId(extractorId);
}
if (extractorType) {
resp.setExtractorType(extractorType);
}
if (connectorName) {
resp.setConnectorName(connectorName);
}
if (secrets) {
resp.setSecrets(JSON.stringify(secrets));
}
if (connectionData) {
resp.setConnectionData(JSON.stringify(connectionData));
}
}
return resp;
}
exports.mapToExtractResponse = mapToExtractResponse;
function createLaunchHandlerRequest(launchRequest, apiOptions) {
var connectorClass = launchRequest.connectorClass, connectionId = launchRequest.connectionId, pluginPath = launchRequest.pluginPath, size = launchRequest.size, extractorMode = launchRequest.extractorMode, connData = launchRequest.connectionData, secrets = launchRequest.secrets, locale = launchRequest.locale, language = launchRequest.language, accessToken = launchRequest.accessToken;
var browserWatcherPort = apiOptions.browserWatcherPort, staticServerOptions = apiOptions.staticServerOptions, epsApiPort = apiOptions.epsApiPort;
if (browserWatcherPort === undefined || staticServerOptions === undefined) {
throw new Error("Required services for Launch are not enabled. browserWatcherPort: ".concat(browserWatcherPort, ", staticServerOptions: ").concat(staticServerOptions));
}
(0, handler_utils_1.validateCallerId)(launchRequest.callerId, apiOptions.callerId);
(0, handler_utils_1.validateInstanceId)(launchRequest.epsInstanceId, apiOptions.epsInstanceId);
(0, handler_utils_1.validatePluginPath)(launchRequest.pluginPath);
var connectionData = tryParseToJson(connData, 'Connection Data');
return {
epsServiceInfo: {
callerId: apiOptions.callerId,
epsInstanceId: apiOptions.epsInstanceId,
epsApiPort: epsApiPort,
browserWatcherPort: browserWatcherPort,
staticServerId: staticServerOptions.staticServerId,
staticServerPort: staticServerOptions.staticServerPort,
},
launchUIOptions: {
connectorClass: connectorClass,
connectionId: connectionId,
tacoPath: pluginPath,
connectionData: connectionData,
parentPositionSize: toDefaultSize(size),
secrets: mapSecretsToObject(secrets, accessToken),
extractorMode: extractorMode,
i18n: {
language: language !== null && language !== void 0 ? language : apiOptions.i18n.language,
locale: locale !== null && locale !== void 0 ? locale : apiOptions.i18n.locale,
},
},
};
}
exports.createLaunchHandlerRequest = createLaunchHandlerRequest;
function tryParseToJson(data, name) {
if (!data) {
return undefined;
}
try {
return JSON.parse(data);
}
catch (error) {
throw new Error("Incorrect format! Unable to parse ".concat(name, " to JSON!'"));
}
}
exports.tryParseToJson = tryParseToJson;
function parseConnectionData(connData) {
if (!connData) {
throw new Error("Connection data is missing!");
}
var connectionData = tryParseToJson(connData, 'Connection Data');
return connectionData;
}
exports.parseConnectionData = parseConnectionData;
function createExtractHandlerRequest(extractRequest, apiOptions) {
var connectorClass = extractRequest.connectorClass, connectionId = extractRequest.connectionId, pluginPath = extractRequest.pluginPath, connData = extractRequest.connectionData, secrets = extractRequest.secrets, accessToken = extractRequest.accessToken;
(0, handler_utils_1.validateCallerId)(extractRequest.callerId, apiOptions.callerId);
(0, handler_utils_1.validateInstanceId)(extractRequest.epsInstanceId, apiOptions.epsInstanceId);
(0, handler_utils_1.validatePluginPath)(extractRequest.pluginPath);
var connectionData = parseConnectionData(connData);
return {
connectorClass: connectorClass,
connectionId: connectionId,
tacoPath: pluginPath,
connectionData: connectionData,
secrets: mapSecretsToObject(secrets, accessToken),
};
}
exports.createExtractHandlerRequest = createExtractHandlerRequest;
var EpsServiceImpl = /** @class */ (function () {
function EpsServiceImpl(extractorLaunchedEvent, // prettier
apiOptions) {
this.extractorLaunchedEvent = extractorLaunchedEvent;
this.apiOptions = apiOptions;
this.extractHandler = new extract_handler_1.ExtractHandler();
}
EpsServiceImpl.prototype.launch = function (call, callback) {
return __awaiter(this, void 0, void 0, function () {
var launchRequest, handlerRequest, launchResult, error, response, resp, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
launchRequest = call.request.toObject();
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
handlerRequest = createLaunchHandlerRequest(launchRequest, this.apiOptions);
return [4 /*yield*/, (0, launch_1.handleLaunch)(this.extractorLaunchedEvent, handlerRequest)];
case 2:
launchResult = _a.sent();
if (!launchResult) {
error = new Error("[gRPC] launch failed, launchResult: ".concat(launchResult));
eps_logger_1.Logger.error(error);
callback(error);
return [2 /*return*/];
}
response = launchResult.response;
if (isEPSErrorResponse(response)) {
callback(response);
return [2 /*return*/];
}
resp = mapToExtractResponse(response);
eps_logger_1.Logger.info('[gRPC] launch call succeeded, extractorId: ' + resp.getExtractorId());
callback(null, resp);
return [3 /*break*/, 4];
case 3:
error_1 = _a.sent();
callback(error_1, null);
return [2 /*return*/];
case 4: return [2 /*return*/];
}
});
});
};
EpsServiceImpl.prototype.extract = function (call, callback) {
return __awaiter(this, void 0, void 0, function () {
var extractRequest, handlerRequest, extractResult, error, response, resp, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
extractRequest = call.request.toObject();
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
handlerRequest = createExtractHandlerRequest(extractRequest, this.apiOptions);
return [4 /*yield*/, this.extractHandler.handleExtractRequest(this.extractorLaunchedEvent, handlerRequest)];
case 2:
extractResult = _a.sent();
if (!extractResult) {
error = new Error("[gRPC] extract failed, launchResult: ".concat(extractResult));
eps_logger_1.Logger.error(error);
callback(error);
return [2 /*return*/];
}
response = extractResult.response;
if (isEPSErrorResponse(response)) {
callback(response);
return [2 /*return*/];
}
resp = mapToExtractResponse(response);
eps_logger_1.Logger.info('[gRPC] extract call succeeded, extractorId: ' + resp.getExtractorId());
callback(null, resp);
return [3 /*break*/, 4];
case 3:
error_2 = _a.sent();
callback(error_2);
return [2 /*return*/];
case 4: return [2 /*return*/];
}
});
});
};
EpsServiceImpl.prototype.getAppUrl = function (call, callback) {
return __awaiter(this, void 0, void 0, function () {
var staticServerOptions, _a, connectionId, connectorClass, pluginPath, language, locale, result, resp, error_3;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
staticServerOptions = this.apiOptions.staticServerOptions;
if (staticServerOptions === undefined) {
throw new Error('Static server must be enabled for getAppUrl.');
}
_a = call.request.toObject(), connectionId = _a.connectionId, connectorClass = _a.connectorClass, pluginPath = _a.pluginPath, language = _a.language, locale = _a.locale;
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, (0, app_url_1.getWebAuthoringAppUrl)({
connectionId: connectionId,
connectorClass: connectorClass,
pluginPath: pluginPath,
staticServerOptions: staticServerOptions,
i18n: {
language: language !== null && language !== void 0 ? language : this.apiOptions.i18n.language,
locale: locale !== null && locale !== void 0 ? locale : this.apiOptions.i18n.locale,
},
})];
case 2:
result = _b.sent();
resp = new eps_pb_1.AppUrlResponse();
resp.setConnectorAppUrl(result.connectorAppUrl);
callback(null, resp);
return [3 /*break*/, 4];
case 3:
error_3 = _b.sent();
callback(error_3, null);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}
});
});
};
EpsServiceImpl.prototype.terminateExtractor = function (call, callback) {
try {
var _a = call.request.toObject(), connectionId = _a.connectionId, extractorIdList = _a.extractorIdList;
var result = this.extractHandler.handleTerminationRequest({
connectionId: connectionId,
extractorIds: extractorIdList,
});
var resp = new eps_pb_1.TerminateExtractorResponse();
resp.setExtractorIdList(result.freedExtractorIds);
callback(null, resp);
}
catch (error) {
callback(error, null);
}
};
return EpsServiceImpl;
}());
exports.EpsServiceImpl = EpsServiceImpl;
function isEPSErrorResponse(response) {
return 'errorMsg' in response;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXBzLXNlcnZlci1pbXBsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2Vwcy9tYWluL2FwaS9ncnBjL3NlcnZlci9lcHMtc2VydmVyLWltcGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsZ0RBUThCO0FBRTlCLHNEQUFrRTtBQUVsRSxvREFBOEU7QUFFOUUsaUVBQW1FO0FBQ25FLHlEQUFzRDtBQUd0RCw2REFBdUQ7QUFFdkQsa0VBQTJHO0FBQzNHLHNFQUFtRTtBQUVuRSxTQUFnQixhQUFhLENBQUMsSUFBNkM7SUFDekUsSUFBSSxDQUFDLElBQUksRUFBRTtRQUNULE9BQU8sSUFBQSxpQ0FBaUIsRUFBQyxFQUFFLENBQUMsQ0FBQTtLQUM3QjtJQUVELE9BQU8sSUFBQSxpQ0FBaUIsRUFBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQTtBQUN0RyxDQUFDO0FBTkQsc0NBTUM7QUFFRCxTQUFnQixrQkFBa0IsQ0FBQyxPQUEyQixFQUFFLFdBQW9CO0lBQ2xGLHNEQUFzRDtJQUN0RCxJQUFJLFdBQVcsRUFBRTtRQUNmLE9BQU87WUFDTCxjQUFjLEVBQUUsV0FBVztTQUM1QixDQUFBO0tBQ0Y7SUFFRCxJQUFJLE9BQU8sRUFBRTtRQUNYLE9BQU8sY0FBYyxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQTtLQUMxQztJQUNELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUM7QUFaRCxnREFZQztBQUVELFNBQWdCLG9CQUFvQixDQUFDLFFBQXVDO0lBQzFFLElBQU0sSUFBSSxHQUFvQixJQUFJLHdCQUFlLEVBQUUsQ0FBQTtJQUVuRCxJ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