@@ -4,58 +4,59 @@ const pkgName = 'generate-ip',
44 copyright = '© 2024–2025 Adam Lui & contributors under the MIT license.' ,
55 cmdFormat = 'generate-[ip|ipv6|mac] [options|commands]' ,
66 srcURL = 'https://code.generate-ip.org' ,
7- docURL = 'https://docs.generate-ip.org/#-command-line-usage' ;
7+ docURL = 'https://docs.generate-ip.org/#-command-line-usage'
88
99( async ( ) => {
1010
1111 // Import LIBS
1212 const { ipv4, ipv6, mac } = require ( __dirname . match ( / s r c / ) ? './generate-ip' : './generate-ip.min' ) ,
1313 fs = require ( 'fs' ) , path = require ( 'path' ) ,
14- { execSync } = require ( 'child_process' ) ; // for --version cmd + cross-platform copying
14+ { execSync } = require ( 'child_process' ) // for --version cmd + cross-platform copying
1515
1616 // Init UI COLORS
1717 const nc = '\x1b[0m' , // no color
1818 br = '\x1b[1;91m' , // bright red
1919 by = '\x1b[1;33m' , // bright yellow
2020 bg = '\x1b[1;92m' , // bright green
21- bw = '\x1b[1;97m' ; // bright white
21+ bw = '\x1b[1;97m' // bright white
2222
2323 // Load sys LANGUAGE
24- let langCode = 'en' ;
24+ let langCode = 'en'
2525 if ( process . platform == 'win32' ) {
26- try { langCode = execSync ( '(Get-Culture).TwoLetterISOLanguageName' , { shell : 'powershell' , encoding : 'utf-8' } ) . trim ( ) ; }
26+ try { langCode = execSync ( '(Get-Culture).TwoLetterISOLanguageName' , { shell : 'powershell' , encoding : 'utf-8' } ) . trim ( ) }
2727 catch ( err ) { }
2828 } else { // macOS/Linux
29- const env = process . env ;
30- langCode = ( env . LANG || env . LANGUAGE || env . LC_ALL || env . LC_MESSAGES || env . LC_NAME || 'en' ) ?. split ( '.' ) [ 0 ] ;
29+ const env = process . env
30+ langCode = ( env . LANG || env . LANGUAGE || env . LC_ALL || env . LC_MESSAGES || env . LC_NAME || 'en' ) ?. split ( '.' ) [ 0 ]
3131 }
3232
3333 // Define MESSAGES
34- let msgs = { } ;
34+ let msgs = { }
3535 const msgsLoaded = new Promise ( ( resolve , reject ) => {
3636 const msgHostURL = 'https://cdn.jsdelivr.net/gh/adamlui/js-utils/generate-ip/_locales/' ,
37- msgLocaleDir = ( langCode ? langCode . replace ( '-' , '_' ) : 'en' ) + '/' ;
38- let msgHref = msgHostURL + msgLocaleDir + 'messages.json' , msgFetchTries = 0 ;
39- fetchData ( msgHref ) . then ( onLoad ) . catch ( reject ) ;
37+ msgLocaleDir = ( langCode ? langCode . replace ( '-' , '_' ) : 'en' ) + '/'
38+ let msgHref = msgHostURL + msgLocaleDir + 'messages.json' , msgFetchTries = 0
39+ fetchData ( msgHref ) . then ( onLoad ) . catch ( reject )
4040 async function onLoad ( resp ) {
4141 try { // to return localized messages.json
42- const msgs = await resp . json ( ) , flatMsgs = { } ;
42+ const msgs = await resp . json ( ) , flatMsgs = { }
4343 for ( const key in msgs ) // remove need to ref nested keys
4444 if ( typeof msgs [ key ] == 'object' && 'message' in msgs [ key ] )
45- flatMsgs [ key ] = msgs [ key ] . message ;
46- resolve ( flatMsgs ) ;
45+ flatMsgs [ key ] = msgs [ key ] . message
46+ resolve ( flatMsgs )
4747 } catch ( err ) { // if bad response
48- msgFetchTries ++ ; if ( msgFetchTries == 3 ) return resolve ( { } ) ; // try up to 3X (original/region-stripped/EN) only
48+ msgFetchTries ++ ; if ( msgFetchTries == 3 ) return resolve ( { } ) // try up to 3X (original/region-stripped/EN) only
4949 msgHref = langCode . includes ( '-' ) && msgFetchTries == 1 ? // if regional lang on 1st try...
5050 msgHref . replace ( / ( [ ^ _ ] * ) _ [ ^ / ] * ( \/ .* ) / , '$1$2' ) // ...strip region before retrying
51- : ( msgHostURL + 'en/messages.json' ) ; // else use default English messages
52- fetchData ( msgHref ) . then ( onLoad ) . catch ( reject ) ;
51+ : ( msgHostURL + 'en/messages.json' ) // else use default English messages
52+ fetchData ( msgHref ) . then ( onLoad ) . catch ( reject )
5353 }
5454 }
55- } ) ; try { msgs = await msgsLoaded ; } catch ( err ) { }
55+ } )
56+ try { msgs = await msgsLoaded } catch ( err ) { }
5657
5758 // Load SETTINGS from args
58- const config = { } ;
59+ const config = { }
5960 const reArgs = {
6061 paramOptions : { 'qty' : / ^ - - ? q u ? a ? n ? t i ? t ? y (?: = .* | $ ) / } ,
6162 flags : {
@@ -64,81 +65,82 @@ const pkgName = 'generate-ip',
6465 'quietMode' : / ^ - - ? q (?: u i e t ) ? (?: - ? m o d e ) ? $ /
6566 } ,
6667 infoCmds : { 'help' : / ^ - - ? h (?: e l p ) ? $ / , 'version' : / ^ - - ? v e ? r ? s ? i ? o ? n ? $ / }
67- } ;
68+ }
6869 process . argv . forEach ( arg => {
69- if ( ! arg . startsWith ( '-' ) ) return ;
70+ if ( ! arg . startsWith ( '-' ) ) return
7071 const matchedParamOption = Object . keys ( reArgs . paramOptions )
7172 . find ( option => reArgs . paramOptions [ option ] . test ( arg ) )
7273 const matchedFlag = Object . keys ( reArgs . flags ) . find ( flag => reArgs . flags [ flag ] . test ( arg ) )
73- const matchedInfoCmd = Object . keys ( reArgs . infoCmds ) . find ( cmd => reArgs . infoCmds [ cmd ] . test ( arg ) ) ;
74- if ( matchedFlag ) config [ matchedFlag ] = true ;
74+ const matchedInfoCmd = Object . keys ( reArgs . infoCmds ) . find ( cmd => reArgs . infoCmds [ cmd ] . test ( arg ) )
75+ if ( matchedFlag ) config [ matchedFlag ] = true
7576 else if ( matchedParamOption ) {
7677 if ( ! / = .+ / . test ( arg ) ) {
7778 console . error ( `\n${ br + ( msgs . prefix_error || 'ERROR' ) } : `
7879 + `Arg [--${ arg . replace ( / - / g, '' ) } ] `
79- + `${ msgs . error_noEqual || 'requires \'=\' followed by a value' } .${ nc } ` ) ;
80- printHelpCmdAndDocURL ( ) ; process . exit ( 1 ) ;
80+ + `${ msgs . error_noEqual || 'requires \'=\' followed by a value' } .${ nc } ` )
81+ printHelpCmdAndDocURL ( ) ; process . exit ( 1 )
8182 }
82- const value = arg . split ( '=' ) [ 1 ] ;
83- config [ matchedParamOption ] = parseInt ( value ) || value ;
83+ const value = arg . split ( '=' ) [ 1 ]
84+ config [ matchedParamOption ] = parseInt ( value ) || value
8485 } else if ( ! matchedInfoCmd && ! / i p v 4 / . test ( arg ) ) {
8586 console . error ( `\n${ br + ( msgs . prefix_error || 'ERROR' ) } : `
86- + `Arg [${ arg } ] ${ msgs . error_notRecognized || 'not recognized' } .${ nc } ` ) ;
87- console . info ( `\n${ by + ( msgs . info_validArgs || 'Valid arguments are below' ) } .${ nc } ` ) ;
88- printHelpSections ( [ 'paramOptions' , 'flags' , 'infoCmds' ] ) ;
89- process . exit ( 1 ) ;
90- } } ) ;
87+ + `Arg [${ arg } ] ${ msgs . error_notRecognized || 'not recognized' } .${ nc } ` )
88+ console . info ( `\n${ by + ( msgs . info_validArgs || 'Valid arguments are below' ) } .${ nc } ` )
89+ printHelpSections ( [ 'paramOptions' , 'flags' , 'infoCmds' ] )
90+ process . exit ( 1 )
91+ } } )
9192 if ( config . qty && ( isNaN ( config . qty ) || config . qty < 1 ) ) {
9293 console . error ( `\n${ br + ( msgs . prefix_error || 'ERROR' ) } : [qty] `
93- + `${ msgs . error_nonPositiveNum || 'argument can only be > 0' } .${ nc } ` ) ;
94- printHelpCmdAndDocURL ( ) ; process . exit ( 1 ) ;
94+ + `${ msgs . error_nonPositiveNum || 'argument can only be > 0' } .${ nc } ` )
95+ printHelpCmdAndDocURL ( ) ; process . exit ( 1 )
9596 }
9697
9798 // Show HELP screen if -h or --help passed
98- if ( process . argv . some ( arg => reArgs . infoCmds . help . test ( arg ) ) ) printHelpSections ( ) ;
99+ if ( process . argv . some ( arg => reArgs . infoCmds . help . test ( arg ) ) ) printHelpSections ( )
99100
100101 // Show VERSION number if -v or --version passed
101102 else if ( process . argv . some ( arg => reArgs . infoCmds . version . test ( arg ) ) ) {
102- const globalVer = execSync ( `npm view ${ pkgName } version` ) . toString ( ) . trim ( ) || 'none' ;
103- let localVer , currentDir = process . cwd ( ) ;
103+ const globalVer = execSync ( `npm view ${ pkgName } version` ) . toString ( ) . trim ( ) || 'none'
104+ let localVer , currentDir = process . cwd ( )
104105 while ( currentDir != '/' ) {
105- const localManifestPath = path . join ( currentDir , 'package.json' ) ;
106+ const localManifestPath = path . join ( currentDir , 'package.json' )
106107 if ( fs . existsSync ( localManifestPath ) ) {
107- const localManifest = require ( localManifestPath ) ;
108+ const localManifest = require ( localManifestPath )
108109 localVer = ( localManifest . dependencies ?. [ pkgName ]
109110 || localManifest . devDependencies ?. [ pkgName ]
110- ) ?. match ( / ( \d + \. \d + \. \d + ) / ) [ 0 ] || 'none' ;
111- break ;
111+ ) ?. match ( / ( \d + \. \d + \. \d + ) / ) [ 0 ] || 'none'
112+ break
112113 }
113- currentDir = path . dirname ( currentDir ) ;
114+ currentDir = path . dirname ( currentDir )
114115 }
115- console . info ( `\n${ msgs . prefix_globalVer || 'Global version' } : ${ globalVer } ` ) ;
116- console . info ( `${ msgs . prefix_localVer || 'Local version' } : ${ localVer } ` ) ;
116+ console . info ( `\n${ msgs . prefix_globalVer || 'Global version' } : ${ globalVer } ` )
117+ console . info ( `${ msgs . prefix_localVer || 'Local version' } : ${ localVer } ` )
117118
118119 } else { // log/copy RESULT(S)
119120 const genOptions = { qty : config . qty || 1 , verbose : ! config . quietMode } ,
120121 ipResult = config . ipv6mode ? ipv6 . generate ( genOptions )
121122 : config . macMode ? mac . generate ( genOptions )
122- : ipv4 . generate ( genOptions ) ;
123- printIfNotQuiet ( `\n${ msgs . info_copying || 'Copying to clipboard' } ...` ) ;
124- copyToClipboard ( Array . isArray ( ipResult ) ? ipResult . join ( '\n' ) : ipResult ) ;
123+ : ipv4 . generate ( genOptions )
124+ printIfNotQuiet ( `\n${ msgs . info_copying || 'Copying to clipboard' } ...` )
125+ copyToClipboard ( Array . isArray ( ipResult ) ? ipResult . join ( '\n' ) : ipResult )
125126 }
126127
127128 // Define FUNCTIONS
128129
129130 function fetchData ( url ) { // instead of fetch() to support Node.js < v21
130131 return new Promise ( ( resolve , reject ) => {
131- const protocol = url . match ( / ^ ( [ ^ : ] + ) : \/ \/ / ) [ 1 ] ;
132- if ( ! / ^ h t t p s ? $ / . test ( protocol ) ) reject ( new Error ( `${ msgs . error_invalidURL || 'Invalid URL' } .` ) ) ;
132+ const protocol = url . match ( / ^ ( [ ^ : ] + ) : \/ \/ / ) [ 1 ]
133+ if ( ! / ^ h t t p s ? $ / . test ( protocol ) ) reject ( new Error ( `${ msgs . error_invalidURL || 'Invalid URL' } .` ) )
133134 require ( protocol ) . get ( url , resp => {
134- let rawData = '' ;
135- resp . on ( 'data' , chunk => rawData += chunk ) ;
136- resp . on ( 'end' , ( ) => resolve ( { json : ( ) => JSON . parse ( rawData ) } ) ) ;
137- } ) . on ( 'error' , reject ) ;
138- } ) ; }
135+ let rawData = ''
136+ resp . on ( 'data' , chunk => rawData += chunk )
137+ resp . on ( 'end' , ( ) => resolve ( { json : ( ) => JSON . parse ( rawData ) } ) )
138+ } ) . on ( 'error' , reject )
139+ } )
140+ }
139141
140142 function printHelpSections ( includeSections = [ 'header' , 'usage' , 'paramOptions' , 'flags' , 'infoCmds' ] ) {
141- const appPrefix = `\x1b[106m\x1b[30m ${ pkgName } ${ nc } ` ; // bright teal bg + black fg
143+ const appPrefix = `\x1b[106m\x1b[30m ${ pkgName } ${ nc } ` // bright teal bg + black fg
142144 const helpSections = {
143145 'header' : [
144146 '\n├ ' + appPrefix + ( msgs . appCopyright || copyright ) ,
@@ -163,51 +165,52 @@ const pkgName = 'generate-ip',
163165 ` -h, --help ${ msgs . optionDesc_help || 'Display help screen.' } ` ,
164166 ` -v, --version ${ msgs . optionDesc_version || 'Show version number' } .`
165167 ]
166- } ;
167- includeSections . forEach ( section => { // print valid arg elems
168- helpSections [ section ] ?. forEach ( line => printHelpMsg ( line , / h e a d e r | u s a g e / . test ( section ) ? 1 : 29 ) ) ; } ) ;
169- console . info ( `\n${ msgs . info_moreHelp || 'For more help' } , ${ msgs . info_visit || 'visit' } : ${ bw + docURL + nc } ` ) ;
168+ }
169+ includeSections . forEach ( section => // print valid arg elems
170+ helpSections [ section ] ?. forEach ( line => printHelpMsg ( line , / h e a d e r | u s a g e / . test ( section ) ? 1 : 29 ) ) )
171+ console . info ( `\n${ msgs . info_moreHelp || 'For more help' } , ${ msgs . info_visit || 'visit' } : ${ bw + docURL + nc } ` )
170172
171173 function printHelpMsg ( msg , indent ) { // wrap msg + indent 2nd+ lines
172174 const terminalWidth = process . stdout . columns || 80 ,
173175 lines = [ ] , words = msg . match ( / \S + | \s + / g) ,
174- prefix = '| ' ;
176+ prefix = '| '
175177
176178 // Split msg into lines of appropriate lengths
177- let currentLine = '' ;
179+ let currentLine = ''
178180 words . forEach ( word => {
179- const lineLength = terminalWidth - ( ! lines . length ? 0 : indent ) ;
181+ const lineLength = terminalWidth - ( ! lines . length ? 0 : indent )
180182 if ( currentLine . length + prefix . length + word . length > lineLength ) { // cap/store it
181- lines . push ( ! lines . length ? currentLine : currentLine . trimStart ( ) ) ;
182- currentLine = '' ;
183+ lines . push ( ! lines . length ? currentLine : currentLine . trimStart ( ) )
184+ currentLine = ''
183185 }
184- currentLine += word ;
185- } ) ;
186- lines . push ( ! lines . length ? currentLine : currentLine . trimStart ( ) ) ;
186+ currentLine += word
187+ } )
188+ lines . push ( ! lines . length ? currentLine : currentLine . trimStart ( ) )
187189
188190 // Print formatted msg
189191 lines . forEach ( ( line , idx ) => console . info ( prefix + (
190192 idx == 0 ? line // print 1st line unindented
191193 : ' ' . repeat ( indent ) + line // print subsequent lines indented
192- ) ) ) ;
194+ ) ) )
193195 }
194196 }
195197
196198 function printHelpCmdAndDocURL ( ) {
197199 console . info ( `\n${ msgs . info_moreHelp || 'For more help' } ,`
198200 + ` ${ msgs . info_type || 'type' } 'generate-ip --help'`
199201 + ` ${ msgs . info_or || 'or' } ${ msgs . info_visit || 'visit' } \n${ bw + docURL + nc } `
200- ) ; }
202+ )
203+ }
201204
202- function printIfNotQuiet ( msg ) { if ( ! config . quietMode ) console . info ( msg ) ; }
205+ function printIfNotQuiet ( msg ) { if ( ! config . quietMode ) console . info ( msg ) }
203206
204207 function copyToClipboard ( data ) {
205208 if ( process . platform == 'darwin' ) // macOS
206- execSync ( `printf "${ data } " | pbcopy` ) ;
209+ execSync ( `printf "${ data } " | pbcopy` )
207210 else if ( process . platform == 'linux' )
208- execSync ( `printf "${ data } " | xclip -selection clipboard` ) ;
211+ execSync ( `printf "${ data } " | xclip -selection clipboard` )
209212 else if ( process . platform == 'win32' )
210- execSync ( `Set-Clipboard -Value "${ data } "` , { shell : 'powershell' } ) ;
213+ execSync ( `Set-Clipboard -Value "${ data } "` , { shell : 'powershell' } )
211214 }
212215
213- } ) ( ) ;
216+ } ) ( )
0 commit comments