@@ -2,6 +2,7 @@ const fs = require('fs')
const path = require ( 'path' )
const chokidar = require ( 'chokidar' )
const assign _deep = require ( 'assign-deep' )
//const deepmerge = require('deepmerge')
// https://github.com/jonschlinkert/assign-deep // 类似 Object.assign 直接赋值到第一个对象里。只下载2个包。assign 优选。
// https://github.com/jonschlinkert/merge-deep // 生成一个新对象。会下载7~ 8个包。
@@ -11,10 +12,10 @@ const assign_deep = require('assign-deep')
const my = { envar : { } }
module . exports = {
start _watching ( { envarFiles = [ './envar-base-dynamic .js' , './envar-base-dynamic .gitignore.js' ] , rawEnvar = { } , interval = 1000 } = { } ) {
start _watching ( { envarFiles = [ './envar-config .js' , './envar-config .gitignore.js' ] , rawEnvar = { } , interval = 1000 } = { } ) {
chokidar . watch ( envarFiles , { interval } ) . on ( 'change' , ( onpath ) => {
// .on('all', (event, onpath)) 但这时, 即使server刚启动, 也会调用到这里一次
console . log ( 'envarTool.start_watching: envar file changed:' , onpath )
globalThis . wo ? . cc log? . ( 'envarTool.start_watching: envar file changed:' , onpath )
try {
// 或者调用 get_dynamic_envar。
delete require . cache [ require . resolve ( path . resolve ( onpath ) ) ]
@@ -23,9 +24,10 @@ module.exports = {
// 注意, assign_deep 会用 newEnvar 里的 undefined 属性覆盖掉 rawEnvar 里的原属性!所以要注意保持一致。(这和发送到前端的不一样,发送到前端的会被 JSON.stringify 以及 express 过滤掉 undefined.)
// 目前的解决方案里,已通过 base2app 参数来确保只在发送给前端时才设置 undefined, 但为防万一, 在这里通过 JSON.stringify 确保删除了 undefined
assign _deep ( rawEnvar , JSON . parse ( JSON . stringify ( newEnvar ) ) )
console . log ( ` envarTool.start_watching: OK reload ${ onpath } ` )
globalThis . wo ? . cc log? . ( ` envarTool.start_watching: OK reload ${ onpath } ` )
} catch ( expt ) {
console . log ( ` envarTool.start_watching: Fail reload ${ onpath } ` )
globalThis . wo ? . cc log? . ( ` envarTool.start_watching: Fail reload ${ onpath } ` )
globalThis . wo ? . ccerror ? . ( expt )
}
} )
} ,
@@ -36,26 +38,16 @@ module.exports = {
* - 字符串数组: 按顺序导入导入每个文件,后面文件里的变量覆盖前面的。
* - 对象: 直接添加到 rawEnvar 上。
*/
merge _envar ( {
rawEnvar = { } ,
envarFiles = [
'./envar-base-basic.js' ,
'./envar-base-basic.gitignore.js' ,
'./envar-base-dynamic.js' ,
'./envar-base-dynamic.gitignore.js' ,
'./envar-base-secret.js' ,
'./envar-base-secret.gitignore.js' ,
] ,
} = { } ) {
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : ` <<<<<<<< Configuring [ ${ process . env . NODE _ENV } ] Environment <<<<<<<< ` } , '\n,' )
merge _envar ( { rawEnvar = { } , envarFiles = [ './envar-config.js' , './envar-config.gitignore.js' ] } = { } ) {
globalThis . wo ? . ccinfo ? . ( { _from : 'merge_envar' , about : ` <<<<<<<< Configuring [ ${ process . env . NODE _ENV } ] Environment <<<<<<<< ` } )
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : '- Loading Configuration Files (读取配置文件)' } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'merge_envar' , about : '- Loading Configuration Files (读取配置文件)' } )
if ( typeof envarFiles === 'string' ) {
// 例如当输入参数为 envarFiles = 'envar-base .js' 里面应当 module.exports 一个数组
// 例如当输入参数为 envarFiles = 'envar-config .js' 里面应当 module.exports 一个数组
if ( fs . existsSync ( path . resolve ( envarFiles ) ) ) {
envarFiles = require ( path . resolve ( envarFiles ) )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : ` - ${ envarFiles } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'merge_envar' , about : ` - ${ envarFiles } is missing. ` } )
envarFiles = undefined
}
}
@@ -69,9 +61,9 @@ module.exports = {
} else if ( typeof fileContent === 'function' ) {
assign _deep ( rawEnvar , fileContent ( ) )
}
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : ` - ${ configFile } is loaded. ` } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'merge_envar' , about : ` - ${ configFile } is loaded. ` } )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : ` - ${ configFile } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'merge_envar' , about : ` - ${ configFile } is missing. ` } )
}
}
} else if ( typeof envarFiles === 'object' ) {
@@ -79,18 +71,18 @@ module.exports = {
} else if ( typeof envarFiles === 'function' ) {
assign _deep ( rawEnvar , envarFiles ( ) )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : ` - unrecognized envarFiles! ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'merge_envar' , about : ` - unrecognized envarFiles! ` } )
}
if ( process . argv . length > 2 && Array . isArray ( rawEnvar . commanderOptions ) ) {
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : '- Loading Command Line Parameters (载入命令行参数)' } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'merge_envar' , about : '- Loading Command Line Parameters (载入命令行参数)' } )
const commander = require ( 'commander' )
commander . version ( rawEnvar . Base _Version || '0.0.1' , '-v, --version' ) // 默认是 -V。如果要 -v, 就要加 '-v --version'
for ( let [ key , param , desc ] of rawEnvar . commanderOptions || [ ] ) {
commander . option ( param , ` ${ desc } Default = " ${ rawEnvar [ key ] } " ` )
}
commander . parse ( process . argv )
// console. log({_at:new Date().toJSON(),_from:'merge_envar', about: '- Merging Command Line Parameters into Configuration (把命令行参数值合并入配置)' },'\n,')
// globalThis.wo?.cc log?. ({_at:new Date().toJSON(),_from:'merge_envar', about: '- Merging Command Line Parameters into Configuration (把命令行参数值合并入配置)' },'\n,')
for ( let key in commander ) {
if ( ! /^_/ . test ( key ) && typeof commander [ key ] === 'string' ) {
// commander 自带了一批 _开头的属性, 过滤掉
@@ -100,14 +92,14 @@ module.exports = {
delete rawEnvar . commanderOptions
}
console . log ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar' , about : ` >>>>>>>> Configured [ ${ process . env . NODE _ENV } ] Environment >>>>>>>> ` } , '\n,' )
globalThis . wo ? . cclog ? . ( { _from : 'merge_envar' , about : ` >>>>>>>> Configured [ ${ process . env . NODE _ENV || 'development' } ] Environment >>>>>>>> ` } , '\n,' )
return rawEnvar
} ,
/* 读取动态配置文件中的环境变量。
*/
get _dynamic _envar ( { dynamicEnvarFiles = [ './envar-base-dynamic .js' , './envar-base-dynamic .gitignore.js' ] , base2app } = { } ) {
get _dynamic _envar ( { dynamicEnvarFiles = [ './envar-config .js' , './envar-config .gitignore.js' ] , base2app , _uipl , _clientInfo } = { } ) {
// config file should be absolute or relative to the node process's dir.
let dynamicEnvar = { }
@@ -117,7 +109,7 @@ module.exports = {
if ( fs . existsSync ( path . resolve ( dynamicEnvarFiles ) ) ) {
dynamicEnvarFiles = require ( path . resolve ( dynamicEnvarFiles ) )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'get_dynamic_envar' , about : ` - ${ dynamicEnvarFiles } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'get_dynamic_envar' , about : ` - ${ dynamicEnvarFiles } is missing. ` } )
dynamicEnvarFiles = undefined
}
}
@@ -130,11 +122,11 @@ module.exports = {
if ( typeof fileContent === 'object' ) {
assign _deep ( dynamicEnvar , fileContent )
} else if ( typeof fileContent === 'function' ) {
assign _deep ( dynamicEnvar , fileContent ( { base2app } ) )
assign _deep ( dynamicEnvar , fileContent ( { base2app , _uipl , _clientInfo } ) )
}
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'get_dynamic_envar' , about : ` - ${ dynamicFile } is parsed. ` } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'get_dynamic_envar' , about : ` - ${ dynamicFile } is parsed. ` } )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'get_dynamic_envar' , about : ` - ${ dynamicFile } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'get_dynamic_envar' , about : ` - ${ dynamicFile } is missing. ` } )
}
}
} else if ( typeof dynamicEnvarFiles === 'object' ) {
@@ -142,7 +134,7 @@ module.exports = {
} else if ( typeof dynamicEnvarFiles === 'function' ) {
dynamicEnvar = dynamicEnvarFiles ( )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'get_dynamic_envar' , about : ` - unrecognized dynamicEnvarFiles! ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'get_dynamic_envar' , about : ` - unrecognized dynamicEnvarFiles! ` } )
}
return dynamicEnvar
@@ -151,7 +143,7 @@ module.exports = {
/* 隐藏机密配置文件中的环境变量。
* 需要输出当前环境变量时,必须调用本函数,避免机密信息被输出。
*/
mask _secret _envar ( { rawEnvar , secretEnvarFiles = [ './envar-base- secret.js' , './envar-base- secret.gitignore.js' ] } = { } ) {
mask _secret _envar ( { rawEnvar , secretEnvarFiles = [ './envar-secret.js' , './envar-secret.gitignore.js' ] } = { } ) {
let envar = JSON . parse ( JSON . stringify ( rawEnvar ) ) // 复制一份,避免污染
let secretEnvar = { }
@@ -160,12 +152,12 @@ module.exports = {
if ( fs . existsSync ( path . resolve ( secretEnvarFiles ) ) ) {
secretEnvarFiles = require ( path . resolve ( secretEnvarFiles ) )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'mask_secret_envar' , about : ` - ${ secretEnvarFiles } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'mask_secret_envar' , about : ` - ${ secretEnvarFiles } is missing. ` } )
secretEnvarFiles = undefined
}
}
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'mask_secret_envar' , about : ` - Parsing secretEnvarFiles... ` } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'mask_secret_envar' , about : ` - Parsing secretEnvarFiles... ` } )
if ( Array . isArray ( secretEnvarFiles ) ) {
for ( let secretFile of secretEnvarFiles ) {
if ( fs . existsSync ( path . resolve ( secretFile ) ) ) {
@@ -175,9 +167,9 @@ module.exports = {
} else if ( typeof fileContent === 'function' ) {
assign _deep ( secretEnvar , fileContent ( ) )
}
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'mask_secret_envar' , about : ` - ${ secretFile } is parsed. ` } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'mask_secret_envar' , about : ` - ${ secretFile } is parsed. ` } )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'mask_secret_envar' , about : ` - ${ secretFile } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'mask_secret_envar' , about : ` - ${ secretFile } is missing. ` } )
}
}
} else if ( typeof secretEnvarFiles === 'object' ) {
@@ -185,7 +177,7 @@ module.exports = {
} else if ( typeof secretEnvarFiles === 'function' ) {
dynamicEnvar = secretEnvarFiles ( )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'mask_secret_envar' , about : ` - unrecognized secretEnvarFiles! ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'mask_secret_envar' , about : ` - unrecognized secretEnvarFiles! ` } )
}
for ( let key in secretEnvar ) {
@@ -196,26 +188,17 @@ module.exports = {
} ,
// 预制方法
envar _all ( {
files = [
'./envar-base-basic.js' ,
'./envar-base-basic.gitignore.js' ,
'./envar-base-dynamic.js' ,
'./envar-base-dynamic.gitignore.js' ,
'./envar-base-secret.js' ,
'./envar-base-secret.gitignore.js' ,
] ,
} = { } ) {
envar _all ( { files = [ './envar-config.js' , './envar-config.gitignore.js' , './envar-secret.js' , './envar-secret.gitignore.js' ] } = { } ) {
let envar = this . get _envar ( { inProcess : false , refresh : true , files } )
if ( process . argv . length > 2 && Array . isArray ( envar . commanderOptions ) ) {
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'envar_all' , about : '- Loading Command Line Parameters (载入命令行参数)' } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'envar_all' , about : '- Loading Command Line Parameters (载入命令行参数)' } )
const commander = require ( 'commander' )
commander . version ( envar . Base _Version || '0.0.1' , '-v, --version' ) // 默认是 -V。如果要 -v, 就要加 '-v --version'
for ( let [ key , param , desc ] of envar . commanderOptions || [ ] ) {
commander . option ( param , ` ${ desc } Default = " ${ envar [ key ] } " ` )
}
commander . parse ( process . argv )
// console. log({_at:new Date().toJSON(),_from:'envar_all', about: '- Merging Command Line Parameters into Configuration (把命令行参数值合并入配置)' },'\n,')
// globalThis.wo?.cc log?. ({_at:new Date().toJSON(),_from:'envar_all', about: '- Merging Command Line Parameters into Configuration (把命令行参数值合并入配置)' },'\n,')
for ( let key in commander ) {
if ( ! /^_/ . test ( key ) && typeof commander [ key ] === 'string' ) {
// commander 自带了一批 _开头的属性, 过滤掉
@@ -226,13 +209,13 @@ module.exports = {
}
return envar
} ,
envar _basic ( { envarKey , files = [ './envar-base-basic .js' , './envar-base-basic .gitignore.js' ] } = { } ) {
envar _basic ( { envarKey , files = [ './envar-config .js' , './envar-config .gitignore.js' ] } = { } ) {
return ( my [ 'basic' ] = this . get _envar ( { envarKey , inProcess : false , inCache : true , cachename : 'basic' , refresh : false , files } ) )
} ,
envar _dynamic ( { envarKey , files = [ './envar-base-dynamic .js' , './envar-base-dynamic .gitignore.js' ] } = { } ) {
envar _dynamic ( { envarKey , files = [ './envar-config .js' , './envar-config .gitignore.js' ] } = { } ) {
return this . get _envar ( { envarKey , inProcess : true , inCache : false , refresh : true , files } )
} ,
envar _sesame ( { envarKey , files = [ './envar-base- secret.js' , './envar-base- secret.gitignore.js' ] } = { } ) {
envar _sesame ( { envarKey , files = [ './envar-secret.js' , './envar-secret.gitignore.js' ] } = { } ) {
return ( my [ 'sesame' ] = this . get _envar ( { envarKey , inProcess : true , inCache : true , cachename : 'sesame' , refresh : false , files } ) )
} ,
// 可定制的通用方法
@@ -253,7 +236,7 @@ module.exports = {
if ( fs . existsSync ( path . resolve ( files ) ) ) {
files = require ( path . resolve ( files ) )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar_files' , about : ` - ${ files } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'merge_envar_files' , about : ` - ${ files } is missing. ` } )
files = undefined
}
}
@@ -265,15 +248,15 @@ module.exports = {
delete require . cache [ require . resolve ( path . resolve ( envarFile ) ) ] // delete require.cache[fullpath] 不起作用,必须要加 require.resolve
}
assign _deep ( envar , require ( path . resolve ( envarFile ) ) )
console . info ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar_files' , about : ` - ${ envarFile } is parsed. ` } , '\n,' )
globalThis . wo ? . ccinfo ? . ( { _from : 'merge_envar_files' , about : ` - ${ envarFile } is parsed. ` } )
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar_files' , about : ` - ${ envarFile } is missing. ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'merge_envar_files' , about : ` - ${ envarFile } is missing. ` } )
}
}
} else if ( typeof files === 'object' ) {
envar = files
} else {
console . warn ( { _at : new Date ( ) . toJSON ( ) , _from : 'merge_envar_files' , about : ` - unrecognized files! ` } , '\n,' )
globalThis . wo ? . ccwarn ? . ( { _from : 'merge_envar_files' , about : ` - unrecognized files! ` } )
}
return envar