1 import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
2 import { getSort, throwIfNotValid } from '../utils'
4 isPluginDescriptionValid,
9 } from '../../helpers/custom-validators/plugins'
10 import { PluginType } from '../../../shared/models/plugins/plugin.type'
11 import { PeerTubePlugin } from '../../../shared/models/plugins/peertube-plugin.model'
12 import { FindAndCountOptions, json } from 'sequelize'
13 import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model'
15 @DefaultScope(() => ({
17 exclude: [ 'storage' ]
25 fields: [ 'name', 'type' ],
30 export class PluginModel extends Model<PluginModel> {
33 @Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name'))
38 @Is('PluginType', value => throwIfNotValid(value, isPluginTypeValid, 'type'))
43 @Is('PluginVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
48 @Is('PluginLatestVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
62 peertubeEngine: string
65 @Is('PluginDescription', value => throwIfNotValid(value, isPluginDescriptionValid, 'description'))
70 @Is('PluginHomepage', value => throwIfNotValid(value, isPluginHomepage, 'homepage'))
75 @Column(DataType.JSONB)
79 @Column(DataType.JSONB)
88 static listEnabledPluginsAndThemes () {
96 return PluginModel.findAll(query)
99 static loadByNpmName (npmName: string) {
100 const name = this.normalizePluginName(npmName)
101 const type = this.getTypeFromNpmName(npmName)
110 return PluginModel.findOne(query)
113 static getSetting (pluginName: string, pluginType: PluginType, settingName: string) {
115 attributes: [ 'settings' ],
122 return PluginModel.findOne(query)
124 if (!p || !p.settings) return undefined
126 return p.settings[settingName]
130 static setSetting (pluginName: string, pluginType: PluginType, settingName: string, settingValue: string) {
139 [`settings.${settingName}`]: settingValue
142 return PluginModel.update(toSave, query)
143 .then(() => undefined)
146 static getData (pluginName: string, pluginType: PluginType, key: string) {
149 attributes: [ [ json('storage.' + key), 'value' ] as any ], // FIXME: typings
156 return PluginModel.findOne(query)
158 if (!c) return undefined
159 const value = c.value
161 if (typeof value === 'string' && value.startsWith('{')) {
163 return JSON.parse(value)
173 static storeData (pluginName: string, pluginType: PluginType, key: string, data: any) {
182 [`storage.${key}`]: data
185 return PluginModel.update(toSave, query)
186 .then(() => undefined)
189 static listForApi (options: {
190 pluginType?: PluginType,
191 uninstalled?: boolean,
196 const { uninstalled = false } = options
197 const query: FindAndCountOptions = {
198 offset: options.start,
199 limit: options.count,
200 order: getSort(options.sort),
206 if (options.pluginType) query.where['type'] = options.pluginType
209 .findAndCountAll(query)
210 .then(({ rows, count }) => {
211 return { total: count, data: rows }
215 static listInstalled () {
222 return PluginModel.findAll(query)
225 static normalizePluginName (npmName: string) {
226 return npmName.replace(/^peertube-((theme)|(plugin))-/, '')
229 static getTypeFromNpmName (npmName: string) {
230 return npmName.startsWith('peertube-plugin-')
235 static buildNpmName (name: string, type: PluginType) {
236 if (type === PluginType.THEME) return 'peertube-theme-' + name
238 return 'peertube-plugin-' + name
241 getPublicSettings (registeredSettings: RegisterServerSettingOptions[]) {
242 const result: { [ name: string ]: string } = {}
243 const settings = this.settings || {}
245 for (const r of registeredSettings) {
246 if (r.private !== false) continue
248 result[r.name] = settings[r.name] || r.default || null
254 toFormattedJSON (): PeerTubePlugin {
258 version: this.version,
259 latestVersion: this.latestVersion,
260 enabled: this.enabled,
261 uninstalled: this.uninstalled,
262 peertubeEngine: this.peertubeEngine,
263 description: this.description,
264 homepage: this.homepage,
265 settings: this.settings,
266 createdAt: this.createdAt,
267 updatedAt: this.updatedAt