page.js 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. const _ = require('lodash')
  2. const graphHelper = require('../../helpers/graph')
  3. /* global WIKI */
  4. module.exports = {
  5. Query: {
  6. async pages() { return {} }
  7. },
  8. Mutation: {
  9. async pages() { return {} }
  10. },
  11. PageQuery: {
  12. /**
  13. * PAGE HISTORY
  14. */
  15. async history(obj, args, context, info) {
  16. return WIKI.models.pageHistory.getHistory({
  17. pageId: args.id,
  18. offsetPage: args.offsetPage || 0,
  19. offsetSize: args.offsetSize || 100
  20. })
  21. },
  22. /**
  23. * SEARCH PAGES
  24. */
  25. async search (obj, args, context) {
  26. if (WIKI.data.searchEngine) {
  27. const resp = await WIKI.data.searchEngine.query(args.query, args)
  28. return {
  29. ...resp,
  30. results: _.filter(resp.results, r => {
  31. return WIKI.auth.checkAccess(context.req.user, ['read:pages'], {
  32. path: r.path,
  33. locale: r.locale
  34. })
  35. })
  36. }
  37. } else {
  38. return {
  39. results: [],
  40. suggestions: [],
  41. totalHits: 0
  42. }
  43. }
  44. },
  45. /**
  46. * LIST PAGES
  47. */
  48. async list (obj, args, context, info) {
  49. let results = await WIKI.models.pages.query().column([
  50. 'pages.id',
  51. 'path',
  52. { locale: 'localeCode' },
  53. 'title',
  54. 'description',
  55. 'isPublished',
  56. 'isPrivate',
  57. 'privateNS',
  58. 'contentType',
  59. 'createdAt',
  60. 'updatedAt'
  61. ])
  62. .withGraphJoined('tags')
  63. .modifyGraph('tags', builder => {
  64. builder.select('tag')
  65. })
  66. .modify(queryBuilder => {
  67. if (args.limit) {
  68. queryBuilder.limit(args.limit)
  69. }
  70. if (args.locale) {
  71. queryBuilder.where('localeCode', args.locale)
  72. }
  73. if (args.tags && args.tags.length > 0) {
  74. queryBuilder.whereIn('tags.tag', args.tags)
  75. }
  76. const orderDir = args.orderByDirection === 'DESC' ? 'desc' : 'asc'
  77. switch (args.orderBy) {
  78. case 'CREATED':
  79. queryBuilder.orderBy('createdAt', orderDir)
  80. break
  81. case 'PATH':
  82. queryBuilder.orderBy('path', orderDir)
  83. break
  84. case 'TITLE':
  85. queryBuilder.orderBy('title', orderDir)
  86. break
  87. case 'UPDATED':
  88. queryBuilder.orderBy('updatedAt', orderDir)
  89. break
  90. default:
  91. queryBuilder.orderBy('pages.id', orderDir)
  92. break
  93. }
  94. })
  95. results = _.filter(results, r => {
  96. return WIKI.auth.checkAccess(context.req.user, ['read:pages'], {
  97. path: r.path,
  98. locale: r.locale
  99. })
  100. }).map(r => ({
  101. ...r,
  102. tags: _.map(r.tags, 'tag')
  103. }))
  104. if (args.tags && args.tags.length > 0) {
  105. results = _.filter(results, r => _.every(args.tags, t => _.includes(r.tags, t)))
  106. }
  107. return results
  108. },
  109. /**
  110. * FETCH SINGLE PAGE
  111. */
  112. async single (obj, args, context, info) {
  113. let page = await WIKI.models.pages.getPageFromDb(args.id)
  114. if (page) {
  115. return {
  116. ...page,
  117. locale: page.localeCode,
  118. editor: page.editorKey
  119. }
  120. } else {
  121. throw new WIKI.Error.PageNotFound()
  122. }
  123. },
  124. /**
  125. * FETCH TAGS
  126. */
  127. async tags (obj, args, context, info) {
  128. return WIKI.models.tags.query().orderBy('tag', 'asc')
  129. },
  130. /**
  131. * SEARCH TAGS
  132. */
  133. async searchTags (obj, args, context, info) {
  134. const results = await WIKI.models.tags.query()
  135. .column('tag')
  136. .where(builder => {
  137. builder.andWhere(builderSub => {
  138. if (WIKI.config.db.type === 'postgres') {
  139. builderSub.where('tag', 'ILIKE', `%${args.query}%`)
  140. } else {
  141. builderSub.where('tag', 'LIKE', `%${args.query}%`)
  142. }
  143. })
  144. })
  145. .limit(5)
  146. return results.map(r => r.tag)
  147. },
  148. /**
  149. * FETCH PAGE TREE
  150. */
  151. async tree (obj, args, context, info) {
  152. let results = []
  153. let conds = {
  154. localeCode: args.locale
  155. }
  156. if (args.parent) {
  157. conds.parent = (args.parent < 1) ? null : args.parent
  158. } else if (args.path) {
  159. // conds.parent = (args.parent < 1) ? null : args.parent
  160. }
  161. switch (args.mode) {
  162. case 'FOLDERS':
  163. conds.isFolder = true
  164. results = await WIKI.models.knex('pageTree').where(conds)
  165. break
  166. case 'PAGES':
  167. await WIKI.models.knex('pageTree').where(conds).andWhereNotNull('pageId')
  168. break
  169. default:
  170. results = await WIKI.models.knex('pageTree').where(conds)
  171. break
  172. }
  173. return results.filter(r => {
  174. return WIKI.auth.checkAccess(context.req.user, ['read:pages'], {
  175. path: r.path,
  176. locale: r.localeCode
  177. })
  178. }).map(r => ({
  179. ...r,
  180. parent: r.parent || 0,
  181. locale: r.localeCode
  182. }))
  183. },
  184. /**
  185. * FETCH PAGE LINKS
  186. */
  187. async links (obj, args, context, info) {
  188. let results = []
  189. results = await WIKI.models.knex('pages')
  190. .column({ id: 'pages.id' }, { path: 'pages.path' }, 'title', { link: 'pageLinks.path' }, { locale: 'pageLinks.localeCode' })
  191. .fullOuterJoin('pageLinks', 'pages.id', 'pageLinks.pageId')
  192. .where({
  193. 'pages.localeCode': args.locale
  194. })
  195. return _.reduce(results, (result, val) => {
  196. // -> Check if user has access to source and linked page
  197. if (
  198. !WIKI.auth.checkAccess(context.req.user, ['read:pages'], { path: val.path, locale: args.locale }) ||
  199. !WIKI.auth.checkAccess(context.req.user, ['read:pages'], { path: val.link, locale: val.locale })
  200. ) {
  201. return result
  202. }
  203. const existingEntry = _.findIndex(result, ['id', val.id])
  204. if (existingEntry >= 0) {
  205. if (val.link) {
  206. result[existingEntry].links.push(`${val.locale}/${val.link}`)
  207. }
  208. } else {
  209. result.push({
  210. id: val.id,
  211. title: val.title,
  212. path: `${args.locale}/${val.path}`,
  213. links: val.link ? [`${val.locale}/${val.link}`] : []
  214. })
  215. }
  216. return result
  217. }, [])
  218. }
  219. },
  220. PageMutation: {
  221. /**
  222. * CREATE PAGE
  223. */
  224. async create(obj, args, context) {
  225. try {
  226. const page = await WIKI.models.pages.createPage({
  227. ...args,
  228. user: context.req.user
  229. })
  230. return {
  231. responseResult: graphHelper.generateSuccess('Page created successfully.'),
  232. page
  233. }
  234. } catch (err) {
  235. return graphHelper.generateError(err)
  236. }
  237. },
  238. /**
  239. * UPDATE PAGE
  240. */
  241. async update(obj, args, context) {
  242. try {
  243. const page = await WIKI.models.pages.updatePage({
  244. ...args,
  245. user: context.req.user
  246. })
  247. return {
  248. responseResult: graphHelper.generateSuccess('Page has been updated.'),
  249. page
  250. }
  251. } catch (err) {
  252. return graphHelper.generateError(err)
  253. }
  254. },
  255. /**
  256. * MOVE PAGE
  257. */
  258. async move(obj, args, context) {
  259. try {
  260. await WIKI.models.pages.movePage({
  261. ...args,
  262. user: context.req.user
  263. })
  264. return {
  265. responseResult: graphHelper.generateSuccess('Page has been moved.')
  266. }
  267. } catch (err) {
  268. return graphHelper.generateError(err)
  269. }
  270. },
  271. /**
  272. * DELETE PAGE
  273. */
  274. async delete(obj, args, context) {
  275. try {
  276. await WIKI.models.pages.deletePage({
  277. ...args,
  278. user: context.req.user
  279. })
  280. return {
  281. responseResult: graphHelper.generateSuccess('Page has been deleted.')
  282. }
  283. } catch (err) {
  284. return graphHelper.generateError(err)
  285. }
  286. },
  287. /**
  288. * FLUSH PAGE CACHE
  289. */
  290. async flushCache(obj, args, context) {
  291. try {
  292. await WIKI.models.pages.flushCache()
  293. return {
  294. responseResult: graphHelper.generateSuccess('Pages Cache has been flushed successfully.')
  295. }
  296. } catch (err) {
  297. return graphHelper.generateError(err)
  298. }
  299. },
  300. /**
  301. * MIGRATE ALL PAGES FROM SOURCE LOCALE TO TARGET LOCALE
  302. */
  303. async migrateToLocale(obj, args, context) {
  304. try {
  305. const count = await WIKI.models.pages.migrateToLocale(args)
  306. return {
  307. responseResult: graphHelper.generateSuccess('Migrated content to target locale successfully.'),
  308. count
  309. }
  310. } catch (err) {
  311. return graphHelper.generateError(err)
  312. }
  313. },
  314. /**
  315. * REBUILD TREE
  316. */
  317. async rebuildTree(obj, args, context) {
  318. try {
  319. await WIKI.models.pages.rebuildTree()
  320. return {
  321. responseResult: graphHelper.generateSuccess('Page tree rebuilt successfully.')
  322. }
  323. } catch (err) {
  324. return graphHelper.generateError(err)
  325. }
  326. },
  327. /**
  328. * RENDER PAGE
  329. */
  330. async render (obj, args, context) {
  331. try {
  332. const page = await WIKI.models.pages.query().findById(args.id)
  333. if (!page) {
  334. throw new Error('Invalid Page Id')
  335. }
  336. await WIKI.models.pages.renderPage(page)
  337. return {
  338. responseResult: graphHelper.generateSuccess('Page rendered successfully.')
  339. }
  340. } catch (err) {
  341. return graphHelper.generateError(err)
  342. }
  343. }
  344. },
  345. Page: {
  346. // comments(pg) {
  347. // return pg.$relatedQuery('comments')
  348. // }
  349. }
  350. }