UNPKG

kata-cli

Version:
315 lines (251 loc) 10.2 kB
import { Component, JsonObject, Json, IConfig } from "merapi"; import * as _ from "lodash"; const Catch = require("catch-decorator"); const yaml = require("js-yaml"); const fs = require("fs"); const os = require("os"); const path = require("path"); const inquirer = require("inquirer"); const analytics = require("universal-analytics"); function wrapError(error: any) { let errorMessage; if (error.response && error.response.body && error.response.body.message) { errorMessage = error.response.body.message; } else if (error.response && error.response.body) { errorMessage = error.response.body; } else { errorMessage = error.message; } return errorMessage; } export const CatchError = Catch(Error, (error: any) => { console.log("Error"); console.error(wrapError(error)); }); export default class Helper extends Component { constructor(private config : IConfig) { super(); } public getFiles(dir : string, ending : string) : string[] { const fileList = fs.readdirSync(dir); const res = []; for (let i = 0; i < fileList.length; i++) { const stat = fs.statSync(path.resolve(dir, fileList[i])); if (stat.isDirectory()) { res.push(...this.getFiles(dir + "/" + fileList[i], ending)); } else if (stat.isFile() && fileList[i].endsWith(ending)) { res.push(dir + "/" + fileList[i]); } } return res; } public loadYaml(file : string) : JsonObject { return yaml.safeLoad(fs.readFileSync(file, "utf8")); } public dumpYaml(file : string, object : JsonObject) : void { fs.writeFileSync(file, yaml.safeDump(object, { indent: 4, lineWidth: 150 }), "utf8"); } public compareTestResult(result : Json, expect : Json) : { field : string, expect : any, result : any }[] { if (!result) { return null; } const errors = []; const expected = this.config.create(expect).flatten(); const res = this.config.create(result); for (const i in expected) { const value = res.get(i); if (value !== expected[i]) { errors.push({ field: i, expect: expected[i], result: value }); } } return errors; } public setProp(prop : string, value : string, options? : JsonObject) : void { const jsonPath = `${os.homedir()}/.katajson`; let jsonProp; if (fs.existsSync(jsonPath)) { jsonProp = JSON.parse(fs.readFileSync(jsonPath, "utf8")); } else { jsonProp = {}; } jsonProp[prop] = value; fs.writeFileSync(jsonPath, JSON.stringify(jsonProp), "utf8"); } public getProp(prop : string, options? : JsonObject) : Json { const jsonPath = `${os.homedir()}/.katajson`; let jsonProp; if (fs.existsSync(jsonPath)) { jsonProp = JSON.parse(fs.readFileSync(jsonPath, "utf8")); } else { jsonProp = {}; } return jsonProp[prop]; } public delete() : Boolean { const jsonPath = `${os.homedir()}/.katajson`; if (fs.existsSync(jsonPath)) { fs.unlinkSync(jsonPath); return true; } return false; } public deleteKeyToken(userName: string) { const jsonPath = `${os.homedir()}/.katajson`; let jsonProp; if (fs.existsSync(jsonPath)) { jsonProp = JSON.parse(fs.readFileSync(jsonPath, "utf8")); // if userName token exist if (userName in jsonProp.token) { jsonProp.current_login = "admin"; delete jsonProp.token[userName]; delete jsonProp.projectId; delete jsonProp.projectName; delete jsonProp.isImpersonate; } else { return new Error(`Failed to unimpersonate ${(userName)}`); } } else { jsonProp = {}; } fs.writeFileSync(jsonPath, JSON.stringify(jsonProp), "utf8"); return jsonProp; } public toPromise(ctx : any, func : any, ...args : any[]) : Promise<any> { return new Promise((resolve, reject) => { args.push((error : Error, data : any, response : Response) => { if (error) { reject(error); } else { resolve({ data, response }); } }); func.apply(ctx, args); }); } public getBotId() : string { const desc = this.loadYaml("./bot.yml"); return desc.id as string; } public getProjectId(): string { return this.getProp("projectId") as string; } public createDirectory(dirPath: string, mode?: number) { if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, mode); } } public getCurrentToken() : JsonObject { const currentLogin = this.getProp("current_login") as string || ""; const tokenProp = (this.getProp("token") || {}) as JsonObject; return { currentLogin, token: tokenProp[currentLogin] }; } public loadYamlOrJsonFile(filePath : string) { if (!fs.existsSync(filePath)) { return new Error("FILE NOT FOUND"); } const fileExt = path.extname(filePath); if (fileExt === ".json") { return JSON.parse(fs.readFileSync(filePath, "utf8")); } else if (fileExt === ".yml" || fileExt === ".yaml") { return this.loadYaml(filePath); } else if (fileExt === ".txt") { return fs.readFileSync(filePath, "utf8"); } else { return new Error("UNSUPPORTED FILE TYPE"); } } public async inquirerPrompt(questions : JsonObject[]) : Promise<JsonObject> { return inquirer.prompt(questions); } public wrapError(error: any) { const errorMessage: string = wrapError(error); const commands: JsonObject[] = this.getCommandSession(); // Note: error might happen even after clearCommandSession is called // this might results in an empty command, we do not want to track empty command error if (commands.length > 0) { const lastCommand: string = commands[commands.length - 1].command as string; const mainCommand: string = lastCommand.split(" ")[0]; this.sendGoogleAnalytics("debug", mainCommand, lastCommand, commands, errorMessage); this.clearCommandSession(); } return errorMessage; } public difference(object: any, base: any) { function changes(object: any, base: any) { return _.transform(object, function(result: any, value, key) { if (!_.isEqual(value, base[key])) { result[key] = (_.isObject(value) && _.isObject(base[key])) ? changes(value, base[key]) : value; } }); } return changes(object, base); } public viewConfig() : void { const jsonPath = `${os.homedir()}/.katajson`; let jsonProp; if (fs.existsSync(jsonPath)) { jsonProp = JSON.parse(fs.readFileSync(jsonPath, "utf8")); delete jsonProp.first_login; } else { jsonProp = ".katajson file not found"; } console.log(jsonProp); } public checkNotificationStatus(): Boolean { const jsonPath = `${os.homedir()}/.katanotif`; if (fs.existsSync(jsonPath)) { return true } else { fs.writeFileSync(jsonPath, "true", "utf8"); return false } } public addCommandSession(command:string): void { const jsonPath = `${os.homedir()}/.katacommand`; let jsonData:JsonObject[] = []; if (fs.existsSync(jsonPath)) jsonData = JSON.parse(fs.readFileSync(jsonPath, "utf8")); if (jsonData.length > 0) { const lastData:JsonObject = jsonData[jsonData.length - 1] const diff:number = Math.abs(Number(lastData.timestamp) - new Date().getTime()) / 36e5; if (diff >= 1) jsonData = [] //Lebih dari 1 jam ? } jsonData.push({ timestamp: new Date().getTime(), command: command }) fs.writeFileSync(jsonPath, JSON.stringify(jsonData), "utf8"); } public getCommandSession(): JsonObject[] { const jsonPath = `${os.homedir()}/.katacommand`; let jsonData:JsonObject[] = []; if (fs.existsSync(jsonPath)) jsonData = JSON.parse(fs.readFileSync(jsonPath, "utf8")); return jsonData } public clearCommandSession(): void { const jsonPath = `${os.homedir()}/.katacommand`; fs.writeFileSync(jsonPath, "[]", "utf8"); } public sendGoogleAnalytics(event:string, action:string, command:string, lastSession?:JsonObject[], errorMessage?:string): void { let firstLogin = this.getProp("first_login") as JsonObject; let projectId = this.getProp("projectId") as string; let projectName = this.getProp("projectName") as string; if (!firstLogin) firstLogin = { id: null, username: null, type: null } if (!projectId) projectId = null if (!projectName) projectName = null const version = this.config.default("version", "1.0.0") const google = analytics(this.config.default("config.trackingId", "UA-131926842-1"), firstLogin.id); const data:JsonObject = { userId: firstLogin.id, username: firstLogin.username, currentUserType: firstLogin.type, activeProjectId: projectId, activeProjectName: projectName, command: command, versionCLI: version, timestamp: new Date().getTime() } if (lastSession) data.lastSession = lastSession if (errorMessage) data.errorMessage = errorMessage google.event(event, action, JSON.stringify(data), (err:any) => { if (err) console.log(this.wrapError(err)); }) } }