You need to sign in or sign up before continuing.
sites.mjs 4.61 KB
Newer Older
1 2
import { Model } from 'objection'
import { defaultsDeep, keyBy } from 'lodash-es'
3
import { v4 as uuid } from 'uuid'
4 5 6 7

/**
 * Site model
 */
8
export class Site extends Model {
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
  static get tableName () { return 'sites' }

  static get jsonSchema () {
    return {
      type: 'object',
      required: ['hostname'],

      properties: {
        id: { type: 'string' },
        hostname: { type: 'string' },
        isEnabled: { type: 'boolean', default: false }
      }
    }
  }

  static get jsonAttributes () {
    return ['config']
  }

28 29
  static async getSiteByHostname ({ hostname, forceReload = false }) {
    if (forceReload) {
30
      await WIKI.db.sites.reloadCache()
31 32 33 34 35 36 37 38 39 40
    }
    const siteId = WIKI.sitesMappings[hostname] || WIKI.sitesMappings['*']
    if (siteId) {
      return WIKI.sites[siteId]
    }
    return null
  }

  static async reloadCache () {
    WIKI.logger.info('Reloading site configurations...')
41
    const sites = await WIKI.db.sites.query().orderBy('id')
42
    WIKI.sites = keyBy(sites, 'id')
43 44 45 46 47 48 49
    WIKI.sitesMappings = {}
    for (const site of sites) {
      WIKI.sitesMappings[site.hostname] = site.id
    }
    WIKI.logger.info(`Loaded ${sites.length} site configurations [ OK ]`)
  }

50
  static async createSite (hostname, config) {
51
    const newSite = await WIKI.db.sites.query().insertAndFetch({
52 53
      hostname,
      isEnabled: true,
54
      config: defaultsDeep(config, {
55 56 57 58
        title: 'My Wiki Site',
        description: '',
        company: '',
        contentLicense: '',
59
        footerExtra: '',
60
        pageExtensions: ['md', 'html', 'txt'],
61
        pageCasing: true,
62
        discoverable: false,
63
        defaults: {
64 65 66 67
          tocDepth: {
            min: 1,
            max: 2
          }
68 69
        },
        features: {
NGPixel's avatar
NGPixel committed
70
          browse: true,
71 72 73 74 75 76 77 78 79
          ratings: false,
          ratingsMode: 'off',
          comments: false,
          contributions: false,
          profile: true,
          search: true
        },
        logoUrl: '',
        logoText: true,
80
        sitemap: true,
81 82 83 84
        robots: {
          index: true,
          follow: true
        },
85 86 87 88
        locales: {
          primary: 'en',
          active: ['en']
        },
89 90 91
        assets: {
          logo: false,
          logoExt: 'svg',
92 93 94
          favicon: false,
          faviconExt: 'svg',
          loginBg: false
95
        },
96 97
        theme: {
          dark: false,
98
          codeBlocksTheme: 'github-dark',
99 100 101
          colorPrimary: '#1976D2',
          colorSecondary: '#02C39A',
          colorAccent: '#FF9800',
102
          colorHeader: '#000000',
103
          colorSidebar: '#1976D2',
104 105 106
          injectCSS: '',
          injectHead: '',
          injectBody: '',
107
          contentWidth: 'full',
108 109 110
          sidebarPosition: 'left',
          tocPosition: 'right',
          showSharingMenu: true,
111 112 113
          showPrintBtn: true,
          baseFont: 'roboto',
          contentFont: 'roboto'
114
        },
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
        editors: {
          asciidoc: {
            isActive: true,
            config: {}
          },
          markdown: {
            isActive: true,
            config: {
              allowHTML: true,
              kroki: false,
              krokiServerUrl: 'https://kroki.io',
              latexEngine: 'katex',
              lineBreaks: true,
              linkify: true,
              multimdTable: true,
              plantuml: false,
              plantumlServerUrl: 'https://www.plantuml.com/plantuml/',
              quotes: 'english',
              tabWidth: 2,
              typographer: false,
              underline: true
            }
          },
          wysiwyg: {
            isActive: true,
            config: {}
          }
        },
143 144 145
        uploads: {
          conflictBehavior: 'overwrite',
          normalizeFilename: true
146 147 148 149
        }
      })
    })

NGPixel's avatar
NGPixel committed
150 151 152 153 154
    WIKI.logger.debug(`Creating new root navigation for site ${newSite.id}`)

    await WIKI.db.navigation.query().insert({
      id: newSite.id,
      siteId: newSite.id,
155
      items: []
NGPixel's avatar
NGPixel committed
156 157
    })

158 159
    WIKI.logger.debug(`Creating new DB storage for site ${newSite.id}`)

160
    await WIKI.db.storage.query().insert({
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
      module: 'db',
      siteId: newSite.id,
      isEnabled: true,
      contentTypes: {
        activeTypes: ['pages', 'images', 'documents', 'others', 'large'],
        largeThreshold: '5MB'
      },
      assetDelivery: {
        streaming: true,
        directAccess: false
      },
      state: {
        current: 'ok'
      }
    })

    return newSite
  }

  static async updateSite (id, patch) {
181
    return WIKI.db.sites.query().findById(id).patch(patch)
182 183 184
  }

  static async deleteSite (id) {
185 186
    await WIKI.db.storage.query().delete().where('siteId', id)
    return WIKI.db.sites.query().deleteById(id)
187 188
  }
}