feat: convert page
This commit is contained in:
parent
d75c5532d1
commit
26f1c0f372
@ -150,6 +150,9 @@
|
|||||||
v-list-item.pl-4(@click='pageSource', v-if='mode !== `source` && hasReadSourcePermission')
|
v-list-item.pl-4(@click='pageSource', v-if='mode !== `source` && hasReadSourcePermission')
|
||||||
v-list-item-avatar(size='24', tile): v-icon(color='indigo') mdi-code-tags
|
v-list-item-avatar(size='24', tile): v-icon(color='indigo') mdi-code-tags
|
||||||
v-list-item-title.body-2 {{$t('common:header.viewSource')}}
|
v-list-item-title.body-2 {{$t('common:header.viewSource')}}
|
||||||
|
v-list-item.pl-4(@click='pageConvert', v-if='hasWritePagesPermission')
|
||||||
|
v-list-item-avatar(size='24', tile): v-icon(color='indigo') mdi-lightning-bolt
|
||||||
|
v-list-item-title.body-2 {{$t('common:header.convert')}}
|
||||||
v-list-item.pl-4(@click='pageDuplicate', v-if='hasWritePagesPermission')
|
v-list-item.pl-4(@click='pageDuplicate', v-if='hasWritePagesPermission')
|
||||||
v-list-item-avatar(size='24', tile): v-icon(color='indigo') mdi-content-duplicate
|
v-list-item-avatar(size='24', tile): v-icon(color='indigo') mdi-content-duplicate
|
||||||
v-list-item-title.body-2 {{$t('common:header.duplicate')}}
|
v-list-item-title.body-2 {{$t('common:header.duplicate')}}
|
||||||
@ -237,6 +240,7 @@
|
|||||||
page-selector(mode='move', v-model='movePageModal', :open-handler='pageMoveRename', :path='path', :locale='locale')
|
page-selector(mode='move', v-model='movePageModal', :open-handler='pageMoveRename', :path='path', :locale='locale')
|
||||||
page-selector(mode='create', v-model='duplicateOpts.modal', :open-handler='pageDuplicateHandle', :path='duplicateOpts.path', :locale='duplicateOpts.locale')
|
page-selector(mode='create', v-model='duplicateOpts.modal', :open-handler='pageDuplicateHandle', :path='duplicateOpts.path', :locale='duplicateOpts.locale')
|
||||||
page-delete(v-model='deletePageModal', v-if='path && path.length')
|
page-delete(v-model='deletePageModal', v-if='path && path.length')
|
||||||
|
page-convert(v-model='convertPageModal', v-if='path && path.length')
|
||||||
|
|
||||||
.nav-header-dev(v-if='isDevMode')
|
.nav-header-dev(v-if='isDevMode')
|
||||||
v-icon mdi-alert
|
v-icon mdi-alert
|
||||||
@ -255,7 +259,8 @@ import movePageMutation from 'gql/common/common-pages-mutation-move.gql'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
PageDelete: () => import('./page-delete.vue')
|
PageDelete: () => import('./page-delete.vue'),
|
||||||
|
PageConvert: () => import('./page-convert.vue')
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
dense: {
|
dense: {
|
||||||
@ -274,6 +279,7 @@ export default {
|
|||||||
searchAdvMenuShown: false,
|
searchAdvMenuShown: false,
|
||||||
newPageModal: false,
|
newPageModal: false,
|
||||||
movePageModal: false,
|
movePageModal: false,
|
||||||
|
convertPageModal: false,
|
||||||
deletePageModal: false,
|
deletePageModal: false,
|
||||||
locales: siteLangs,
|
locales: siteLangs,
|
||||||
isDevMode: false,
|
isDevMode: false,
|
||||||
@ -354,6 +360,9 @@ export default {
|
|||||||
this.$root.$on('pageMove', () => {
|
this.$root.$on('pageMove', () => {
|
||||||
this.pageMove()
|
this.pageMove()
|
||||||
})
|
})
|
||||||
|
this.$root.$on('pageConvert', () => {
|
||||||
|
this.pageConvert()
|
||||||
|
})
|
||||||
this.$root.$on('pageDuplicate', () => {
|
this.$root.$on('pageDuplicate', () => {
|
||||||
this.pageDuplicate()
|
this.pageDuplicate()
|
||||||
})
|
})
|
||||||
@ -416,6 +425,9 @@ export default {
|
|||||||
pageDuplicateHandle ({ locale, path }) {
|
pageDuplicateHandle ({ locale, path }) {
|
||||||
window.location.assign(`/e/${locale}/${path}?from=${this.$store.get('page/id')}`)
|
window.location.assign(`/e/${locale}/${path}?from=${this.$store.get('page/id')}`)
|
||||||
},
|
},
|
||||||
|
pageConvert () {
|
||||||
|
this.convertPageModal = true
|
||||||
|
},
|
||||||
pageMove () {
|
pageMove () {
|
||||||
this.movePageModal = true
|
this.movePageModal = true
|
||||||
},
|
},
|
||||||
|
122
client/components/common/page-convert.vue
Normal file
122
client/components/common/page-convert.vue
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<template lang='pug'>
|
||||||
|
v-dialog(
|
||||||
|
v-model='isShown'
|
||||||
|
max-width='550'
|
||||||
|
persistent
|
||||||
|
overlay-color='blue-grey darken-4'
|
||||||
|
overlay-opacity='.7'
|
||||||
|
)
|
||||||
|
v-card
|
||||||
|
.dialog-header.is-short.is-dark
|
||||||
|
v-icon.mr-2(color='white') mdi-lightning-bolt
|
||||||
|
span {{$t('common:page.convert')}}
|
||||||
|
v-card-text.pt-5
|
||||||
|
i18next.body-2(path='common:page.convertTitle', tag='div')
|
||||||
|
span.blue-grey--text.text--darken-2(place='title') {{pageTitle}}
|
||||||
|
v-select.mt-5(
|
||||||
|
:items=`[
|
||||||
|
{ value: 'markdown', text: 'Markdown' },
|
||||||
|
{ value: 'ckeditor', text: 'Visual Editor' },
|
||||||
|
{ value: 'code', text: 'Raw HTML' }
|
||||||
|
]`
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
hide-details
|
||||||
|
v-model='newEditor'
|
||||||
|
)
|
||||||
|
.caption.mt-5 {{$t('common:page.convertSubtitle')}}
|
||||||
|
v-card-chin
|
||||||
|
v-spacer
|
||||||
|
v-btn(text, @click='discard', :disabled='loading') {{$t('common:actions.cancel')}}
|
||||||
|
v-btn.px-4(color='grey darken-3', @click='convertPage', :loading='loading').white--text {{$t('common:actions.convert')}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import _ from 'lodash'
|
||||||
|
import { get } from 'vuex-pathify'
|
||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false,
|
||||||
|
newEditor: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isShown: {
|
||||||
|
get() { return this.value },
|
||||||
|
set(val) { this.$emit('input', val) }
|
||||||
|
},
|
||||||
|
pageTitle: get('page/title'),
|
||||||
|
pagePath: get('page/path'),
|
||||||
|
pageLocale: get('page/locale'),
|
||||||
|
pageId: get('page/id'),
|
||||||
|
pageEditor: get('page/editor')
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.newEditor = this.pageEditor
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
discard() {
|
||||||
|
this.isShown = false
|
||||||
|
},
|
||||||
|
async convertPage() {
|
||||||
|
this.loading = true
|
||||||
|
this.$store.commit(`loadingStart`, 'page-convert')
|
||||||
|
this.$nextTick(async () => {
|
||||||
|
try {
|
||||||
|
const resp = await this.$apollo.mutate({
|
||||||
|
mutation: gql`
|
||||||
|
mutation (
|
||||||
|
$id: Int!
|
||||||
|
$editor: String!
|
||||||
|
) {
|
||||||
|
pages {
|
||||||
|
convert(
|
||||||
|
id: $id
|
||||||
|
editor: $editor
|
||||||
|
) {
|
||||||
|
responseResult {
|
||||||
|
succeeded
|
||||||
|
errorCode
|
||||||
|
slug
|
||||||
|
message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
id: this.pageId,
|
||||||
|
editor: this.newEditor
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (_.get(resp, 'data.pages.convert.responseResult.succeeded', false)) {
|
||||||
|
this.isShown = false
|
||||||
|
_.delay(() => {
|
||||||
|
window.location.assign(`/e/${this.pageLocale}/${this.pagePath}`)
|
||||||
|
}, 400)
|
||||||
|
} else {
|
||||||
|
throw new Error(_.get(resp, 'data.pages.convert.responseResult.message', this.$t('common:error.unexpected')))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
this.$store.commit('pushGraphError', err)
|
||||||
|
}
|
||||||
|
this.$store.commit(`loadingStop`, 'page-convert')
|
||||||
|
this.loading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang='scss'>
|
||||||
|
|
||||||
|
</style>
|
@ -14,6 +14,7 @@ const state = {
|
|||||||
tags: [],
|
tags: [],
|
||||||
title: '',
|
title: '',
|
||||||
updatedAt: '',
|
updatedAt: '',
|
||||||
|
editor: '',
|
||||||
mode: '',
|
mode: '',
|
||||||
scriptJs: '',
|
scriptJs: '',
|
||||||
scriptCss: '',
|
scriptCss: '',
|
||||||
|
@ -234,6 +234,18 @@
|
|||||||
)
|
)
|
||||||
v-icon(size='20') mdi-code-tags
|
v-icon(size='20') mdi-code-tags
|
||||||
span {{$t('common:header.viewSource')}}
|
span {{$t('common:header.viewSource')}}
|
||||||
|
v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasWritePagesPermission')
|
||||||
|
template(v-slot:activator='{ on }')
|
||||||
|
v-btn(
|
||||||
|
fab
|
||||||
|
small
|
||||||
|
color='white'
|
||||||
|
light
|
||||||
|
v-on='on'
|
||||||
|
@click='pageConvert'
|
||||||
|
)
|
||||||
|
v-icon(size='20') mdi-lightning-bolt
|
||||||
|
span {{$t('common:header.convert')}}
|
||||||
v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasWritePagesPermission')
|
v-tooltip(:right='$vuetify.rtl', :left='!$vuetify.rtl', v-if='hasWritePagesPermission')
|
||||||
template(v-slot:activator='{ on }')
|
template(v-slot:activator='{ on }')
|
||||||
v-btn(
|
v-btn(
|
||||||
@ -314,7 +326,7 @@ import _ from 'lodash'
|
|||||||
import ClipboardJS from 'clipboard'
|
import ClipboardJS from 'clipboard'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
Vue.component('tabset', Tabset)
|
Vue.component('Tabset', Tabset)
|
||||||
|
|
||||||
Prism.plugins.autoloader.languages_path = '/_assets/js/prism/'
|
Prism.plugins.autoloader.languages_path = '/_assets/js/prism/'
|
||||||
Prism.plugins.NormalizeWhitespace.setDefaults({
|
Prism.plugins.NormalizeWhitespace.setDefaults({
|
||||||
@ -397,6 +409,10 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
},
|
||||||
|
editor: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
isPublished: {
|
isPublished: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -516,6 +532,7 @@ export default {
|
|||||||
this.$store.set('page/path', this.path)
|
this.$store.set('page/path', this.path)
|
||||||
this.$store.set('page/tags', this.tags)
|
this.$store.set('page/tags', this.tags)
|
||||||
this.$store.set('page/title', this.title)
|
this.$store.set('page/title', this.title)
|
||||||
|
this.$store.set('page/editor', this.editor)
|
||||||
this.$store.set('page/updatedAt', this.updatedAt)
|
this.$store.set('page/updatedAt', this.updatedAt)
|
||||||
if (this.effectivePermissions) {
|
if (this.effectivePermissions) {
|
||||||
this.$store.set('page/effectivePermissions', JSON.parse(Buffer.from(this.effectivePermissions, 'base64').toString()))
|
this.$store.set('page/effectivePermissions', JSON.parse(Buffer.from(this.effectivePermissions, 'base64').toString()))
|
||||||
@ -597,6 +614,9 @@ export default {
|
|||||||
pageSource () {
|
pageSource () {
|
||||||
this.$root.$emit('pageSource')
|
this.$root.$emit('pageSource')
|
||||||
},
|
},
|
||||||
|
pageConvert () {
|
||||||
|
this.$root.$emit('pageConvert')
|
||||||
|
},
|
||||||
pageDuplicate () {
|
pageDuplicate () {
|
||||||
this.$root.$emit('pageDuplicate')
|
this.$root.$emit('pageDuplicate')
|
||||||
},
|
},
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
"@aoberoi/passport-slack": "1.0.5",
|
"@aoberoi/passport-slack": "1.0.5",
|
||||||
"@azure/storage-blob": "12.2.1",
|
"@azure/storage-blob": "12.2.1",
|
||||||
"@exlinc/keycloak-passport": "1.0.2",
|
"@exlinc/keycloak-passport": "1.0.2",
|
||||||
|
"@joplin/turndown-plugin-gfm": "1.0.27",
|
||||||
"@root/csr": "0.8.1",
|
"@root/csr": "0.8.1",
|
||||||
"@root/keypairs": "0.10.1",
|
"@root/keypairs": "0.10.1",
|
||||||
"@root/pem": "1.0.4",
|
"@root/pem": "1.0.4",
|
||||||
@ -176,6 +177,7 @@
|
|||||||
"striptags": "3.1.1",
|
"striptags": "3.1.1",
|
||||||
"subscriptions-transport-ws": "0.9.18",
|
"subscriptions-transport-ws": "0.9.18",
|
||||||
"tar-fs": "2.1.0",
|
"tar-fs": "2.1.0",
|
||||||
|
"turndown": "7.0.0",
|
||||||
"twemoji": "13.0.1",
|
"twemoji": "13.0.1",
|
||||||
"uslug": "1.0.4",
|
"uslug": "1.0.4",
|
||||||
"uuid": "8.3.1",
|
"uuid": "8.3.1",
|
||||||
|
@ -398,6 +398,22 @@ module.exports = {
|
|||||||
return graphHelper.generateError(err)
|
return graphHelper.generateError(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* CONVERT PAGE
|
||||||
|
*/
|
||||||
|
async convert(obj, args, context) {
|
||||||
|
try {
|
||||||
|
await WIKI.models.pages.convertPage({
|
||||||
|
...args,
|
||||||
|
user: context.req.user
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
responseResult: graphHelper.generateSuccess('Page has been converted.')
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return graphHelper.generateError(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* MOVE PAGE
|
* MOVE PAGE
|
||||||
*/
|
*/
|
||||||
|
@ -112,6 +112,11 @@ type PageMutation {
|
|||||||
title: String
|
title: String
|
||||||
): PageResponse @auth(requires: ["write:pages", "manage:pages", "manage:system"])
|
): PageResponse @auth(requires: ["write:pages", "manage:pages", "manage:system"])
|
||||||
|
|
||||||
|
convert(
|
||||||
|
id: Int!
|
||||||
|
editor: String!
|
||||||
|
): DefaultResponse @auth(requires: ["write:pages", "manage:pages", "manage:system"])
|
||||||
|
|
||||||
move(
|
move(
|
||||||
id: Int!
|
id: Int!
|
||||||
destinationPath: String!
|
destinationPath: String!
|
||||||
|
@ -9,6 +9,9 @@ const striptags = require('striptags')
|
|||||||
const emojiRegex = require('emoji-regex')
|
const emojiRegex = require('emoji-regex')
|
||||||
const he = require('he')
|
const he = require('he')
|
||||||
const CleanCSS = require('clean-css')
|
const CleanCSS = require('clean-css')
|
||||||
|
const TurndownService = require('turndown')
|
||||||
|
const turndownPluginGfm = require('@joplin/turndown-plugin-gfm').gfm
|
||||||
|
const cheerio = require('cheerio')
|
||||||
|
|
||||||
/* global WIKI */
|
/* global WIKI */
|
||||||
|
|
||||||
@ -140,6 +143,7 @@ module.exports = class Page extends Model {
|
|||||||
creatorId: 'uint',
|
creatorId: 'uint',
|
||||||
creatorName: 'string',
|
creatorName: 'string',
|
||||||
description: 'string',
|
description: 'string',
|
||||||
|
editorKey: 'string',
|
||||||
isPrivate: 'boolean',
|
isPrivate: 'boolean',
|
||||||
isPublished: 'boolean',
|
isPublished: 'boolean',
|
||||||
publishEndDate: 'string',
|
publishEndDate: 'string',
|
||||||
@ -471,6 +475,134 @@ module.exports = class Page extends Model {
|
|||||||
return page
|
return page
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an Existing Page
|
||||||
|
*
|
||||||
|
* @param {Object} opts Page Properties
|
||||||
|
* @returns {Promise} Promise of the Page Model Instance
|
||||||
|
*/
|
||||||
|
static async convertPage(opts) {
|
||||||
|
// -> Fetch original page
|
||||||
|
const ogPage = await WIKI.models.pages.query().findById(opts.id)
|
||||||
|
if (!ogPage) {
|
||||||
|
throw new Error('Invalid Page Id')
|
||||||
|
}
|
||||||
|
|
||||||
|
// -> Check for page access
|
||||||
|
if (!WIKI.auth.checkAccess(opts.user, ['write:pages'], {
|
||||||
|
locale: ogPage.localeCode,
|
||||||
|
path: ogPage.path
|
||||||
|
})) {
|
||||||
|
throw new WIKI.Error.PageUpdateForbidden()
|
||||||
|
}
|
||||||
|
|
||||||
|
// -> Check content type
|
||||||
|
const sourceContentType = ogPage.contentType
|
||||||
|
const targetContentType = _.get(_.find(WIKI.data.editors, ['key', opts.editor]), `contentType`, 'text')
|
||||||
|
const shouldConvert = sourceContentType !== targetContentType
|
||||||
|
let convertedContent = null
|
||||||
|
|
||||||
|
// -> Convert content
|
||||||
|
if (shouldConvert) {
|
||||||
|
// -> Markdown => HTML
|
||||||
|
if (sourceContentType === 'markdown' && targetContentType === 'html') {
|
||||||
|
if (!ogPage.render) {
|
||||||
|
throw new Error('Aborted conversion because rendered page content is empty!')
|
||||||
|
}
|
||||||
|
convertedContent = ogPage.render
|
||||||
|
|
||||||
|
const $ = cheerio.load(convertedContent, {
|
||||||
|
decodeEntities: true
|
||||||
|
})
|
||||||
|
|
||||||
|
if ($.root().children().length > 0) {
|
||||||
|
$('.toc-anchor').remove()
|
||||||
|
|
||||||
|
convertedContent = $.html('body').replace('<body>', '').replace('</body>', '').replace(/&#x([0-9a-f]{1,6});/ig, (entity, code) => {
|
||||||
|
code = parseInt(code, 16)
|
||||||
|
|
||||||
|
// Don't unescape ASCII characters, assuming they're encoded for a good reason
|
||||||
|
if (code < 0x80) return entity
|
||||||
|
|
||||||
|
return String.fromCodePoint(code)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// -> HTML => Markdown
|
||||||
|
} else if (sourceContentType === 'html' && targetContentType === 'markdown') {
|
||||||
|
const td = new TurndownService({
|
||||||
|
bulletListMarker: '-',
|
||||||
|
codeBlockStyle: 'fenced',
|
||||||
|
emDelimiter: '*',
|
||||||
|
fence: '```',
|
||||||
|
headingStyle: 'atx',
|
||||||
|
hr: '---',
|
||||||
|
linkStyle: 'inlined',
|
||||||
|
preformattedCode: true,
|
||||||
|
strongDelimiter: '**'
|
||||||
|
})
|
||||||
|
|
||||||
|
td.use(turndownPluginGfm)
|
||||||
|
|
||||||
|
td.keep(['kbd'])
|
||||||
|
|
||||||
|
td.addRule('subscript', {
|
||||||
|
filter: ['sub'],
|
||||||
|
replacement: c => `~${c}~`
|
||||||
|
})
|
||||||
|
|
||||||
|
td.addRule('superscript', {
|
||||||
|
filter: ['sup'],
|
||||||
|
replacement: c => `^${c}^`
|
||||||
|
})
|
||||||
|
|
||||||
|
td.addRule('underline', {
|
||||||
|
filter: ['u'],
|
||||||
|
replacement: c => `_${c}_`
|
||||||
|
})
|
||||||
|
|
||||||
|
td.addRule('removeTocAnchors', {
|
||||||
|
filter: (n, o) => {
|
||||||
|
return n.nodeName === 'A' && n.classList.contains('toc-anchor')
|
||||||
|
},
|
||||||
|
replacement: c => ''
|
||||||
|
})
|
||||||
|
|
||||||
|
convertedContent = td.turndown(ogPage.content)
|
||||||
|
// -> Unsupported
|
||||||
|
} else {
|
||||||
|
throw new Error('Unsupported source / destination content types combination.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -> Create version snapshot
|
||||||
|
if (shouldConvert) {
|
||||||
|
await WIKI.models.pageHistory.addVersion({
|
||||||
|
...ogPage,
|
||||||
|
isPublished: ogPage.isPublished === true || ogPage.isPublished === 1,
|
||||||
|
action: 'updated',
|
||||||
|
versionDate: ogPage.updatedAt
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// -> Update page
|
||||||
|
await WIKI.models.pages.query().patch({
|
||||||
|
contentType: targetContentType,
|
||||||
|
editorKey: opts.editor,
|
||||||
|
...(convertedContent ? { content: convertedContent } : {})
|
||||||
|
}).where('id', ogPage.id)
|
||||||
|
const page = await WIKI.models.pages.getPageFromDb(ogPage.id)
|
||||||
|
|
||||||
|
await WIKI.models.pages.deletePageFromCache(page.hash)
|
||||||
|
WIKI.events.outbound.emit('deletePageFromCache', page.hash)
|
||||||
|
|
||||||
|
// -> Update on Storage
|
||||||
|
await WIKI.models.storage.pageEvent({
|
||||||
|
event: 'updated',
|
||||||
|
page
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move a Page
|
* Move a Page
|
||||||
*
|
*
|
||||||
@ -872,6 +1004,7 @@ module.exports = class Page extends Model {
|
|||||||
creatorId: page.creatorId,
|
creatorId: page.creatorId,
|
||||||
creatorName: page.creatorName,
|
creatorName: page.creatorName,
|
||||||
description: page.description,
|
description: page.description,
|
||||||
|
editorKey: page.editorKey,
|
||||||
extra: {
|
extra: {
|
||||||
css: _.get(page, 'extra.css', ''),
|
css: _.get(page, 'extra.css', ''),
|
||||||
js: _.get(page, 'extra.js', '')
|
js: _.get(page, 'extra.js', '')
|
||||||
|
@ -20,6 +20,7 @@ block body
|
|||||||
updated-at=page.updatedAt
|
updated-at=page.updatedAt
|
||||||
author-name=page.authorName
|
author-name=page.authorName
|
||||||
:author-id=page.authorId
|
:author-id=page.authorId
|
||||||
|
editor=page.editorKey
|
||||||
:is-published=page.isPublished.toString()
|
:is-published=page.isPublished.toString()
|
||||||
toc=Buffer.from(page.toc).toString('base64')
|
toc=Buffer.from(page.toc).toString('base64')
|
||||||
:page-id=page.id
|
:page-id=page.id
|
||||||
|
17
yarn.lock
17
yarn.lock
@ -3220,6 +3220,11 @@
|
|||||||
"@types/yargs" "^15.0.0"
|
"@types/yargs" "^15.0.0"
|
||||||
chalk "^4.0.0"
|
chalk "^4.0.0"
|
||||||
|
|
||||||
|
"@joplin/turndown-plugin-gfm@1.0.27":
|
||||||
|
version "1.0.27"
|
||||||
|
resolved "https://registry.yarnpkg.com/@joplin/turndown-plugin-gfm/-/turndown-plugin-gfm-1.0.27.tgz#15ae15c169b88a355647065e7502f6619f0ace46"
|
||||||
|
integrity sha512-4BPgTSkhvxPI3tbjG4BPiBq0VuNZji1Y77DRWHb09GnzsrgwBI+gpo3EI6obkyIeRuN/03wzf98W5u1iau2vpQ==
|
||||||
|
|
||||||
"@kwsites/file-exists@^1.1.1":
|
"@kwsites/file-exists@^1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99"
|
resolved "https://registry.yarnpkg.com/@kwsites/file-exists/-/file-exists-1.1.1.tgz#ad1efcac13e1987d8dbaf235ef3be5b0d96faa99"
|
||||||
@ -8277,6 +8282,11 @@ domhandler@^2.3.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "1"
|
domelementtype "1"
|
||||||
|
|
||||||
|
domino@^2.1.6:
|
||||||
|
version "2.1.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.6.tgz#fe4ace4310526e5e7b9d12c7de01b7f485a57ffe"
|
||||||
|
integrity sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==
|
||||||
|
|
||||||
dompurify@2.2.0:
|
dompurify@2.2.0:
|
||||||
version "2.2.0"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.0.tgz#51d34e76faa38b5d6b4e83a0678530f27fe3965c"
|
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.0.tgz#51d34e76faa38b5d6b4e83a0678530f27fe3965c"
|
||||||
@ -18405,6 +18415,13 @@ tunnel@0.0.6, tunnel@^0.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
|
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
|
||||||
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
|
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
|
||||||
|
|
||||||
|
turndown@7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/turndown/-/turndown-7.0.0.tgz#19b2a6a2d1d700387a1e07665414e4af4fec5225"
|
||||||
|
integrity sha512-G1FfxfR0mUNMeGjszLYl3kxtopC4O9DRRiMlMDDVHvU1jaBkGFg4qxIyjIk2aiKLHyDyZvZyu4qBO2guuYBy3Q==
|
||||||
|
dependencies:
|
||||||
|
domino "^2.1.6"
|
||||||
|
|
||||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||||
version "0.14.5"
|
version "0.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user