ability to expose plugin's config on frontend javascript
Massimo Melina committed
Feb 26, 2023 at 23:59 UTC
ed7d54bea4cad68b6c9232e8cf68c15d8c66e23e
4 files changed
+25
-5
dev-plugins.md
+1
@@ -76,6 +76,7 @@ Currently, these properties are supported:
76
- `label: string` what name to display next to the field. Default is based on `key`.
77
- `defaultValue: any` value to be used when nothing is set.
78
- `helperText: string` extra text printed next to the field.
79
+- `frontend: boolean` expose this setting on the frontend, so that javascript can access it as HFS.plugins[PLUGIN_NAME][CONFIG_KEY]
80
81
Based on `type`, other properties are supported:
82
- `string`
src/const.ts
+1
-1
@@ -17,7 +17,7 @@ export const VERSION = pkg.version
17
export const DAY = 86_400_000
18
export const SESSION_DURATION = DAY
19
20
-export const API_VERSION = 5 // afterEntryName
20
+export const API_VERSION = 6 // config.frontend
21
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
22
23
export const SPECIAL_URI = '/~/'
src/misc.ts
+12
-2
@@ -32,8 +32,18 @@ export function setHidden<T, ADD>(dest: T, src: ADD) {
32
}))) as T & ADD
33
}
34
35
-export function objSameKeys<S extends object,VR=any>(src: S, newValue:(value:Truthy<S[keyof S]>, key:keyof S)=>any) {
36
- return Object.fromEntries(Object.entries(src).map(([k,v]) => [k, newValue(v,k as keyof S)])) as { [K in keyof S]:VR }
35
+export function objSameKeys<S extends object,VR=any>(
36
+ src: S,
37
+ newValue: (value:Truthy<S[keyof S]>, key:keyof S, skip:()=>void)=>any
38
+) {
39
+ let skipped = false
40
+ const pairs = Object.entries(src).map( ([k,v]) => {
41
+ skipped = false
42
+ const newV = newValue(v, k as keyof S, skip)
43
+ return !skipped && [k, newV]
44
+ })
45
+ return Object.fromEntries(pairs.filter(Boolean)) as { [K in keyof S]:VR }
46
+ function skip() { skipped = true }
47
}
48
49
export function wait(ms: number) {
src/serveGuiFiles.ts
+11
-2
@@ -12,12 +12,13 @@ import {
12
VERSION
13
} from './const'
14
import { serveFile } from './serveFile'
15
-import { mapPlugins } from './plugins'
15
+import { getPluginConfigFields, mapPlugins, pluginsConfig } from './plugins'
16
import { refresh_session } from './api.auth'
17
import { ApiError } from './apiMiddleware'
18
import { join, extname } from 'path'
19
-import { getOrSet } from './misc'
19
+import { getOrSet, objSameKeys, onlyTruthy } from './misc'
20
import { favicon, title } from './adminApis'
21
+import _ from 'lodash'
22
23
// in case of dev env we have our static files within the 'dist' folder'
24
const DEV_STATIC = process.env.DEV ? 'dist/' : ''
@@ -84,6 +85,14 @@ async function treatIndex(ctx: Koa.Context, body: string, filesUri: string) {
85
VERSION,
86
API_VERSION,
87
session: session instanceof ApiError ? null : session,
88
+ // expose plugins' configs that were declared with 'frontend' attribute
89
+ plugins: Object.fromEntries(onlyTruthy(mapPlugins((pl,name) => {
90
+ const configs = objSameKeys(getPluginConfigFields(name), (v,k,skip) =>
91
+ !v.frontend ? skip() :
92
+ (pluginsConfig.get()?.[name]?.[k] ?? pl.getData().config?.[k]?.defaultValue)
93
+ )
94
+ return !_.isEmpty(configs) && [name, configs]
95
+ })))
96
}, null, 4)}
97
document.documentElement.setAttribute('ver', '${VERSION.split('-')[0] /*for style selectors*/}')
98
</script>