plugin.config.defaultValue
Massimo Melina committed
May 1, 2022 at 00:10 UTC
c323f81343ddbbe5b88ba6fb5b8d57ea546be35a
7 files changed
+42
-21
admin/src/LogoutPage.ts
+1
-1
@@ -5,7 +5,7 @@ import { alertDialog } from "./dialog"
5
import { useSnapState } from './state'
6
7
export default function LogoutPage() {
8
- const [cfg] = useApiComp('get_config', { only: [] })
8
+ const [cfg] = useApiComp('get_config', { only: [] }) // sort of noop
9
const { username } = useSnapState()
10
if (isValidElement(cfg))
11
return cfg
admin/src/PluginsPage.ts
+8
-14
@@ -1,5 +1,5 @@
1
-import { createElement as h, isValidElement } from "react"
2
-import { apiCall, useApiComp, useApiList } from './api'
1
+import { createElement as h } from "react"
2
+import { apiCall, useApiList } from './api'
3
import { DataGrid } from '@mui/x-data-grid'
4
import { Alert, Box } from '@mui/material'
5
import { IconBtn } from './misc'
@@ -8,16 +8,10 @@ import { alertDialog, formDialog } from './dialog'
8
import { BoolField, Field, MultiSelectField, NumberField, SelectField, StringField } from './Form'
9
import { ArrayField } from './ArrayField'
10
11
-const PLUGINS_CONFIG = 'plugins_config'
12
-
11
export default function PluginsPage() {
12
const { list, error, initializing } = useApiList('get_plugins')
15
- const [cfgRes, reloadCfg] = useApiComp('get_config', { only: [PLUGINS_CONFIG] })
16
- if (isValidElement(cfgRes))
17
- return cfgRes
13
if (error)
14
return h(Alert, { severity: 'error' }, error)
20
- const cfg = cfgRes[PLUGINS_CONFIG]
15
return h(DataGrid, {
16
rows: list,
17
loading: initializing,
@@ -61,15 +55,15 @@ export default function PluginsPage() {
55
icon: Settings,
56
title: "Configuration",
57
disabled: !config,
64
- onClick() {
65
- formDialog({
58
+ async onClick() {
59
+ const pl = await apiCall('get_plugin', { id })
60
+ const values = await formDialog({
61
title: `${id} configuration`,
62
fields: [ h(Box, {}, row.description), ...makeFields(config) ],
68
- values: cfg?.[id],
69
- }).then(config => {
70
- if (config)
71
- apiCall('set_plugin', { id, config }).then(reloadCfg)
63
+ values: pl.config,
64
})
65
+ if (values)
66
+ await apiCall('set_plugin', { id, config: values })
67
}
68
}),
69
)
plugins/vhosting/plugin.js
+2
-1
@@ -10,6 +10,7 @@ exports.config = {
10
host: { label: "Domain" },
11
root: { helperText: "Root path in VFS" },
12
},
13
+ defaultValue: [],
14
height: 300,
15
}
16
}
@@ -23,7 +24,7 @@ exports.init = api => ({
24
return
25
}
26
const hosts = api.getConfig('hosts')
26
- if (!hosts) return
27
+ if (!hosts?.length) return
28
for (const row of hosts)
29
if (ctx.host === row.host) {
30
toModify.path = row.root + toModify.path
server/src/adminApis.ts
+23
-3
@@ -7,7 +7,7 @@ import { API_VERSION, BUILD_TIMESTAMP, COMPATIBLE_API_VERSION, FORBIDDEN, HFS_ST
7
import vfsApis from './api.vfs'
8
import accountsApis from './api.accounts'
9
import { Connection, getConnections } from './connections'
10
-import { debounceAsync, isLocalHost, onOff, pendingPromise } from './misc'
10
+import { debounceAsync, isLocalHost, objSameKeys, onOff, pendingPromise, same } from './misc'
11
import _ from 'lodash'
12
import events from './events'
13
import { getFromAccount } from './perm'
@@ -18,7 +18,15 @@ import { writeFile } from 'fs/promises'
18
import { createReadStream } from 'fs'
19
import * as readline from 'readline'
20
import { loggers } from './log'
21
-import { mapPlugins, getAvailablePlugins, Plugin, AvailablePlugin, enablePlugins, pluginsConfig } from './plugins'
21
+import {
22
+ mapPlugins,
23
+ getAvailablePlugins,
24
+ Plugin,
25
+ AvailablePlugin,
26
+ enablePlugins,
27
+ pluginsConfig,
28
+ getPluginConfigFields
29
+} from './plugins'
30
import { execFile } from 'child_process'
31
import { promisify } from 'util'
32
import assert from 'assert'
@@ -176,13 +184,25 @@ export const adminApis: ApiHandlers = {
184
enablePlugins.set( enabled ? [...a, id] : a.filter((x: string) => x !== id) )
185
}
186
if (config) {
179
- config = _.pickBy(config, v => v !== null)
187
+ const fields = getPluginConfigFields(id)
188
+ config = _.pickBy(config, (v, k) =>
189
+ v !== null && !same(v, fields?.[k]?.defaultValue))
190
if (_.isEmpty(config))
191
config = undefined
192
pluginsConfig.set({ ...pluginsConfig.get(), [id]: config })
193
}
194
return {}
195
},
196
+
197
+ async get_plugin({ id }) {
198
+ return {
199
+ enabled: enablePlugins.get().includes(id),
200
+ config: {
201
+ ...objSameKeys(getPluginConfigFields(id) ||{}, v => v?.defaultValue),
202
+ ...pluginsConfig.get()[id]
203
+ }
204
+ }
205
+ },
206
}
207
208
// offer an api for a generic dynamic list
server/src/config.ts
+2
@@ -110,6 +110,8 @@ export function setConfig(newCfg: Record<string,any>, save?: boolean) {
110
}
111
112
function setConfig1(k: string, newV: any, saveChanges=true) {
113
+ if (_.isPlainObject(newV))
114
+ newV = _.pickBy(newV, x => x !== undefined)
115
if (same(newV, configProps[k]?.defaultValue))
116
newV = undefined
117
if (started && same(newV, state[k])) return // no change
server/src/const.ts
+1
-1
@@ -12,7 +12,7 @@ export const VERSION = ''
12
export const SESSION_DURATION = 30*60_000
13
export const DAY = 86_400_000
14
15
-export const API_VERSION = 2
15
+export const API_VERSION = 3 // with 3 we introduced config.defaultValue
16
export const COMPATIBLE_API_VERSION = 1 // while changes in the api are not breaking, this number stays the same, otherwise is made equal to API_VERSION
17
18
export const SPECIAL_URI = '/~/'
server/src/plugins.ts
+5
-1
@@ -30,6 +30,10 @@ export function mapPlugins<T>(cb:(plugin:Readonly<Plugin>, pluginName:string)=>
30
}).filter(x => x !== undefined) as Exclude<T,undefined>[]
31
}
32
33
+export function getPluginConfigFields(id: string) {
34
+ return plugins[id]?.getData().config
35
+}
36
+
37
export function pluginsMiddleware(): Koa.Middleware {
38
return async (ctx, next) => {
39
const after = []
@@ -190,7 +194,7 @@ async function rescan() {
194
getConnections,
195
events,
196
getConfig: (cfgKey: string) =>
193
- pluginsConfig.get()?.[id]?.[cfgKey]
197
+ pluginsConfig.get()?.[id]?.[cfgKey] ?? data.config?.[cfgKey]?.defaultValue
198
})
199
Object.assign(data, res)
200
new Plugin(id, data, unwatch)