| 
					
				 | 
			
			
				@@ -2,6 +2,11 @@ const path = require('path') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const sgit = require('simple-git/promise') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const fs = require('fs-extra') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const _ = require('lodash') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const stream = require('stream') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const Promise = require('bluebird') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const pipeline = Promise.promisify(stream.pipeline) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const klaw = require('klaw') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+const pageHelper = require('../../../helpers/page.js') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 const localeFolderRegex = /^([a-z]{2}(?:-[a-z]{2})?\/)?(.*)/i 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -154,66 +159,74 @@ module.exports = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       const diff = await this.git.diffSummary(['-M', currentCommitLog.hash, latestCommitLog.hash]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       if (_.get(diff, 'files', []).length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (const item of diff.files) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const contentType = getContenType(item.file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (!contentType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          const contentPath = getPagePath(item.file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        await this.processFiles(diff.files) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Process Files 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @param {Array<String>} files Array of files to process 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  async processFiles(files) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (const item of files) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const contentType = getContenType(item.file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!contentType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const contentPath = getPagePath(item.file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          let itemContents = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            itemContents = await fs.readFile(path.join(this.repoPath, item.file), 'utf8') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const pageData = WIKI.models.pages.parseMetadata(itemContents, contentType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            const currentPage = await WIKI.models.pages.query().findOne({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              path: contentPath.path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              localeCode: contentPath.locale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (currentPage) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // Already in the DB, can mark as modified 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              WIKI.logger.info(`(STORAGE/GIT) Page marked as modified: ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              await WIKI.models.pages.updatePage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                id: currentPage.id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                title: _.get(pageData, 'title', currentPage.title), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                description: _.get(pageData, 'description', currentPage.description), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                isPublished: _.get(pageData, 'isPublished', currentPage.isPublished), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                isPrivate: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                content: pageData.content, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                authorId: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                skipStorage: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // Not in the DB, can mark as new 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              WIKI.logger.info(`(STORAGE/GIT) Page marked as new: ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              const pageEditor = await WIKI.models.editors.getDefaultEditor(contentType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              await WIKI.models.pages.createPage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                path: contentPath.path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                locale: contentPath.locale, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                title: _.get(pageData, 'title', _.last(contentPath.path.split('/'))), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                description: _.get(pageData, 'description', ''), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                isPublished: _.get(pageData, 'isPublished', true), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                isPrivate: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                content: pageData.content, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                authorId: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                editor: pageEditor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                skipStorage: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (err.code === 'ENOENT' && item.deletions > 0 && item.insertions === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // File was deleted by git, can safely mark as deleted in DB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              WIKI.logger.info(`(STORAGE/GIT) Page marked as deleted: ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      let itemContents = '' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        itemContents = await fs.readFile(path.join(this.repoPath, item.file), 'utf8') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const pageData = WIKI.models.pages.parseMetadata(itemContents, contentType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const currentPage = await WIKI.models.pages.query().findOne({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          path: contentPath.path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          localeCode: contentPath.locale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (currentPage) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Already in the DB, can mark as modified 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WIKI.logger.info(`(STORAGE/GIT) Page marked as modified: ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          await WIKI.models.pages.updatePage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            id: currentPage.id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            title: _.get(pageData, 'title', currentPage.title), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            description: _.get(pageData, 'description', currentPage.description), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isPublished: _.get(pageData, 'isPublished', currentPage.isPublished), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isPrivate: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            content: pageData.content, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            authorId: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            skipStorage: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Not in the DB, can mark as new 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WIKI.logger.info(`(STORAGE/GIT) Page marked as new: ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const pageEditor = await WIKI.models.editors.getDefaultEditor(contentType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          await WIKI.models.pages.createPage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            path: contentPath.path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            locale: contentPath.locale, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            title: _.get(pageData, 'title', _.last(contentPath.path.split('/'))), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            description: _.get(pageData, 'description', ''), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isPublished: _.get(pageData, 'isPublished', true), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            isPrivate: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            content: pageData.content, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            authorId: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            editor: pageEditor, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            skipStorage: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } catch (err) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (err.code === 'ENOENT' && item.deletions > 0 && item.insertions === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // File was deleted by git, can safely mark as deleted in DB 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WIKI.logger.info(`(STORAGE/GIT) Page marked as deleted: ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              await WIKI.models.pages.deletePage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                path: contentPath.path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                locale: contentPath.locale, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                skipStorage: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              WIKI.logger.warn(`(STORAGE/GIT) Failed to open ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              WIKI.logger.warn(err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          await WIKI.models.pages.deletePage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            path: contentPath.path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            locale: contentPath.locale, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            skipStorage: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WIKI.logger.warn(`(STORAGE/GIT) Failed to open ${item.file}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WIKI.logger.warn(err) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -278,5 +291,56 @@ module.exports = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     await this.git.commit(`docs: rename ${page.sourcePath} to ${destinationFilePath}`, destinationFilePath, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       '--author': `"${page.authorName} <${page.authorEmail}>"` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * HANDLERS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  async importAll() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    WIKI.logger.info(`(STORAGE/GIT) Importing all content from local Git repo to the DB...`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    await pipeline( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      klaw(this.repoPath, { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        filter: (f) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return !_.includes(f, '.git') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      new stream.Transform({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        objectMode: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transform: async (file, enc, cb) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const relPath = file.path.substr(this.repoPath.length + 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (relPath && relPath.length > 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            WIKI.logger.info(`(STORAGE/GIT) Processing ${relPath}...`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await this.processFiles([{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              file: relPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              deletions: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              insertions: 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cb() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    WIKI.logger.info('(STORAGE/GIT) Import completed.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  async syncUntracked() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    WIKI.logger.info(`(STORAGE/GIT) Adding all untracked content...`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    await pipeline( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt').select().from('pages').where({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        isPrivate: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }).stream(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      new stream.Transform({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        objectMode: true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transform: async (page, enc, cb) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const fileName = `${page.path}.${getFileExtension(page.contentType)}` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          WIKI.logger.info(`(STORAGE/GIT) Adding ${fileName}...`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          const filePath = path.join(this.repoPath, fileName) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          await fs.outputFile(filePath, pageHelper.injectPageMetadata(page), 'utf8') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          await this.git.add(`./${fileName}`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cb() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    await this.git.commit(`docs: add all untracked content`) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    WIKI.logger.info('(STORAGE/GIT) All content is now tracked.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |