/**
 * FoalTS
 * Copyright(c) 2017-2021 Loïc Poullain <loic.poullain@centraliens.net>
 * Released under the MIT License.
 */ import { red , yellow } from 'colors/safe' ; import * as program from 'commander' ; import { createSecret } from './create-secret' ; import { connectAngular , connectReact , connectVue , createApp , createController , createEntity , createHook , createRestApi , createScript , createService , createVSCodeConfig , } from './generate' ; import { ClientError } from './generate/file-system' ; import { rmdir } from './rmdir' ; import { runScript } from './run-script' ; function displayError ( ... lines ) { console . error ( ) ; lines . forEach ( line => console . error ( red ( line ) ) ) ; console . error ( ) ; process . exitCode = 1 ; } const pkg = require ( '../package.json' ) ; program . version ( pkg . version , '-v, --version' ) ; program . command ( 'createapp <name>' ) . description ( 'Create a new project.' ) . option ( '-G, --no-git' , 'Don\'t initialize a git repository' ) . option ( '-I, --no-install' , 'Don\'t autoinstall packages using yarn or npm (uses first available)' ) . option ( '-m, --mongodb' , 'Generate a new project using MongoDB instead of SQLite' , false ) . option ( '-y, --yaml' , 'Generate a new project using YAML configuration instead of JSON' , false ) . action ( ( name , options ) => { createApp ( { autoInstall : options . install , initRepo : options . git , mongodb : options . mongodb , name , yaml : options . yaml } ) ; } ) ; program . command ( 'createsecret' ) . description ( 'Create a 256-bit random secret encoded in base64.' ) . action ( ( ) => createSecret ( ) . then ( secret => console . log ( secret ) ) ) ; program . command ( 'run <name>' ) . alias ( 'run-script' ) . description ( 'Run a shell script.' ) . action ( ( name ) => { runScript ( { name } , process . argv ) ; } ) ; program . command ( 'connect <framework> <path>' ) . description ( 'Configure your frontend to interact with your application.' ) . addHelpText ( 'after' , `
Available frameworks:
  - angular
  - react
  - vue
  ` ) . action ( async ( framework , path ) => { switch ( framework ) { case 'angular' : connectAngular ( path ) ; break ; case 'react' : connectReact ( path ) ; break ; case 'vue' : connectVue ( path ) ; break ; default : displayError ( `Unknown framework ${ yellow ( framework ) }. Please provide a valid one:` , '' , '  - angular' , '  - react' , '  - vue' ) ; } } ) ; type GenerateType = 'controller' | 'entity' | 'rest-api' | 'hook' | 'script' | 'service' | 'vscode-config' ; const generateTypes = [ 'controller' , 'entity' , 'rest-api' , 'hook' , 'script' , 'service' , 'vscode-config' ] ; program . command ( 'generate <type> [name]' ) . description ( 'Generate and/or modify files.' ) . option ( '-r, --register' , 'Register the controller into app.controller.ts (only available if type=controller|rest-api)' , false ) . option ( '-a, --auth' , 'Add an owner to the entities of the generated REST API (only available if type=rest-api)' , false ) . alias ( 'g' ) . addHelpText ( 'after' , `
Available types:
${ generateTypes . map ( t => `  - ${ t }` ) . join ( '\n' ) }
  ` ) . action ( async ( type , name , options ) => { if ( ! name && type !== 'vscode-config' ) { displayError ( `Argument "name" is required when creating a ${ type }. Please provide one.` ) ; return ; } try { switch ( type ) { case 'controller' : createController ( { name , register : options . register } ) ; break ; case 'entity' : createEntity ( { name } ) ; break ; case 'rest-api' : createRestApi ( { name , register : options . register , auth : options . auth } ) ; break ; case 'hook' : createHook ( { name } ) ; break ; case 'script' : createScript ( { name } ) ; break ; case 'service' : createService ( { name } ) ; break ; case 'vscode-config' : createVSCodeConfig ( ) ; break ; default : displayError ( `Unknown type ${ yellow ( type ) }. Please provide a valid one:` , '' , ... generateTypes . map ( t => `  - ${ t }` ) ) ; } } catch ( error ) { if ( error instanceof ClientError ) { displayError ( error . message ) ; return ; } throw error ; } } ) ; program . command ( 'rmdir <name>' ) . description ( 'Remove a directory and all its contents, including any subdirectories and files.' ) . action ( async ( name ) => { try { await rmdir ( name ) ; } catch ( error ) { if ( error . code === 'ENOTDIR' ) { displayError ( error . message ) ; return ; } throw error ; } } ) ; program . on ( 'command:*' , ( commands ) => { program . outputHelp ( ) ; displayError ( `Unknown command ${ yellow ( commands [ 0 ] ) }.` ) ; } ) ; program . parse ( process . argv ) ;