| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 | 
							- import { Model } from 'objection'
 
- import path from 'node:path'
 
- import fs from 'node:fs/promises'
 
- import { capitalize, find, has, hasIn, remove, uniq } from 'lodash-es'
 
- import yaml from 'js-yaml'
 
- /**
 
-  * Storage model
 
-  */
 
- export class Storage extends Model {
 
-   static get tableName() { return 'storage' }
 
-   static get idColumn() { return 'id' }
 
-   static get jsonSchema () {
 
-     return {
 
-       type: 'object',
 
-       required: ['module', 'isEnabled', 'siteId'],
 
-       properties: {
 
-         module: {type: 'string'},
 
-         isEnabled: {type: 'boolean'}
 
-       }
 
-     }
 
-   }
 
-   static get jsonAttributes() {
 
-     return ['contentTypes', 'assetDelivery', 'versioning', 'schedule', 'config', 'state']
 
-   }
 
-   static async getTargets ({ siteId, enabledOnly = false } = {}) {
 
-     return WIKI.db.storage.query().where(builder => {
 
-       if (siteId) {
 
-         builder.where('siteId', siteId)
 
-       }
 
-       if (enabledOnly) {
 
-         builder.where('isEnabled', true)
 
-       }
 
-     })
 
-   }
 
-   static async refreshTargetsFromDisk () {
 
-     let trx
 
-     try {
 
-       // -> Fetch definitions from disk
 
-       const storageDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/storage'))
 
-       WIKI.storage.defs = []
 
-       for (const dir of storageDirs) {
 
-         const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/storage', dir, 'definition.yml'), 'utf8')
 
-         const defParsed = yaml.load(def)
 
-         defParsed.key = dir
 
-         defParsed.isLoaded = false
 
-         WIKI.storage.defs.push(defParsed)
 
-         WIKI.logger.debug(`Loaded storage module definition ${dir}: [ OK ]`)
 
-       }
 
-       WIKI.logger.info(`Loaded ${WIKI.storage.defs.length} storage module definitions: [ OK ]`)
 
-     } catch (err) {
 
-       WIKI.logger.error('Failed to scan or load new storage providers: [ FAILED ]')
 
-       WIKI.logger.error(err)
 
-       if (trx) {
 
-         trx.rollback()
 
-       }
 
-     }
 
-   }
 
-   /**
 
-  * Ensure a storage module is loaded
 
-  */
 
-   static async ensureModule (moduleName) {
 
-     if (!has(WIKI.storage.modules, moduleName)) {
 
-       try {
 
-         WIKI.storage.modules[moduleName] = (await import(`../modules/storage/${moduleName}/storage.mjs`)).default
 
-         WIKI.logger.debug(`Activated storage module ${moduleName}: [ OK ]`)
 
-         return true
 
-       } catch (err) {
 
-         WIKI.logger.warn(`Failed to load storage module ${moduleName}: [ FAILED ]`)
 
-         WIKI.logger.warn(err)
 
-         return false
 
-       }
 
-     } else {
 
-       return true
 
-     }
 
-   }
 
-   /**
 
-    * Initialize active storage targets
 
-    */
 
-   static async initTargets () {
 
-     const dbTargets = await WIKI.db.storage.query().where('isEnabled', true)
 
-     const activeModules = uniq(dbTargets.map(t => t.module))
 
-     try {
 
-       // -> Stop and delete existing jobs
 
-       // const prevjobs = remove(WIKI.scheduler.jobs, job => job.name === 'sync-storage')
 
-       // if (prevjobs.length > 0) {
 
-       //   prevjobs.forEach(job => job.stop())
 
-       // }
 
-       // -> Load active modules
 
-       for (const md of activeModules) {
 
-         this.ensureModule(md)
 
-       }
 
-       // -> Initialize targets
 
-       // for (const target of this.targets) {
 
-       //   const targetDef = find(WIKI.data.storage, ['key', target.key])
 
-       //   target.fn = require(`../modules/storage/${target.key}/storage`)
 
-       //   target.fn.config = target.config
 
-       //   target.fn.mode = target.mode
 
-       //   try {
 
-       //     await target.fn.init()
 
-       //     // -> Save succeeded init state
 
-       //     await WIKI.db.storage.query().patch({
 
-       //       state: {
 
-       //         status: 'operational',
 
-       //         message: '',
 
-       //         lastAttempt: new Date().toISOString()
 
-       //       }
 
-       //     }).where('key', target.key)
 
-       //     // -> Set recurring sync job
 
-       //     if (targetDef.schedule && target.syncInterval !== 'P0D') {
 
-       //       WIKI.scheduler.registerJob({
 
-       //         name: 'sync-storage',
 
-       //         immediate: false,
 
-       //         schedule: target.syncInterval,
 
-       //         repeat: true
 
-       //       }, target.key)
 
-       //     }
 
-       //     // -> Set internal recurring sync job
 
-       //     if (targetDef.internalSchedule && targetDef.internalSchedule !== 'P0D') {
 
-       //       WIKI.scheduler.registerJob({
 
-       //         name: 'sync-storage',
 
-       //         immediate: false,
 
-       //         schedule: target.internalSchedule,
 
-       //         repeat: true
 
-       //       }, target.key)
 
-       //     }
 
-       //   } catch (err) {
 
-       //     // -> Save initialization error
 
-       //     await WIKI.db.storage.query().patch({
 
-       //       state: {
 
-       //         status: 'error',
 
-       //         message: err.message,
 
-       //         lastAttempt: new Date().toISOString()
 
-       //       }
 
-       //     }).where('key', target.key)
 
-       //   }
 
-       // }
 
-     } catch (err) {
 
-       WIKI.logger.warn(err)
 
-       throw err
 
-     }
 
-   }
 
-   static async pageEvent({ event, page }) {
 
-     try {
 
-       for (let target of this.targets) {
 
-         await target.fn[event](page)
 
-       }
 
-     } catch (err) {
 
-       WIKI.logger.warn(err)
 
-       throw err
 
-     }
 
-   }
 
-   static async assetEvent({ event, asset }) {
 
-     try {
 
-       for (let target of this.targets) {
 
-         await target.fn[`asset${capitalize(event)}`](asset)
 
-       }
 
-     } catch (err) {
 
-       WIKI.logger.warn(err)
 
-       throw err
 
-     }
 
-   }
 
-   static async getLocalLocations({ asset }) {
 
-     const locations = []
 
-     const promises = this.targets.map(async (target) => {
 
-       try {
 
-         const path = await target.fn.getLocalLocation(asset)
 
-         locations.push({
 
-           path,
 
-           key: target.key
 
-         })
 
-       } catch (err) {
 
-         WIKI.logger.warn(err)
 
-       }
 
-     })
 
-     await Promise.all(promises)
 
-     return locations
 
-   }
 
-   static async executeAction(targetKey, handler) {
 
-     try {
 
-       const target = find(this.targets, ['key', targetKey])
 
-       if (target) {
 
-         if (hasIn(target.fn, handler)) {
 
-           await target.fn[handler]()
 
-         } else {
 
-           throw new Error('Invalid Handler for Storage Target')
 
-         }
 
-       } else {
 
-         throw new Error('Invalid or Inactive Storage Target')
 
-       }
 
-     } catch (err) {
 
-       WIKI.logger.warn(err)
 
-       throw err
 
-     }
 
-   }
 
- }
 
 
  |