2020-02-24 08:24:36 +00:00
|
|
|
import * as yaml from 'js-yaml'
|
2020-07-06 08:06:47 +00:00
|
|
|
import * as fs from '@ccms/common/dist/fs'
|
|
|
|
import { plugin } from '@ccms/api'
|
2020-09-24 10:36:10 +00:00
|
|
|
import { provideSingleton } from '@ccms/container'
|
|
|
|
|
|
|
|
import { interfaces } from './interfaces'
|
2020-07-06 08:06:47 +00:00
|
|
|
import { getPluginConfigMetadata } from './utils'
|
2020-02-24 08:24:36 +00:00
|
|
|
|
|
|
|
export interface PluginConfigLoader {
|
2020-07-06 08:06:47 +00:00
|
|
|
load(content: string): any
|
|
|
|
dump(variable: any): string
|
2020-02-24 08:24:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export class YamlPluginConfig implements PluginConfigLoader {
|
|
|
|
load(content: string) {
|
2021-03-27 03:35:54 +00:00
|
|
|
return yaml.load(content)
|
2020-02-24 08:24:36 +00:00
|
|
|
}
|
|
|
|
dump(variable: any): string {
|
2021-03-27 03:35:54 +00:00
|
|
|
return yaml.dump(variable, { skipInvalid: true, lineWidth: 120 })
|
2020-02-24 08:24:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class JsonPluginConfig implements PluginConfigLoader {
|
|
|
|
load(content: string) {
|
2020-07-06 08:06:47 +00:00
|
|
|
return JSON.parse(content)
|
2020-02-24 08:24:36 +00:00
|
|
|
}
|
|
|
|
dump(variable: any): string {
|
2020-09-24 10:36:10 +00:00
|
|
|
return JSON.stringify(variable, undefined, 4)
|
2020-02-24 08:24:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-02 10:53:31 +00:00
|
|
|
export interface PluginConfig {
|
|
|
|
/**
|
|
|
|
* Save Config to File
|
|
|
|
*/
|
|
|
|
readonly save?: () => void
|
|
|
|
/**
|
|
|
|
* Reload Config from File
|
|
|
|
*/
|
|
|
|
readonly reload?: () => void
|
|
|
|
[key: string]: any
|
|
|
|
}
|
|
|
|
|
2020-09-24 10:36:10 +00:00
|
|
|
@provideSingleton(PluginConfigManager)
|
|
|
|
export class PluginConfigManager {
|
|
|
|
private configLoaderMap = new Map<string, PluginConfigLoader>()
|
2020-02-24 08:24:36 +00:00
|
|
|
|
2020-09-24 10:36:10 +00:00
|
|
|
constructor() {
|
|
|
|
this.configLoaderMap.set("json", new JsonPluginConfig())
|
|
|
|
let yaml = new YamlPluginConfig()
|
|
|
|
this.configLoaderMap.set("yml", yaml)
|
|
|
|
this.configLoaderMap.set("yaml", yaml)
|
|
|
|
process.on('plugin.before.load', this.loadConfig.bind(this))
|
|
|
|
process.on('plugin.after.disable', this.saveConfig.bind(this))
|
|
|
|
}
|
2020-07-06 08:06:47 +00:00
|
|
|
|
2020-09-24 10:36:10 +00:00
|
|
|
getConfigLoader(format: string) {
|
|
|
|
if (!this.configLoaderMap.has(format)) { throw new Error(`Unsupport config format ${format} !`) }
|
|
|
|
return this.configLoaderMap.get(format)
|
|
|
|
}
|
|
|
|
|
|
|
|
loadConfig(plugin: plugin.Plugin) {
|
|
|
|
let configs = getPluginConfigMetadata(plugin)
|
|
|
|
for (let [_, config] of configs) {
|
2020-10-02 10:53:31 +00:00
|
|
|
this.loadConfig0(plugin, config)
|
2020-07-06 08:06:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-24 10:36:10 +00:00
|
|
|
saveConfig(plugin: plugin.Plugin) {
|
|
|
|
let configs = getPluginConfigMetadata(plugin)
|
|
|
|
for (let [_, config] of configs) {
|
2020-10-31 03:40:38 +00:00
|
|
|
config.autosave && this.saveConfig0(plugin, config)
|
2020-09-24 10:36:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-02 10:53:31 +00:00
|
|
|
private defienConfigProp(plugin: plugin.Plugin, metadata: interfaces.ConfigMetadata, value: any) {
|
|
|
|
Object.defineProperties(value, {
|
|
|
|
'save': { value: () => this.saveConfig0(plugin, metadata) },
|
|
|
|
'reload': { value: () => this.loadConfig0(plugin, metadata) }
|
|
|
|
})
|
|
|
|
Object.defineProperty(plugin, metadata.variable, { value })
|
|
|
|
}
|
|
|
|
|
|
|
|
private loadConfig0(plugin: plugin.Plugin, metadata: interfaces.ConfigMetadata) {
|
|
|
|
try {
|
|
|
|
metadata.file = fs.concat(fs.file(plugin.description.loadMetadata.file).parent, plugin.description.name, metadata.filename)
|
|
|
|
let configLoader = this.getConfigLoader(metadata.format)
|
2021-06-22 07:51:13 +00:00
|
|
|
let defaultValue = metadata.default ?? plugin[metadata.variable]
|
|
|
|
let configValue = defaultValue
|
2020-10-02 10:53:31 +00:00
|
|
|
if (!fs.exists(metadata.file)) {
|
2021-06-22 07:51:13 +00:00
|
|
|
base.save(metadata.file, configLoader.dump(defaultValue))
|
2020-10-02 10:53:31 +00:00
|
|
|
console.i18n("ms.plugin.manager.config.save.default", { plugin: plugin.description.name, name: metadata.name, format: metadata.format })
|
|
|
|
} else {
|
2021-06-22 07:51:13 +00:00
|
|
|
configValue = configLoader.load(base.read(metadata.file)) || {}
|
2021-11-04 01:07:48 +00:00
|
|
|
if (defaultValue && this.setDefaultValue(configValue, defaultValue)) {
|
|
|
|
base.save(metadata.file, configLoader.dump(configValue))
|
2020-12-17 08:58:37 +00:00
|
|
|
}
|
2021-08-14 04:44:58 +00:00
|
|
|
console.debug(`[${plugin.description.name}] Load Config ${metadata.variable} from file ${metadata.file} =>\n${JSON.stringify(configValue, undefined, 4).substr(0, 500)}`)
|
2020-10-02 10:53:31 +00:00
|
|
|
}
|
2021-06-22 07:51:13 +00:00
|
|
|
this.defienConfigProp(plugin, metadata, configValue)
|
2020-10-02 10:53:31 +00:00
|
|
|
} catch (error) {
|
|
|
|
console.i18n("ms.plugin.manager.config.load.error", { plugin: plugin.description.name, name: metadata.name, format: metadata.format, error })
|
|
|
|
console.ex(error)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-04 01:07:48 +00:00
|
|
|
private setDefaultValue(configValue, defaultValue) {
|
|
|
|
let needSave = false
|
|
|
|
for (const key of Object.keys(defaultValue)) {
|
|
|
|
// 当配置文件不存在当前属性时才进行赋值
|
|
|
|
if (!Object.prototype.hasOwnProperty.call(configValue, key)) {
|
|
|
|
configValue[key] = defaultValue[key]
|
|
|
|
needSave = true
|
|
|
|
} else if (Object.prototype.toString.call(configValue[key]) == "[object Object]") {
|
|
|
|
// 对象需要递归检测
|
|
|
|
needSave ||= this.setDefaultValue(configValue[key], defaultValue[key])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return needSave
|
|
|
|
}
|
|
|
|
|
2020-09-24 10:36:10 +00:00
|
|
|
private saveConfig0(plugin: plugin.Plugin, metadata: interfaces.ConfigMetadata) {
|
2020-07-06 08:06:47 +00:00
|
|
|
try {
|
2020-09-24 10:36:10 +00:00
|
|
|
metadata.file = fs.concat(fs.file(plugin.description.loadMetadata.file).parent, plugin.description.name, metadata.filename)
|
|
|
|
let result = this.getConfigLoader(metadata.format).dump(plugin[metadata.variable])
|
|
|
|
base.save(metadata.file, result)
|
2021-08-14 04:44:58 +00:00
|
|
|
console.debug(`[${plugin.description.name}] Save Config ${metadata.variable} to file ${metadata.file} =>\n${result.substr(0, 500)}`)
|
2020-09-24 10:36:10 +00:00
|
|
|
return true
|
2020-07-06 08:06:47 +00:00
|
|
|
} catch (error) {
|
2020-09-24 10:36:10 +00:00
|
|
|
console.i18n("ms.plugin.manager.config.save.error", { plugin: plugin.description.name, name: metadata.name, format: metadata.format, error })
|
2020-07-06 08:06:47 +00:00
|
|
|
console.ex(error)
|
2020-09-24 10:36:10 +00:00
|
|
|
return false
|
2020-07-06 08:06:47 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-24 08:24:36 +00:00
|
|
|
}
|