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'
14 @DefaultScope(() => ({
16 exclude: [ 'storage' ]
24 fields: [ 'name', 'type' ],
29 export class PluginModel extends Model<PluginModel> {
32 @Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name'))
37 @Is('PluginType', value => throwIfNotValid(value, isPluginTypeValid, 'type'))
42 @Is('PluginVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
47 @Is('PluginLatestVersion', value => throwIfNotValid(value, isPluginVersionValid, 'version'))
61 peertubeEngine: string
64 @Is('PluginDescription', value => throwIfNotValid(value, isPluginDescriptionValid, 'description'))
69 @Is('PluginHomepage', value => throwIfNotValid(value, isPluginHomepage, 'homepage'))
74 @Column(DataType.JSONB)
78 @Column(DataType.JSONB)
87 static listEnabledPluginsAndThemes () {
95 return PluginModel.findAll(query)
98 static loadByNpmName (npmName: string) {
99 const name = this.normalizePluginName(npmName)
100 const type = this.getTypeFromNpmName(npmName)
109 return PluginModel.findOne(query)
112 static getSetting (pluginName: string, pluginType: PluginType, settingName: string) {
114 attributes: [ 'settings' ],
121 return PluginModel.findOne(query)
123 if (!p || !p.settings) return undefined
125 return p.settings[settingName]
129 static setSetting (pluginName: string, pluginType: PluginType, settingName: string, settingValue: string) {
138 [`settings.${settingName}`]: settingValue
141 return PluginModel.update(toSave, query)
142 .then(() => undefined)
145 static getData (pluginName: string, pluginType: PluginType, key: string) {
148 attributes: [ [ json('storage.' + key), 'value' ] as any ], // FIXME: typings
155 return PluginModel.findOne(query)
157 if (!c) return undefined
163 static storeData (pluginName: string, pluginType: PluginType, key: string, data: any) {
172 [`storage.${key}`]: data
175 return PluginModel.update(toSave, query)
176 .then(() => undefined)
179 static listForApi (options: {
181 uninstalled?: boolean,
186 const { uninstalled = false } = options
187 const query: FindAndCountOptions = {
188 offset: options.start,
189 limit: options.count,
190 order: getSort(options.sort),
196 if (options.type) query.where['type'] = options.type
199 .findAndCountAll(query)
200 .then(({ rows, count }) => {
201 return { total: count, data: rows }
205 static normalizePluginName (name: string) {
206 return name.replace(/^peertube-((theme)|(plugin))-/, '')
209 static getTypeFromNpmName (npmName: string) {
210 return npmName.startsWith('peertube-plugin-')
215 static buildNpmName (name: string, type: PluginType) {
216 if (type === PluginType.THEME) return 'peertube-theme-' + name
218 return 'peertube-plugin-' + name
221 toFormattedJSON (): PeerTubePlugin {
225 version: this.version,
226 latestVersion: this.latestVersion,
227 enabled: this.enabled,
228 uninstalled: this.uninstalled,
229 peertubeEngine: this.peertubeEngine,
230 description: this.description,
231 homepage: this.homepage,
232 settings: this.settings,
233 createdAt: this.createdAt,
234 updatedAt: this.updatedAt