pass defaults to admin/config

Massimo Melina committed Feb 10, 2022 at 10:29 UTC bc2d712d8c1dedc50c199fefac41c4c74636fb52
4 files changed +25 -10
src/config.ts
+13 -5
@@ -4,7 +4,7 @@ import { watchLoad } from './watchLoad'
4 import fs from 'fs/promises'
5 import yaml from 'yaml'
6 import _ from 'lodash'
7 -import { onOffMap } from './misc'
7 +import { objSameKeys, onOffMap } from './misc'
8
9 export const CFG_ALLOW_CLEAR_TEXT_LOGIN = 'allow_clear_text_login'
10
@@ -59,7 +59,8 @@ export function getConfig(k:string) {
59 }
60
61 export function getWholeConfig({ omit=[], only=[] }: { omit:string[], only:string[] }) {
62 - let copy = _.omit(state, omit)
62 + let copy = Object.assign( objSameKeys(configProps, x => x.defaultValue), state )
63 + copy = _.omit(copy, omit)
64 if (only.length)
65 copy = _.pick(copy, only)
66 return _.cloneDeep(copy)
@@ -84,14 +85,21 @@ export function setConfig(newCfg: Record<string,any>, partial=false) {
85 let v = newV === undefined ? defaultValue : newV
86 if (caster)
87 v = caster(v)
87 - if (JSON.stringify(v) === JSON.stringify(oldV)) return
88 - state[k] = v
88 + const j = JSON.stringify(v)
89 + if (j === JSON.stringify(oldV)) return // no change
90 + if (j === JSON.stringify(defaultValue)) // if we move away from the default value and then come back, we restore the initial state (undefined)
91 + delete state[k]
92 + else
93 + state[k] = v
94 emitter.emit('new.'+k, v, oldV)
95 }
96 }
97
98 export const saveConfigAsap = _.debounce(async () => {
94 - fs.writeFile(path, yaml.stringify(state))
99 + let txt = yaml.stringify(state)
100 + if (txt.trim() === '{}') // users wouldn't understand
101 + txt = ''
102 + fs.writeFile(path, txt)
103 .catch(err => console.error('Failed at saving config file, please ensure it is writable.', String(err)))
104 }, 100)
105
src/listen.ts
+5 -2
@@ -1,5 +1,5 @@
1 import * as http from 'http'
2 -import { getConfig, subscribeConfig } from './config'
2 +import { defineConfig, getConfig, subscribeConfig } from './config'
3 import { adminApp, app } from './index'
4 import * as https from 'https'
5 import { watchLoad } from './watchLoad'
@@ -7,6 +7,7 @@ import { networkInterfaces } from 'os';
7 import { newConnection } from './connections'
8 import open from 'open'
9 import { debounceAsync } from './misc'
10 +import { DEV } from './const'
11
12 let httpSrv: http.Server
13 let httpsSrv: http.Server
@@ -37,11 +38,13 @@ const considerAdmin = debounceAsync(async () => {
38 })
39 if (!resultPort)
40 return
40 - if (getConfig('open_browser_at_start') !== false)
41 + if (getConfig('open_browser_at_start'))
42 open('http://localhost:' + resultPort).then()
43 console.log('admin interface on http://localhost:' + resultPort)
44 })
45
46 +defineConfig('open_browser_at_start', { defaultValue: !DEV })
47 +
48 subscribeConfig<string>({ k:'admin_network', defaultValue: '127.0.0.1' }, considerAdmin)
49 subscribeConfig<number>({ k:'admin_port', defaultValue: 63636 }, considerAdmin)
50
src/serveFile.ts
+3 -1
@@ -4,7 +4,7 @@ import fs from 'fs/promises'
4 import { METHOD_NOT_ALLOWED, NO_CONTENT } from './const'
5 import { MIME_AUTO, VfsNode } from './vfs'
6 import mimetypes from 'mime-types'
7 -import { getConfig } from './config'
7 +import { defineConfig, getConfig } from './config'
8 import mm from 'micromatch'
9 import _ from 'lodash'
10 import path from 'path'
@@ -18,6 +18,8 @@ export function serveFileNode(node: VfsNode) : Koa.Middleware {
18 }
19 }
20
21 +defineConfig('mime', { defaultValue:{ '*.jpg|*.png|*.mp3|*.txt': 'auto' } })
22 +
23 export function serveFile(source:string, mime?:string, modifier?:(s:string)=>string) : Koa.Middleware {
24 return async (ctx) => {
25 if (!source)
src/zip.ts
+4 -2
@@ -4,7 +4,7 @@ import { filterMapGenerator, pattern2filter, prefix } from './misc'
4 import { QuickZipStream } from './QuickZipStream'
5 import { createReadStream } from 'fs'
6 import fs from 'fs/promises'
7 -import { getConfig } from './config'
7 +import { defineConfig, getConfig } from './config'
8 import { dirname } from 'path'
9
10 export async function zipStreamFromFolder(node: VfsNode, ctx: Koa.Context) {
@@ -45,8 +45,10 @@ export async function zipStreamFromFolder(node: VfsNode, ctx: Koa.Context) {
45 catch {}
46 })
47 const zip = new QuickZipStream(mappedWalker)
48 - const time = 1000 * (getConfig('zip_calculate_size_for_seconds') ?? 1)
48 + const time = 1000 * (getConfig('zip_calculate_size_for_seconds'))
49 ctx.response.length = await zip.calculateSize(time)
50 ctx.body = zip
51 ctx.req.on('close', ()=> zip.destroy())
52 }
53 +
54 +defineConfig('zip_calculate_size_for_seconds', { defaultValue: 1 })