UNPKG

@tableau/taco-toolkit

Version:
297 lines 24.6 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAppLogOption = exports.parseFeatureFlags = exports.parseStaticServerPort = exports.parseMainPort = exports.parsePortRange = exports.parseArgs = exports.handleLoggerSetup = void 0; var commander_1 = require("commander"); var node_os_1 = __importDefault(require("node:os")); var node_path_1 = __importDefault(require("node:path")); var uuid_1 = require("uuid"); var caller_type_1 = require("../../../../shared/enums/caller-type"); var error_codes_1 = require("../../../../shared/errors/error-codes"); var error_source_1 = require("../../../../shared/errors/error-source"); var status_code_1 = require("../../../../shared/errors/status-code"); var log_level_1 = require("../../../../shared/logger/log-level"); var eps_logger_1 = require("../../../logging/eps-logger"); var app_init_1 = require("./app-init"); var EPS_INSTANCE_ID = (0, uuid_1.v4)(); var epsTempDirRoot = node_path_1.default.join(node_os_1.default.tmpdir(), 'tableau-eps-temp'); var epsTempDir = node_path_1.default.join(epsTempDirRoot, EPS_INSTANCE_ID); // TODO: the default folder should not have Tableau dependency... // verify there's nothing replying on this, and point to cwd/log var DEFAULT_LOG_DIR = node_path_1.default.join(node_os_1.default.homedir(), 'Documents', 'My Tableau Repository', 'Logs'); var DEFAULT_LOG_LEVEL = log_level_1.LogLevel.DEBUG; var DEFAULT_STATIC_SERVER_UI_DIR = node_path_1.default.join(epsTempDir, 'static-server', 'app'); var DEFAULT_STATIC_SERVER_HANDLERS_DIR = node_path_1.default.join(epsTempDir, 'static-server', 'handlers'); var DEFAULT_LANGUAGE = 'en_US'; var DEFAULT_LOCALE = 'en_US'; /** * A command line value for log level option to disable a log writer. * Note: it should be only used in the command line layer. */ var LOG_OFF_LEVEL = 'off'; var logLevelChoices = __spreadArray(__spreadArray([], __read(log_level_1.logLevelValues), false), [LOG_OFF_LEVEL], false); function handleLoggerSetup(args) { var program = new commander_1.Command(); // throw for error cases, so that it can log errors and fall back addLoggerOptions(program).allowUnknownOption().exitOverride(); try { program.parse(args); } catch (error) { // if logger configs are incorrect, init logger with fallback settings eps_logger_1.Logger.init(EPS_INSTANCE_ID, { filename: eps_logger_1.EPS_LOG_FILE_NAME, fileLogDirPath: DEFAULT_LOG_DIR, fileLogLevel: log_level_1.LogLevel.INFO, sourceName: 'EPS', consoleLogLevel: log_level_1.LogLevel.WARNING, }); eps_logger_1.Logger.error("Invalid logging options: ".concat(error, ".")); eps_logger_1.Logger.warn('Initializing logger with fallback settings.'); return; } var _a = program.opts(), logDir = _a.logDir, logLevel = _a.logLevel, consoleLogLevel = _a.consoleLogLevel; var appLogOption = getAppLogOption({ logDir: logDir, logLevel: logLevel, consoleLogLevel: consoleLogLevel }); var loggerConfig = (0, eps_logger_1.createLoggerConfig)('EPS', appLogOption); eps_logger_1.Logger.init(EPS_INSTANCE_ID, loggerConfig); } exports.handleLoggerSetup = handleLoggerSetup; function addLoggerOptions(program) { return program .option('--log-dir <log_dir>', 'Log Directory', DEFAULT_LOG_DIR) .addOption(new commander_1.Option('--log-level <log_level>', "Log level for file-based logs. Choices: ".concat(logLevelChoices)) .argParser(parseLogLevel) .default(DEFAULT_LOG_LEVEL)) .addOption(new commander_1.Option('--console-log-level <log_level>', "Log level for console logs. Choices: ".concat(logLevelChoices)) .argParser(parseLogLevel) .default(LOG_OFF_LEVEL)); } function parseLogLevel(value) { var lowerCaseValue = value.toLowerCase(); if (!logLevelChoices.includes(lowerCaseValue)) { throw new commander_1.InvalidArgumentError("Allowed choices are: ".concat(logLevelChoices)); } return lowerCaseValue; } function parseArgs(args) { var program = new commander_1.Command(); addLoggerOptions(program) .requiredOption('--caller-pid <caller_pid>', 'Caller Process Id', parsePid) .requiredOption('--caller-id <caller_id>', 'Caller Id') .requiredOption('--port-file <port_file>', 'Port file path') .addOption(new commander_1.Option('--caller-type <caller_type>', 'Valid values: desktop, prep, vizqlserver, etc.') .choices(Object.values(caller_type_1.CallerType)) .default(caller_type_1.CallerType.desktop)) .addOption(new commander_1.Option('--mode <mode>', "Valid values: ".concat(Object.values(app_init_1.ServerMode))) .choices(Object.values(app_init_1.ServerMode)) .default(app_init_1.ServerMode.prod)) .option('--feature-flags <feature_flags>', 'EPS feature flags as defined in monolith') .option('--port-range <port_range>', 'Port range for all EPS services. Format: start-end', parsePortRange, [9089, 9999]) .option('--static-server-ui-dir <log_dir>', 'Connector app root directory', DEFAULT_STATIC_SERVER_UI_DIR) .option('--static-server-handlers-dir <log_dir>', 'Connector handlers root directory', DEFAULT_STATIC_SERVER_HANDLERS_DIR) .option('--static-server-port <port>', 'Static Server port to use, for vizqlserver only') .option('--main-port <port>', 'Main API port to use, for vizqlserver only') .option('--grpc-server-port <port>', 'grpc Server port to use', parsePort) .option('--language <language>', 'Runtime user choice for language', DEFAULT_LANGUAGE) .option('--locale <locale>', 'Runtime user choice for locale', DEFAULT_LOCALE) .option('--eps-temp-dir-path <dir_path>', 'Root for temporary file storage', epsTempDirRoot) .addHelpCommand() .allowUnknownOption() .configureOutput({ writeOut: function (str) { return eps_logger_1.Logger.info("".concat(str)); }, writeErr: function (str) { return eps_logger_1.Logger.logEPSError(status_code_1.StatusCode.InvalidArgument, error_source_1.ErrorSources.Content, error_codes_1.ErrorCodes.ORP420NN, "Error with command line options. ".concat(str)); }, }); program.parse(args); var options = program.opts(); eps_logger_1.Logger.debug("Command arguments: ".concat(JSON.stringify(options, undefined, 2))); return __assign(__assign({}, options), { // addtional parsing for certain properties mainPort: parseMainPort(options), staticServerPort: parseStaticServerPort(options), featureFlags: parseFeatureFlags(options.featureFlags), epsInstanceId: EPS_INSTANCE_ID }); } exports.parseArgs = parseArgs; function parsePortRange(portRange) { var parts = portRange.split('-'); if (parts.length !== 2) { throw new commander_1.InvalidArgumentError("Port range must be formatted in 'start-end'"); } var start = parseInt(parts[0], 10); var end = parseInt(parts[1], 10); if (!isValidPort(start) || !isValidPort(end)) { throw new commander_1.InvalidArgumentError("Invalid port number in the port range: ".concat(portRange)); } if (end - start < 5) { throw new commander_1.InvalidArgumentError('EPS requires at least 5 ports'); } return [start, end]; } exports.parsePortRange = parsePortRange; function parsePort(portString) { var port = parseInt(portString, 10); if (!isValidPort(port)) { throw new commander_1.InvalidArgumentError("Invalid port number: ".concat(portString)); } return port; } function isValidPort(port) { return Number.isInteger(port) && port > 0 && port <= 65535; } function parsePid(pidString) { var pid = parseInt(pidString, 10); if (isNaN(pid) || pid < 0) { throw new commander_1.InvalidArgumentError("Invalid pid number: ".concat(pidString)); } return pid; } function parseMainPort(options) { var callerType = options.callerType, mainPort = options.mainPort; if (mainPort === undefined) { if (callerType === caller_type_1.CallerType.vizQLServer || callerType === caller_type_1.CallerType.dcf) { throw new Error("--main-port must be provided when --caller-type is ".concat(callerType, ".")); } return; } if (callerType !== caller_type_1.CallerType.vizQLServer && callerType !== caller_type_1.CallerType.dcf) { throw new Error("--main-port can be only used when --caller-type is ".concat(caller_type_1.CallerType.vizQLServer, " or ").concat(caller_type_1.CallerType.dcf, ". The current caller type is '").concat(callerType, "'.")); } return parsePort(mainPort); } exports.parseMainPort = parseMainPort; function parseStaticServerPort(options) { var callerType = options.callerType, staticServerPort = options.staticServerPort; if (staticServerPort === undefined) { if (callerType === caller_type_1.CallerType.vizQLServer) { throw new Error("--static-server-port must be provided when --caller-type is ".concat(callerType, ".")); } return; } if (callerType !== caller_type_1.CallerType.vizQLServer) { throw new Error("--static-server-port can be only used when --caller-type is ".concat(caller_type_1.CallerType.vizQLServer, ". The current caller type is '").concat(callerType, "'.")); } return parsePort(staticServerPort); } exports.parseStaticServerPort = parseStaticServerPort; /** * The configuration for feature flags from monolith. * This config does not include all feature flags passed from monolith, * but only the flags that EPS needs to handle. */ var FEATURE_FLAGS_CONFIG = { EPSSupportgRPC: { falseValue: 'off', defaultValue: true, }, EPSStaticTacoUnpack: { falseValue: 'off', defaultValue: true, }, }; function parseFeatureFlags(input) { var e_1, _a; var flagsString = input !== null && input !== void 0 ? input : ''; var args = flagsString .split(',') .filter(Boolean) .map(function (arg) { var _a = __read(arg.split(':'), 2), key = _a[0], value = _a[1]; return [key.trim(), value === null || value === void 0 ? void 0 : value.trim()]; }); var flags = Object.fromEntries(args); var result = {}; try { for (var _b = __values(Object.entries(FEATURE_FLAGS_CONFIG)), _c = _b.next(); !_c.done; _c = _b.next()) { var _d = __read(_c.value, 2), key = _d[0], config = _d[1]; var flagName = key; eps_logger_1.Logger.info("IN FF PARSING LOOP: ".concat(flagName)); var defaultValue = config.defaultValue, falseValue = config.falseValue; var value = flags[flagName]; if (value === falseValue) { result[flagName] = false; } else { result[flagName] = defaultValue; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } return result; } exports.parseFeatureFlags = parseFeatureFlags; /** * Get app log options from command line values */ function getAppLogOption(options) { var logLevel = options.logLevel, consoleLogLevel = options.consoleLogLevel, logDir = options.logDir; if (logLevel === LOG_OFF_LEVEL) { return { // if file-based log has been explicitly disabled, force to enable console log consoleLogLevel: consoleLogLevel === LOG_OFF_LEVEL ? log_level_1.LogLevel.INFO : consoleLogLevel, logDir: undefined, logLevel: undefined, }; } var logOption = { logDir: logDir, logLevel: logLevel, consoleLogLevel: consoleLogLevel === LOG_OFF_LEVEL ? undefined : consoleLogLevel, }; return logOption; } exports.getAppLogOption = getAppLogOption; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC1saW5lLXBhcnNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lcHMvbWFpbi9jb3JlL2FwcC11dGlscy9jb21tYW5kLWxpbmUtcGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdUNBQStFO0FBQy9FLG9EQUF3QjtBQUN4Qix3REFBNEI7QUFDNUIsNkJBQW1DO0FBRW5DLG9FQUFpRTtBQUNqRSxxRUFBa0U7QUFDbEUsdUVBQXFFO0FBQ3JFLHFFQUFrRTtBQUNsRSxpRUFBOEU7QUFDOUUsMERBQTJGO0FBRzNGLHVDQUF1RDtBQUV2RCxJQUFNLGVBQWUsR0FBRyxJQUFBLFNBQU0sR0FBRSxDQUFBO0FBQ2hDLElBQU0sY0FBYyxHQUFHLG1CQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFFLENBQUMsTUFBTSxFQUFFLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtBQUNqRSxJQUFNLFVBQVUsR0FBRyxtQkFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsZUFBZSxDQUFDLENBQUE7QUFFN0QsaUVBQWlFO0FBQ2pFLGdFQUFnRTtBQUNoRSxJQUFNLGVBQWUsR0FBRyxtQkFBSSxDQUFDLElBQUksQ0FBQyxpQkFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLFdBQVcsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLENBQUMsQ0FBQTtBQUM3RixJQUFNLGlCQUFpQixHQUFHLG9CQUFRLENBQUMsS0FBSyxDQUFBO0FBQ3hDLElBQU0sNEJBQTRCLEdBQUcsbUJBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQTtBQUNsRixJQUFNLGtDQUFrQyxHQUFHLG1CQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxlQUFlLEVBQUUsVUFBVSxDQUFDLENBQUE7QUFDN0YsSUFBTSxnQkFB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