import { Component, JsonObject, Json, IConfig } from "merapi"; import * as _ from "lodash"; import * as path from "path"; import * as fs from "fs"; import * as yaml from "js-yaml"; import * as os from "os"; import * as inquirer from "inquirer"; import { IMerapiDescriptor, IHelper } from "interfaces/main"; import { exec, execSync } from "child_process"; import { copySync } from "fs-extra"; import { join } from "path"; export default class Helper extends Component implements IHelper { public printError = (error : any) => console.error(this.wrapError(error)); constructor(private config : IConfig, private basepath : string) { super(); this.basepath = basepath; } public getFiles(dir : string, ending : string) : string[] { const fileList = fs.readdirSync(dir); const res = []; for (const file in fileList) { if (file) { const stat = fs.statSync(path.resolve(dir, file)); if (stat.isDirectory()) { res.push(...this.getFiles(dir + "/" + file, ending)); } else if (stat.isFile() && file.endsWith(ending)) { res.push(dir + "/" + file); } } } 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 dumpPackageJson(merapiDescriptor : IMerapiDescriptor) : void { const packageDescriptor = { name: merapiDescriptor.name.toLowerCase().replace(" ", "-"), version: "0.0.1", description: "", main: "index.js", repository: { type: "git", url: "https://example.com/" }, nyc: { include: [ "components/**/*.ts", "components/*.ts", "interfaces/*.ts" ], exclude: [ "node_modules" ], extension: [ ".ts" ], require: [ "ts-node/register" ], reporter: [ "json", "html" ], all: true }, author: merapiDescriptor.author, license: "ISC", dependencies: { "@types/node": "^7.0.28", "js-yaml": "^3.9.1", "merapi": "^0.17.1", "lodash": "^4.17.4", } }; fs.writeFileSync("package.json", JSON.stringify(packageDescriptor, null, 4)); this.doNpmInstall(); merapiDescriptor.plugins.forEach((data) => { if (data) { this.doNpmInstall(`--save ${data}`); } }); } public copyAll() : void { // sementara // const indexTemplate = `"use strict"; // const _ = require("lodash"); // const path = require("path"); // const merapi = require("merapi"); // const yaml = require("js-yaml"); // const fs = require("fs"); // const config = yaml.safeLoad(fs.readFileSync("./service.yml", "utf8")); // config.package = require("./package"); // const plugins = yaml.safeLoad(fs.readFileSync("./plugin.yml", "utf8")); // const env = process.env.PLUGIN_ENV || "platform"; // const pluginConf = plugins[env]; // if (pluginConf) { // if (pluginConf.include) // config.plugins = _.union(config.plugins, pluginConf.include); // if (pluginConf.exclude) // config.plugins = _.without(config.plugins, ...pluginConf.exclude); // } // module.exports = merapi({ // basepath: path.resolve(__dirname, "lib"), // config: config, // delimiters: { left: "${", right: "}" } // }); // `; // const startTemplate = `"use strict"; // let boot = require("./index.js"); // try { // boot.start(); // } // catch (e) { // console.log(e.stack); // process.exit(); // }`; // fs.writeFileSync("index.js", indexTemplate); // fs.writeFileSync("start.js", startTemplate); // yg asli // const templatePath = this.config.get("path.template") as string; const currentDir = path.resolve(this.basepath, "../templates"); const templatePath = currentDir; console.log(templatePath); const filesContent = fs.readdirSync(templatePath); filesContent.forEach((data) => { copySync(path.join(templatePath, data), ".", { overwrite: false}); }); } private doNpmInstall(args : string = "") : void { execSync(`npm install ${args}`); } 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) { if (i) { 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 toPromise(ctx : any, func : any, ...args : any[]) : Promise { 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 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 { return inquirer.prompt(questions); } public wrapError(error : any) { let errorMessage; if (error.response && error.response.body && error.response.body.message) { errorMessage = error.response.body.message; } else { errorMessage = error.message; } return errorMessage; } public difference(object : any, base : any) { return this.changes(object, base); } private changes(object1 : any, base2 : any) { return _.transform(object1, (result, value, key) => { if (!_.isEqual(value, base2[key])) { result[key] = (_.isObject(value) && _.isObject(base2[key])) ? this.changes(value, base2[key]) : value; } }); } }