CLI arguments will now be considered user requests to modify configuration, exactly as it was done via the Admin panel
Massimo Melina committed
Apr 10, 2022 at 14:47 UTC
d515e49b3c7d8dd6f042d45a317a58287d98fcd5
3 files changed
+15
-7
server/src/config.ts
+12
-7
@@ -5,7 +5,7 @@ import { argv } from './const'
5
import { watchLoad } from './watchLoad'
6
import yaml from 'yaml'
7
import _ from 'lodash'
8
-import { debounceAsync, objSameKeys, onOff } from './misc'
8
+import { debounceAsync, objSameKeys, onOff, wait } from './misc'
9
import { exists } from 'fs'
10
import { promisify } from 'util'
11
@@ -20,7 +20,7 @@ let state: Record<string, any> = {}
20
const cfgEvents = new EventEmitter()
21
cfgEvents.setMaxListeners(10_000)
22
const path = argv.config || process.env.HFS_CONFIG || PATH
23
-const { save } = watchLoad(path, values => setConfig(values||{}, false), {
23
+const { save } = watchLoad(path, values => setConfig(values||{}, false), {
24
failedOnFirstAttempt(){
25
console.log("No config file, using defaults")
26
setTimeout(() => // for consistency with asynchronous success callback (without this http server is started before the koa app is ready)
@@ -37,7 +37,6 @@ export function defineConfig<T>(k: string, definition: Partial<ConfigProps<T>>)
37
const { caster = _.identity } = definition
38
configProps[k] = {
39
caster,
40
- arg: caster(argv[k]),
40
...definition,
41
defaultValue: _.cloneDeep(definition.defaultValue),
42
}
@@ -46,9 +45,7 @@ export function defineConfig<T>(k: string, definition: Partial<ConfigProps<T>>)
45
export function subscribeConfig<T>({ k, ...definition }:{ k:string } & Partial<ConfigProps<T>>, cb:(v:T, was?:T)=>void) {
46
if (definition)
47
defineConfig(k, definition)
49
- const { defaultValue, arg } = configProps[k] ?? {}
50
- if (arg !== undefined) // it was passed at command line, and it will never change
51
- return cb(arg)
48
+ const { defaultValue } = configProps[k] ?? {}
49
const eventName = 'new.'+k
50
if (started) {
51
let v = state[k]
@@ -68,7 +65,6 @@ export function getWholeConfig({ omit=[], only=[] }: { omit:string[], only:strin
65
let copy = Object.assign(
66
objSameKeys(configProps, x => x.defaultValue),
67
state,
71
- _.pickBy(objSameKeys(configProps, x => x.arg), x => x !== undefined),
68
)
69
copy = _.omit(copy, omit)
70
if (only.length)
@@ -78,6 +74,13 @@ export function getWholeConfig({ omit=[], only=[] }: { omit:string[], only:strin
74
75
// pass a value to `save` to force saving decision, or leave undefined for auto. Passing false will also reset previously loaded configs.
76
export function setConfig(newCfg: Record<string,any>, save?: boolean) {
77
+ if (!started) { // first time we consider also CLI args
78
+ const argCfg = _.pickBy(objSameKeys(configProps, (x,k) => argv[k]), x => x !== undefined)
79
+ if (! _.isEmpty(argCfg)) {
80
+ saveConfigAsap().then() // don't set `save` argument, as it would interfere below at check `save===false`
81
+ Object.assign(newCfg, argCfg)
82
+ }
83
+ }
84
for (const k in newCfg)
85
check(k)
86
if (save) {
@@ -118,6 +121,8 @@ export function setConfig(newCfg: Record<string,any>, save?: boolean) {
121
}
122
123
export const saveConfigAsap = debounceAsync(async () => {
124
+ while (!started)
125
+ await wait(100)
126
let txt = yaml.stringify(state, { lineWidth:1000 })
127
if (txt.trim() === '{}') // most users wouldn't understand
128
if (await promisify(exists)(path)) // if a file exists then empty it, else don't bother creating it
server/src/listen.ts
+2
@@ -58,6 +58,8 @@ async function considerHttps() {
58
stopServer(httpsSrv).then()
59
let port = getConfig('https_port')
60
try {
61
+ while (!app)
62
+ await wait(100)
63
httpsSrv = Object.assign(
64
https.createServer(port < 0 ? {} : { key: httpsNeeds.private_key, cert: httpsNeeds.cert }, app.callback()),
65
{ name: 'https' }
todo.md
+1
@@ -1,4 +1,5 @@
1
# To do
2
+- custom text to display on the frontend
3
- log exceptions
4
- watch certificates for change
5
- admin/fs: render virtual folders differently