feat(admin): export tool for full migration / backup (#5294)
* feat: export content utility (wip) * feat: export navigation + groups + users * feat: export comments + navigation + pages + pages history + settings * feat: export assets
This commit is contained in:
		| @@ -41,6 +41,14 @@ module.exports = { | ||||
|         ext.isCompatible = await WIKI.extensions.ext[ext.key].isCompatible() | ||||
|       } | ||||
|       return exts | ||||
|     }, | ||||
|     async exportStatus () { | ||||
|       return { | ||||
|         status: WIKI.system.exportStatus.status, | ||||
|         progress: Math.ceil(WIKI.system.exportStatus.progress), | ||||
|         message: WIKI.system.exportStatus.message, | ||||
|         startedAt: WIKI.system.exportStatus.startedAt | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   SystemMutation: { | ||||
| @@ -260,6 +268,39 @@ module.exports = { | ||||
|       } catch (err) { | ||||
|         return graphHelper.generateError(err) | ||||
|       } | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|      * Export Wiki to Disk | ||||
|      */ | ||||
|     async export (obj, args, context) { | ||||
|       try { | ||||
|         const desiredPath = path.resolve(WIKI.ROOTPATH, args.path) | ||||
|         // -> Check if export process is already running | ||||
|         if (WIKI.system.exportStatus.status === 'running') { | ||||
|           throw new Error('Another export is already running.') | ||||
|         } | ||||
|         // -> Validate entities | ||||
|         if (args.entities.length < 1) { | ||||
|           throw new Error('Must specify at least 1 entity to export.') | ||||
|         } | ||||
|         // -> Check target path | ||||
|         await fs.ensureDir(desiredPath) | ||||
|         const existingFiles = await fs.readdir(desiredPath) | ||||
|         if (existingFiles.length) { | ||||
|           throw new Error('Target directory must be empty!') | ||||
|         } | ||||
|         // -> Start export | ||||
|         WIKI.system.export({ | ||||
|           entities: args.entities, | ||||
|           path: desiredPath | ||||
|         }) | ||||
|         return { | ||||
|           responseResult: graphHelper.generateSuccess('Export started successfully.') | ||||
|         } | ||||
|       } catch (err) { | ||||
|         return graphHelper.generateError(err) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   SystemInfo: { | ||||
|   | ||||
| @@ -17,7 +17,8 @@ extend type Mutation { | ||||
| type SystemQuery { | ||||
|   flags: [SystemFlag] @auth(requires: ["manage:system"]) | ||||
|   info: SystemInfo | ||||
|   extensions: [SystemExtension]! @auth(requires: ["manage:system"]) | ||||
|   extensions: [SystemExtension] @auth(requires: ["manage:system"]) | ||||
|   exportStatus: SystemExportStatus @auth(requires: ["manage:system"]) | ||||
| } | ||||
|  | ||||
| # ----------------------------------------------- | ||||
| @@ -47,6 +48,11 @@ type SystemMutation { | ||||
|   ): DefaultResponse @auth(requires: ["manage:system"]) | ||||
|  | ||||
|   renewHTTPSCertificate: DefaultResponse @auth(requires: ["manage:system"]) | ||||
|  | ||||
|   export( | ||||
|     entities: [String]! | ||||
|     path: String! | ||||
|   ): DefaultResponse @auth(requires: ["manage:system"]) | ||||
| } | ||||
|  | ||||
| # ----------------------------------------------- | ||||
| @@ -121,3 +127,10 @@ type SystemExtension { | ||||
|   isInstalled: Boolean! | ||||
|   isCompatible: Boolean! | ||||
| } | ||||
|  | ||||
| type SystemExportStatus { | ||||
|   status: String | ||||
|   progress: Int | ||||
|   message: String | ||||
|   startedAt: Date | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user