1
1
import path from "path" ;
2
+ import fs from "fs-extra"
2
3
import { Command } from "commander" ;
3
4
import logger from "./utils/logger" ;
4
5
import Invoice from "./utils/invoice" ;
5
6
import minimist from "minimist"
6
- import { initConfig , openConfigDirectory , openConfigurationFile , openInvoicesDirectory } from "./utils" ;
7
+ import { getConfig , getInvoiceDirectory , getVersion , openConfigDirectory , openConfigurationFile , openInvoicesDirectory , timeout } from "./utils" ;
7
8
import * as os from "os"
8
9
import inquirer from "inquirer" ;
9
-
10
- const args = minimist ( process . argv . slice ( 2 ) )
11
- const isDebug = args . debug || false
12
-
13
- logger . setDebugMode ( isDebug )
14
-
15
- const program = new Command ( ) ;
10
+ import type { Config } from "./types/types" ;
16
11
17
12
export const DEFAULT_DIR = path . join ( os . homedir ( ) , ".config" , "icli/" ) ;
18
13
export const DEFAULT_INVOICES_DIR = path . join ( os . homedir ( ) , "Documents" , "Invoices/" )
19
14
export const DEFAULT_PATH = path . join ( os . homedir ( ) , ".config" , "icli/icli.json" ) ;
20
15
export const INVOICE_PATH = path . join ( path . dirname ( DEFAULT_PATH ) , "invoices.json" ) ;
21
16
17
+
18
+ async function init ( ) {
19
+
20
+ const configExists = fs . existsSync ( DEFAULT_PATH )
21
+
22
+ const version = await getVersion ( )
23
+
24
+ if ( ! configExists ) {
25
+ const config : Partial < Config > = {
26
+ appName : "Invoice CLI Tool" ,
27
+ createdAt : new Date ( ) . toISOString ( ) ,
28
+ version
29
+ }
30
+
31
+ try {
32
+ fs . ensureFileSync ( DEFAULT_PATH )
33
+ fs . writeJsonSync ( DEFAULT_PATH , config , { spaces : 2 } )
34
+ logger . debug ( ) . info ( `Setup the config with no defaults` )
35
+ } catch ( e ) {
36
+ logger . debug ( ) . error ( `${ e } ` )
37
+ logger . error ( 'An error occured.' )
38
+ }
39
+ } else {
40
+ const config = getConfig ( )
41
+ if ( config . version !== version && version !== "Unknown" ) logger . warn ( `The version you are running is outdated. Please upgrade.` )
42
+ }
43
+
44
+ await getInvoiceDirectory ( )
45
+ const config = getConfig ( )
46
+
47
+ await timeout ( 200 )
48
+
49
+ let unset = [ ]
50
+ for ( const defaultOption of Object . keys ( Invoice . defaultOptionPrompts ) ) {
51
+ if ( config ?. default_values ?. [ defaultOption as keyof typeof config . default_values ] ) continue
52
+
53
+ unset . push ( defaultOption . toLowerCase ( ) )
54
+ }
55
+
56
+ if ( unset . length ) {
57
+ await Invoice . setupDefaultValues ( unset )
58
+ }
59
+ }
60
+
61
+
22
62
export async function mainMenu ( ) {
23
63
const choices = await inquirer . prompt ( [
24
64
{
@@ -31,10 +71,10 @@ export async function mainMenu() {
31
71
32
72
switch ( choices . action ) {
33
73
case "View Invoice History" :
34
- new Invoice ( ) . viewHistory ( ) ;
74
+ Invoice . viewHistory ( ) ;
35
75
break ;
36
76
case "Create a New Invoice" :
37
- await new Invoice ( ) . createInvoice ( )
77
+ await Invoice . createInvoice ( )
38
78
break ;
39
79
case "Exit CLI" :
40
80
logger . info ( "Exiting CLI..." ) ;
@@ -44,85 +84,78 @@ export async function mainMenu() {
44
84
mainMenu ( ) ;
45
85
}
46
86
87
+ const args = minimist ( process . argv . slice ( 2 ) )
88
+ const isDebug = args . debug || false
89
+
90
+ logger . setDebugMode ( isDebug )
91
+
92
+ const program = new Command ( ) ;
93
+
47
94
48
- const commands = [
49
- {
50
- name : "setup" ,
51
- description : "Setup configuration file" ,
52
- action : async ( ) => {
53
- await initConfig ( ) ;
54
- await mainMenu ( ) ;
55
- }
56
- } ,
57
- {
58
- name : "history" ,
59
- description : "View invoice history" ,
60
- action : async ( ) => {
61
- new Invoice ( ) . viewHistory ( )
62
- await mainMenu ( )
63
- }
64
- } ,
65
- {
66
- name : "create" ,
67
- description : "Create a new invoice" ,
68
- action : async ( ) => {
69
- await new Invoice ( ) . createInvoice ( args . explicit ? false : true )
70
- await mainMenu ( )
71
- } ,
72
- option : [ {
73
- value : 'explicit' ,
74
- description : "Explicitly select the values for your personal details"
75
- } ]
76
- } ,
77
- {
78
- name : "config" ,
79
- description : "Open the configuration file" ,
80
- action : openConfigurationFile
81
- } ,
82
- {
83
- name : "cd" ,
84
- description : "Open the configuration directory" ,
85
- action : openConfigDirectory
86
- } ,
87
- {
88
- name : "invoices" ,
89
- description : "Open the configuration directory" ,
90
- action : openInvoicesDirectory
91
- } ,
92
- {
93
- name : "defaults" ,
94
- description : "Setup your default details for creating invoices." ,
95
- // options: [Object.keys(Invoice.prototype.defaultOptionPrompts).map(k => ({value: k, description: `Change default value for: ${k}`}))],
96
- options :
97
- Object . keys ( new Invoice ( ) . defaultOptionPrompts )
98
- . map ( o => ( { value : o . toLowerCase ( ) , description : `Change default for: ${ o } ` } ) ) ,
99
- action : async ( ) => {
100
- await new Invoice ( ) . setupDefaultValues ( Array . from ( new Set ( Object . keys ( args ) . filter ( o => o !== "_" && o !== "debug" ) ) ) )
101
- } ,
102
- } ,
103
- {
104
- name : "exit" ,
105
- description : "Exit the CLI tool" ,
106
- action : ( ) => {
107
- logger . info ( 'Exiting CLI...' )
108
- process . exit ( 0 )
109
- }
110
- } ,
111
- ]
112
95
program
113
96
. version ( "1.0.0" )
114
97
. description ( "Invoice CLI Tool" )
115
98
. option ( '--debug' , "Display external logs" )
116
99
117
- commands . forEach ( ( c ) => {
118
- const cmd = program
119
- . command ( c . name )
120
- . description ( c . description )
121
- . action ( c . action )
100
+ program
101
+ . command ( 'history' )
102
+ . description ( 'View invoice history' )
103
+ . action ( async ( ) => {
104
+ Invoice . viewHistory ( )
105
+ await mainMenu ( )
106
+ } )
107
+
108
+ program
109
+ . command ( 'create' )
110
+ . description ( 'Create a new invoice' )
111
+ . option ( '--explicit' )
112
+ . action ( async ( ) => {
113
+ await Invoice . createInvoice ( args . explicit ? false : true )
114
+ await mainMenu ( )
115
+ } )
116
+
117
+ program
118
+ . command ( 'config' )
119
+ . description ( 'Open the configuration file' )
120
+ . action ( openConfigurationFile )
121
+
122
+ program
123
+ . command ( 'cd' )
124
+ . description ( 'Open the configuration directory' )
125
+ . action ( openConfigDirectory )
126
+
127
+ program
128
+ . command ( 'invoices' )
129
+ . description ( 'Open the invoices directory' )
130
+ . action ( openInvoicesDirectory )
131
+
132
+ program
133
+ . command ( 'defaults' )
134
+ . description ( 'Setup the default details for creating new invoices' )
135
+ . action ( async ( ) => await Invoice . setupDefaultValues ( args ? Array . from ( new Set ( Object . keys ( args ) . filter ( o => o !== "_" && o !== 'debug' ) ) ) : undefined ) )
136
+ . option ( '--fullname' )
137
+ . option ( '--sortcode' )
138
+ . option ( '--banknum' )
139
+ . option ( '--address' )
140
+ . option ( '--postcode' )
141
+ . option ( '--email' )
142
+ . option ( '--logo' )
122
143
123
- c . options ?. forEach ( c => {
124
- cmd . option ( `--${ c . value } ` , c . description )
144
+ program
145
+ . command ( 'exit' )
146
+ . description ( 'Exit the Invoice CLI tool' )
147
+ . action ( ( ) => {
148
+ process . exit ( 0 )
125
149
} )
150
+
151
+
152
+
153
+ init ( ) . then ( ( ) => {
154
+ program . parse ( process . argv ) ;
155
+
156
+ if ( ! process . argv . slice ( 2 ) . length ) {
157
+ program . outputHelp ( )
158
+ process . exit ( 0 )
159
+ }
126
160
} )
127
161
128
- program . parse ( process . argv ) ;
0 commit comments