liveperson-functions-cli
Version:
LivePerson Functions CLI
282 lines • 11.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileService = void 0;
const crypto = require("crypto");
const fsDefault = require("fs-extra");
const systeminformation_1 = require("systeminformation");
const os = require("os");
const path_1 = require("path");
const semver = require("semver");
class FileService {
constructor({ cwd = process.cwd(), fs = fsDefault, sysinfo = systeminformation_1.system, dirname = __dirname, } = {}) {
this.cwd = cwd;
this.fs = fs;
this.sysinfo = sysinfo;
this.dirname = dirname;
}
copy(sourcePath, destinationPath) {
try {
this.fs.copySync(sourcePath, destinationPath);
}
catch (error) {
throw new Error(error);
}
}
directoryOrFileExists(pathToFile) {
return this.fs.existsSync(pathToFile);
}
/**
* Returns the path to a functions folder or a file inside a function folder
* @param {string} functionsName
* @param {string} [fileName]
* @returns {string} - path to function or file
* @memberof FileService
*/
// eslint-disable-next-line complexity
getPathToFunction(functionsName, fileName) {
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, 'functions'))) {
/* istanbul ignore else */
if (functionsName &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, 'functions', functionsName, fileName || ''))) {
return (0, path_1.join)(this.cwd, 'functions', functionsName, fileName || '');
}
} /* istanbul ignore else */
else if (this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', 'functions'))) {
/* istanbul ignore else */
if (functionsName &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, functionsName, fileName || ''))) {
return (0, path_1.join)(this.cwd, functionsName, fileName || '');
}
} /* istanbul ignore else */
else if (this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', '..', 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', '..', 'functions'))) {
/* istanbul ignore else */
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, fileName || ''))) {
return (0, path_1.join)(this.cwd, fileName || '');
}
}
if (!functionsName) {
throw new Error('Could not find function. Please make sure you are in a function folder or pass a function name.');
}
throw new Error(`Could not find the folder of function ${functionsName}. Please make sure it's available in the functions folder.`);
}
/**
* Returns the path to the settings.json
* @returns {string} - path to settings.json
* @memberof FileService
*/
getPathToSettings() {
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, 'functions'))) {
/* istanbul ignore else */
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, 'functions', 'settings.json'))) {
return (0, path_1.join)(this.cwd, 'functions', 'settings.json');
}
} /* istanbul ignore else */
else if (this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', 'functions'))) {
/* istanbul ignore else */
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, 'settings.json'))) {
return (0, path_1.join)(this.cwd, 'settings.json');
}
}
throw new Error("Could not find settings.json. Please make sure it's available in the functions folder.");
}
/**
* Reads a the content of a file
* @param {string} pathToFile - path to file
* @param {boolean} [parseJSON=true] - should the output be parsed as JSON
* @param {string} [encoding='utf8'] - encoding of the file
* @returns {*} - content of a file
* @memberof FileService
*/
read(pathToFile, parseJSON = true, encoding = 'utf8') {
/* istanbul ignore else */
if (parseJSON) {
return this.directoryOrFileExists(pathToFile)
? JSON.parse(this.fs.readFileSync(pathToFile, encoding))
: undefined;
}
return this.directoryOrFileExists(pathToFile)
? this.fs.readFileSync(pathToFile, encoding)
: undefined;
}
/**
* Returns all function directories
* @returns {string[]} - Array of function folders
* @memberof FileService
*/
getFunctionsDirectories() {
return this.fs
.readdirSync((0, path_1.join)(this.getRoot(), 'functions'), { withFileTypes: true })
.filter((dirent) => dirent.isDirectory())
.map((dirent) => dirent.name);
}
/**
* Write content to a file
* @param {string} pathToWriteFile - path to the file
* @param {*} data - content of the file
* @param {boolean} [stringify=true] - should the content be stringified
* @param {string} [encoding='utf8'] - encoding of the file
* @returns {void}
* @memberof FileService
*/
write(pathToWriteFile, data, stringify = true, encoding = 'utf8') {
try {
/* istanbul ignore else */
if (stringify) {
this.fs.writeFileSync(pathToWriteFile, JSON.stringify(data, null, 4), encoding);
return;
}
this.fs.writeFileSync(pathToWriteFile, data, encoding);
}
catch (error) {
throw new Error(error);
}
}
/**
* Returns the decrypted temp file.
* @returns {Promise<any>} - returns the decrypted temp file
* @memberof FileService
*/
async getTempFile() {
const data = this.read((0, path_1.join)(os.tmpdir(), 'faas-tmp.json'));
/* istanbul ignore else */
if (!data) {
return undefined;
}
return this.decrypt(data);
}
/**
* Writes the temp file to the temp directory of the os.
* (Temp directory of the OS gets cleared after restart)
* @param {*} data - temp file content
* @returns {Promise<void>} - void
* @memberof FileService
*/
async writeTempFile(data) {
const encryptedData = await this.encrypt(data);
this.write((0, path_1.join)(os.tmpdir(), 'faas-tmp.json'), encryptedData);
}
/**
* Deletes the temp file from the os temp directory
* @memberof FileService
*/
deleteTempFile() {
this.fs.removeSync((0, path_1.join)(os.tmpdir(), 'faas-tmp.json'));
}
/**
* Returns the function config (config.json) of the passed function.
* @param {string} functionName - function name
* @returns {*} - config
* @memberof FileService
*/
getFunctionConfig(functionName) {
return this.read(this.getPathToFunction(functionName, 'config.json'));
}
/**
* Returns config files for multiple passed functions.
* @param {string[]} [lambdaFunctions] - lambda functions
* @returns {ILambdaConfig[]} - Lambda configs
* @memberof FileService
*/
collectLocalLambdaInformation(lambdaFunctions) {
/* istanbul ignore else */
if (lambdaFunctions === null || lambdaFunctions === void 0 ? void 0 : lambdaFunctions.length) {
return lambdaFunctions.map((lambdaFunction) => this.getFunctionConfig(lambdaFunction));
}
const lambda = this.read((0, path_1.join)(this.cwd, 'config.json'));
/* istanbul ignore else */
if (!lambda) {
throw new Error('Could not find function. Please make sure you are in a function folder or pass a function name.');
}
return [lambda];
}
/**
* Returns the name of the function folder.
* Needed if the user calls a command inside a function folder.
* @returns {string} - function folder name
* @memberof FileService
*/
getFunctionFolderName() {
const lambda = this.read((0, path_1.join)(this.cwd, 'config.json'));
/* istanbul ignore else */
if (!lambda) {
throw new Error('Could not find function. Please make sure you are in a function folder or pass a function name.');
}
return lambda.name;
}
/**
* Returns the path to the root directory
* @returns {string} - root directory
* @memberof FileService
*/
getRoot() {
/* istanbul ignore else */
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, 'functions'))) {
return (0, path_1.join)(this.cwd);
}
/* istanbul ignore else */
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', 'functions'))) {
return (0, path_1.join)(this.cwd, '..');
}
/* istanbul ignore else */
if (this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', '..', 'bin')) &&
this.directoryOrFileExists((0, path_1.join)(this.cwd, '..', '..', 'functions'))) {
return (0, path_1.join)(this.cwd, '..', '..');
}
throw new Error(`Could not find root directory. Please make sure you are in a faas project.`);
}
needUpdateBinFolder() {
try {
const cliPackage = this.read((0, path_1.join)(this.dirname, '..', '..', 'package.json'));
const cliVersion = cliPackage === null || cliPackage === void 0 ? void 0 : cliPackage.version;
const toolbeltPackage = this.read((0, path_1.join)(this.getRoot(), 'bin', 'lp-faas-toolbelt', 'package.json'));
const toolbeltVersion = toolbeltPackage === null || toolbeltPackage === void 0 ? void 0 : toolbeltPackage.version;
return semver.gt(cliVersion, toolbeltVersion);
}
catch {
return false;
}
}
/**
* Return the config for crypto.
* Takes the uuid of the system as password for pseudo encryption.
* @returns {Promise<{ algorithm: string; key: Buffer; iv: string }>}
*/
async getCryptoConfig() {
let systemUUID;
try {
const sysData = await this.sysinfo();
systemUUID = sysData.uuid;
}
catch {
systemUUID = '01:02:03:04:05:06';
}
return {
algorithm: 'aes256',
key: crypto.scryptSync(systemUUID, 'faas-cli', 32),
iv: 'faas-cli-vectors',
};
}
async encrypt(data) {
const { algorithm, key, iv } = await this.getCryptoConfig();
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(JSON.stringify(data), 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
async decrypt(data) {
const { algorithm, key, iv } = await this.getCryptoConfig();
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update(data, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return JSON.parse(decrypted);
}
}
exports.FileService = FileService;
//# sourceMappingURL=file.service.js.map