Commit e1382771 authored by NGPixel's avatar NGPixel Committed by Nicolas Giard

feat: extensions check + resolver

parent abc9e4e1
......@@ -17,7 +17,7 @@
v-expansion-panel-header(disable-icon-rotate)
span {{ext.title}}
template(v-slot:actions)
v-chip(label, color='success', small, v-if='ext.installed') Installed
v-chip(label, color='success', small, v-if='ext.isInstalled') Installed
v-chip(label, color='warning', small, v-else) Not Installed
v-expansion-panel-content.pa-0
v-card(flat, :class='$vuetify.theme.dark ? `grey darken-3` : `grey lighten-5`', tile)
......@@ -25,18 +25,15 @@
.body-2 {{ext.description}}
v-divider.my-4
.body-2
strong.mr-3 Supported Platforms:
v-chip.mr-1(label, small, :color='ext.platforms[`linux-amd64`] ? `success` : `error`') Linux (x64)
v-chip.mr-1(label, small, :color='ext.platforms[`linux-arm64`] ? `success` : `error`') Linux (arm64)
v-chip.mr-1(label, small, :color='ext.platforms[`linux-armv7`] ? `success` : `error`') Linux (armv7)
v-chip.mr-1(label, small, :color='ext.platforms.macos ? `success` : `error`') MacOS
v-chip.mr-1(label, small, :color='ext.platforms.windows ? `success` : `error`') Windows
strong.mr-2 This extensions is
v-chip.mr-2(v-if='ext.isCompatible', label, outlined, small, color='success') compatible
v-chip.mr-2(v-else, label, small, color='error') not compatible
strong with your host.
v-card-chin
v-spacer
v-btn(disabled)
v-icon(left) mdi-plus
span Install
</template>
<script>
......@@ -46,122 +43,70 @@ import gql from 'graphql-tag'
export default {
data() {
return {
config: {},
extensions: [
{
key: 'git',
title: 'Git',
description: 'Distributed version control system. Required for the Git storage module.',
platforms: {
'linux-amd64': true,
'linux-arm64': true,
'linux-armv7': true,
'macos': true,
'windows': true
},
installed: true
},
{
key: 'pandoc',
title: 'Pandoc',
description: 'Convert between markup formats. Required for converting from other formats such as MediaWiki, AsciiDoc, Textile and other wikis.',
platforms: {
'linux-amd64': true,
'linux-arm64': false,
'linux-armv7': false,
'macos': true,
'windows': true
},
installed: false
},
{
key: 'puppeteer',
title: 'Puppeteer',
description: 'Headless chromium browser for server-side rendering. Required for generating PDF versions of pages and render content elements on the server (e.g. Mermaid diagrams)',
platforms: {
'linux-amd64': true,
'linux-arm64': false,
'linux-armv7': false,
'macos': true,
'windows': true
},
installed: false
},
{
key: 'sharp',
title: 'Sharp',
description: 'Process and transform images. Required to generate thumbnails of uploaded images and perform transformations.',
platforms: {
'linux-amd64': true,
'linux-arm64': false,
'linux-armv7': false,
'macos': true,
'windows': true
},
installed: false
extensions: []
}
]
}
},
computed: {
},
methods: {
async save () {
try {
await this.$apollo.mutate({
mutation: gql`
mutation (
$host: String!
) {
site {
updateConfig(
host: $host
) {
responseResult {
succeeded
errorCode
slug
message
// try {
// await this.$apollo.mutate({
// mutation: gql`
// mutation (
// $host: String!
// ) {
// site {
// updateConfig(
// host: $host
// ) {
// responseResult {
// succeeded
// errorCode
// slug
// message
// }
// }
// }
// }
// `,
// variables: {
// host: _.get(this.config, 'host', '')
// },
// watchLoading (isLoading) {
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-extensions-update')
// }
// })
// this.$store.commit('showNotification', {
// style: 'success',
// message: 'Configuration saved successfully.',
// icon: 'check'
// })
// } catch (err) {
// this.$store.commit('pushGraphError', err)
// }
}
},
apollo: {
extensions: {
query: gql`
{
system {
extensions {
key
title
description
isInstalled
isCompatible
}
}
}
`,
variables: {
host: _.get(this.config, 'host', '')
},
fetchPolicy: 'network-only',
update: (data) => _.cloneDeep(data.system.extensions),
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-update')
}
})
this.$store.commit('showNotification', {
style: 'success',
message: 'Configuration saved successfully.',
icon: 'check'
})
} catch (err) {
this.$store.commit('pushGraphError', err)
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-extensions-refresh')
}
}
}
// apollo: {
// config: {
// query: gql`
// {
// site {
// config {
// host
// }
// }
// }
// `,
// fetchPolicy: 'network-only',
// update: (data) => _.cloneDeep(data.site.config),
// watchLoading (isLoading) {
// this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-site-refresh')
// }
// }
// }
}
</script>
......
......@@ -19,7 +19,8 @@ const state = {
view: false,
post: false,
manage: false
}
},
commentsCount: 0
}
export default {
......
......@@ -103,10 +103,10 @@
dark
style='min-width: 50px; justify-content: center;'
)
span 334
span {{commentsCount}}
.d-flex
v-btn.text-none(
@click='goToComments'
@click='goToComments()'
:color='$vuetify.theme.dark ? `pink` : `pink darken-3`'
outlined
style='flex: 1 1 100%;'
......@@ -441,6 +441,7 @@ export default {
},
computed: {
isAuthenticated: get('user/authenticated'),
commentsCount: get('page/commentsCount'),
rating: {
get () {
return 3.5
......
......@@ -57,6 +57,7 @@
"cheerio": "1.0.0-rc.3",
"chokidar": "3.4.0",
"clean-css": "4.2.3",
"command-exists": "1.2.9",
"compression": "1.7.4",
"connect-session-knex": "1.6.0",
"cookie-parser": "1.4.5",
......@@ -162,7 +163,6 @@
"scim-query-filter-parser": "2.0.4",
"semver": "7.3.2",
"serve-favicon": "2.5.0",
"sharp": "0.25.2",
"simple-git": "2.4.0",
"solr-node": "1.2.1",
"sqlite3": "4.2.0",
......
const fs = require('fs-extra')
const path = require('path')
/* global WIKI */
module.exports = {
ext: {},
async init () {
const extDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/extensions'))
WIKI.logger.info(`Checking for installed optional extensions...`)
for (let dir of extDirs) {
WIKI.extensions.ext[dir] = require(path.join(WIKI.SERVERPATH, 'modules/extensions', dir, 'ext.js'))
const isInstalled = await WIKI.extensions.ext[dir].check()
if (isInstalled) {
WIKI.logger.info(`Optional extension ${dir} is installed. [ OK ]`)
} else {
WIKI.logger.info(`Optional extension ${dir} was not found on this system. [ SKIPPED ]`)
}
}
}
}
......@@ -40,6 +40,7 @@ module.exports = {
inbound: new EventEmitter(),
outbound: new EventEmitter()
}
WIKI.extensions = require('./extensions')
} catch (err) {
WIKI.logger.error(err)
process.exit(1)
......@@ -76,6 +77,8 @@ module.exports = {
await WIKI.models.searchEngines.refreshSearchEnginesFromDisk()
await WIKI.models.storage.refreshTargetsFromDisk()
await WIKI.extensions.init()
await WIKI.auth.activateStrategies()
await WIKI.models.commentProviders.initProvider()
await WIKI.models.searchEngines.initEngine()
......
......@@ -34,7 +34,14 @@ module.exports = {
result.push({ key, value })
}, [])
},
async info() { return {} }
async info () { return {} },
async extensions () {
const exts = Object.values(WIKI.extensions.ext).map(ext => _.pick(ext, ['key', 'title', 'description', 'isInstalled']))
for (let ext of exts) {
ext.isCompatible = await WIKI.extensions.ext[ext.key].isCompatible()
}
return exts
}
},
SystemMutation: {
async updateFlags (obj, args, context) {
......
......@@ -17,6 +17,7 @@ extend type Mutation {
type SystemQuery {
flags: [SystemFlag] @auth(requires: ["manage:system"])
info: SystemInfo
extensions: [SystemExtension]! @auth(requires: ["manage:system"])
}
# -----------------------------------------------
......@@ -112,3 +113,11 @@ type SystemImportUsersResponseFailed {
email: String
error: String
}
type SystemExtension {
key: String!
title: String!
description: String!
isInstalled: Boolean!
isCompatible: Boolean!
}
......@@ -45,9 +45,9 @@ module.exports = class CommentProvider extends Model {
const dbProviders = await WIKI.models.commentProviders.query()
// -> Fetch definitions from disk
const authDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/comments'))
const commentDirs = await fs.readdir(path.join(WIKI.SERVERPATH, 'modules/comments'))
let diskProviders = []
for (let dir of authDirs) {
for (let dir of commentDirs) {
const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/comments', dir, 'definition.yml'), 'utf8')
diskProviders.push(yaml.safeLoad(def))
}
......
const cmdExists = require('command-exists')
module.exports = {
key: 'git',
title: 'Git',
description: 'Distributed version control system. Required for the Git storage module.',
isInstalled: false,
async isCompatible () {
return true
},
async check () {
try {
await cmdExists('git')
this.isInstalled = true
} catch (err) {
this.isInstalled = false
}
return this.isInstalled
}
}
const cmdExists = require('command-exists')
const os = require('os')
module.exports = {
key: 'pandoc',
title: 'Pandoc',
description: 'Convert between markup formats. Required for converting from other formats such as MediaWiki, AsciiDoc, Textile and other wikis.',
async isCompatible () {
return os.arch() === 'x64'
},
isInstalled: false,
async check () {
try {
await cmdExists('pandoc')
this.isInstalled = true
} catch (err) {
this.isInstalled = false
}
return this.isInstalled
}
}
const cmdExists = require('command-exists')
const os = require('os')
module.exports = {
key: 'puppeteer',
title: 'Puppeteer',
description: 'Headless chromium browser for server-side rendering. Required for generating PDF versions of pages and render content elements on the server (e.g. Mermaid diagrams)',
async isCompatible () {
return os.arch() === 'x64'
},
isInstalled: false,
async check () {
try {
await cmdExists('pandoc')
this.isInstalled = true
} catch (err) {
this.isInstalled = false
}
return this.isInstalled
}
}
const fs = require('fs-extra')
const os = require('os')
const path = require('path')
/* global WIKI */
module.exports = {
key: 'sharp',
title: 'Sharp',
description: 'Process and transform images. Required to generate thumbnails of uploaded images and perform transformations.',
async isCompatible () {
return os.arch() === 'x64'
},
isInstalled: false,
async check () {
this.isInstalled = await fs.pathExists(path.join(WIKI.ROOTPATH, 'node_modules/sharp'))
return this.isInstalled
}
}
This diff was suppressed by a .gitattributes entry.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment