sites.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { Model } from 'objection'
  2. import { defaultsDeep, keyBy } from 'lodash-es'
  3. import { v4 as uuid } from 'uuid'
  4. /**
  5. * Site model
  6. */
  7. export class Site extends Model {
  8. static get tableName () { return 'sites' }
  9. static get jsonSchema () {
  10. return {
  11. type: 'object',
  12. required: ['hostname'],
  13. properties: {
  14. id: { type: 'string' },
  15. hostname: { type: 'string' },
  16. isEnabled: { type: 'boolean', default: false }
  17. }
  18. }
  19. }
  20. static get jsonAttributes () {
  21. return ['config']
  22. }
  23. static async getSiteByHostname ({ hostname, forceReload = false }) {
  24. if (forceReload) {
  25. await WIKI.db.sites.reloadCache()
  26. }
  27. const siteId = WIKI.sitesMappings[hostname] || WIKI.sitesMappings['*']
  28. if (siteId) {
  29. return WIKI.sites[siteId]
  30. }
  31. return null
  32. }
  33. static async reloadCache () {
  34. WIKI.logger.info('Reloading site configurations...')
  35. const sites = await WIKI.db.sites.query().orderBy('id')
  36. WIKI.sites = keyBy(sites, 'id')
  37. WIKI.sitesMappings = {}
  38. for (const site of sites) {
  39. WIKI.sitesMappings[site.hostname] = site.id
  40. }
  41. WIKI.logger.info(`Loaded ${sites.length} site configurations [ OK ]`)
  42. }
  43. static async createSite (hostname, config) {
  44. const newSiteId = uuid
  45. const newDefaultNav = await WIKI.db.navigation.query().insertAndFetch({
  46. name: 'Default',
  47. siteId: newSiteId,
  48. items: JSON.stringify([])
  49. })
  50. const newSite = await WIKI.db.sites.query().insertAndFetch({
  51. id: newSiteId,
  52. hostname,
  53. isEnabled: true,
  54. config: defaultsDeep(config, {
  55. title: 'My Wiki Site',
  56. description: '',
  57. company: '',
  58. contentLicense: '',
  59. footerExtra: '',
  60. pageExtensions: ['md', 'html', 'txt'],
  61. pageCasing: true,
  62. discoverable: false,
  63. defaults: {
  64. tocDepth: {
  65. min: 1,
  66. max: 2
  67. }
  68. },
  69. features: {
  70. ratings: false,
  71. ratingsMode: 'off',
  72. comments: false,
  73. contributions: false,
  74. profile: true,
  75. search: true
  76. },
  77. logoUrl: '',
  78. logoText: true,
  79. sitemap: true,
  80. robots: {
  81. index: true,
  82. follow: true
  83. },
  84. locales: {
  85. primary: 'en',
  86. active: ['en']
  87. },
  88. assets: {
  89. logo: false,
  90. logoExt: 'svg',
  91. favicon: false,
  92. faviconExt: 'svg',
  93. loginBg: false
  94. },
  95. theme: {
  96. dark: false,
  97. codeBlocksTheme: 'github-dark',
  98. colorPrimary: '#1976D2',
  99. colorSecondary: '#02C39A',
  100. colorAccent: '#FF9800',
  101. colorHeader: '#000000',
  102. colorSidebar: '#1976D2',
  103. injectCSS: '',
  104. injectHead: '',
  105. injectBody: '',
  106. contentWidth: 'full',
  107. sidebarPosition: 'left',
  108. tocPosition: 'right',
  109. showSharingMenu: true,
  110. showPrintBtn: true,
  111. baseFont: 'roboto',
  112. contentFont: 'roboto'
  113. },
  114. editors: {
  115. asciidoc: {
  116. isActive: true,
  117. config: {}
  118. },
  119. markdown: {
  120. isActive: true,
  121. config: {
  122. allowHTML: true,
  123. kroki: false,
  124. krokiServerUrl: 'https://kroki.io',
  125. latexEngine: 'katex',
  126. lineBreaks: true,
  127. linkify: true,
  128. multimdTable: true,
  129. plantuml: false,
  130. plantumlServerUrl: 'https://www.plantuml.com/plantuml/',
  131. quotes: 'english',
  132. tabWidth: 2,
  133. typographer: false,
  134. underline: true
  135. }
  136. },
  137. wysiwyg: {
  138. isActive: true,
  139. config: {}
  140. }
  141. },
  142. nav: {
  143. mode: 'mixed',
  144. defaultId: newDefaultNav.id,
  145. },
  146. uploads: {
  147. conflictBehavior: 'overwrite',
  148. normalizeFilename: true
  149. }
  150. })
  151. })
  152. WIKI.logger.debug(`Creating new DB storage for site ${newSite.id}`)
  153. await WIKI.db.storage.query().insert({
  154. module: 'db',
  155. siteId: newSite.id,
  156. isEnabled: true,
  157. contentTypes: {
  158. activeTypes: ['pages', 'images', 'documents', 'others', 'large'],
  159. largeThreshold: '5MB'
  160. },
  161. assetDelivery: {
  162. streaming: true,
  163. directAccess: false
  164. },
  165. state: {
  166. current: 'ok'
  167. }
  168. })
  169. return newSite
  170. }
  171. static async updateSite (id, patch) {
  172. return WIKI.db.sites.query().findById(id).patch(patch)
  173. }
  174. static async deleteSite (id) {
  175. await WIKI.db.storage.query().delete().where('siteId', id)
  176. return WIKI.db.sites.query().deleteById(id)
  177. }
  178. }