import { Command , flags } from "@oclif/command" ; import { IConfig } from "@oclif/config" ; import { OutputFlags } from "@oclif/parser" ; import * as path from "path" ; import * as fs from "fs-extra" ; export default abstract class FlanCommand extends Command { localConfig : { database : { host : string ; db : string ; user ? : string ; port ? : string ; } ; baseDir : string ; saveDir : string ; repoDir : string ; repository ? : string ; } ; static flags = { config : flags . string ( { char : "c" , description : "Path to configuration file" , env : "FLAN_CONFIG" , default : "./flan.config.json" , } ) , } ; protected parsedFlags ? : OutputFlags < typeof FlanCommand . flags > ; constructor ( argv , config ) { super ( argv , config ) ; this . localConfig = { baseDir : ".flan" , saveDir : ".flan/local" , repoDir : ".flan/repo" , database : { host : "localhost" , db : "" , user : "" , port : "5432" , } , } ; } async init ( ) { const { flags } = this . parse ( this . ctor ) ; await this . loadConfigFile ( flags . config as unknown as string ) ; } getPgConnectionArgs ( ) { return [ `--host=${ this . localConfig . database . host }` , `--dbname=${ this . localConfig . database . db }` , "-U" , this . localConfig . database . user as string , `--port=${ this . localConfig . database . port }` , ] ; } async loadConfigFile ( configPath ) { let configJSON = { } ; try { configJSON = await fs . readJson ( configPath ) ; } catch ( error ) { if ( ! error . code || error . code !== "ENOENT" ) { this . error ( "A config file exists but it could not be loaded" ) ; } } this . localConfig = { baseDir : path . resolve ( process . env . FLAN_BASE_DIR || configJSON . baseDir || this . localConfig . baseDir ) , repoDir : path . resolve ( process . env . FLAN_BASE_DIR || configJSON . baseDir || this . localConfig . baseDir , "./repo" ) , saveDir : path . resolve ( process . env . FLAN_BASE_DIR || configJSON . baseDir || this . localConfig . baseDir , "./local" ) , database : { host : process . env . PGHOST || configJSON . database ?. host || this . localConfig . database . host , db : process . env . PGDATABASE || configJSON . database ?. db || this . localConfig . database . db , user : process . env . PGUSER || configJSON . database ?. user || this . localConfig . database . user , port : process . env . PGPORT || configJSON . database ?. port || this . localConfig . database . port , } , } ; if ( process . env . FLAN_REPOSITORY || configJSON . repository ) { this . localConfig . repository = process . env . FLAN_REPOSITORY || configJSON . repository ; } if ( process . env . FLAN_REPO_DIR || configJSON . repoDir ) { this . localConfig . repoDir = path . resolve ( process . env . FLAN_REPO_DIR || configJSON . repoDir || "" ) ; } if ( process . env . FLAN_SAVE_DIR || configJSON . saveDir ) { this . localConfig . saveDir = path . resolve ( process . env . FLAN_SAVE_DIR || configJSON . saveDir || "" ) ; } if ( ! this . localConfig . database . db ) { this . error ( "Database is required" ) ; } if ( ! this . localConfig . database . user ) { this . error ( "Database username is required" ) ; } } async runHook ( name ) { const hooksFileName = path . resolve ( process . cwd ( ) , "./flan.hooks.js" ) ; const hooksExists = await fs . pathExists ( hooksFileName ) ; if ( hooksExists ) { const hooks = require ( hooksFileName ) ; if ( typeof hooks [ name ] === "function" ) return hooks [ name ] ( ) ; } } }