resolvers.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { IResolvers } from 'apollo-server-express'
  2. import fs from 'fs'
  3. import randombytes from 'randombytes'
  4. import { uploadDir } from './constants'
  5. import { checkPermission } from '../user/resolvers'
  6. import { saveStreamToFile, processImage, processVideo, processAudio } from './utils'
  7. export const resolvers: IResolvers = {
  8. Query: {
  9. fsFiles: async (parent, { directory }, context, info) => {
  10. checkPermission(context, 'ADMIN')
  11. const data = await fsFiles(directory)
  12. return data
  13. },
  14. files: (parent, args, context, info) => {
  15. checkPermission(context, 'ADMIN')
  16. return context.db.query.files(args, info)
  17. },
  18. file: (parent, args, context, info) => {
  19. checkPermission(context, 'ADMIN')
  20. return context.db.query.file(args, info)
  21. },
  22. },
  23. Mutation: {
  24. uploadFile: async (parent, { file, ...args }, context, info) => {
  25. checkPermission(context, 'ADMIN')
  26. const fileInfo = await uploadFile(file)
  27. return context.db.mutation.createFile(
  28. {
  29. data: {
  30. ...args,
  31. ...fileInfo,
  32. user: { connect: { id: context.req.userId } },
  33. },
  34. },
  35. info
  36. )
  37. },
  38. updateFile: (parent, args, context, info) => {
  39. checkPermission(context, 'ADMIN')
  40. return context.db.mutation.updateFile(args, info)
  41. },
  42. deleteFile: async (parent, { id }, context, info) => {
  43. checkPermission(context, 'ADMIN')
  44. const file = await context.db.query.file({ where: { id } })
  45. if (!file) throw Error(`File '${id}' not found.`)
  46. console.log(file)
  47. try {
  48. await fs.promises.unlink(file.path)
  49. } catch (error) {}
  50. return context.db.mutation.deleteFile({ where: { id } })
  51. },
  52. },
  53. }
  54. async function fsFiles(directory: string) {
  55. const fileList = await fs.promises.readdir(directory)
  56. return Promise.all(
  57. fileList.map(async (filename) => {
  58. const path = `${directory}/${filename}`
  59. const { size, ctime, mtime } = await fs.promises.stat(path)
  60. return {
  61. filename,
  62. path,
  63. size,
  64. ctime,
  65. mtime,
  66. }
  67. })
  68. )
  69. }
  70. async function uploadFile(file: any) {
  71. const { createReadStream, filename, mimetype, encoding } = await file
  72. const stream = createReadStream()
  73. const fsFilename = randombytes(16).toString('hex')
  74. const path: [string, string] = [uploadDir, fsFilename]
  75. const filePath = path.join('/')
  76. let fileDetails = { filename, mimetype, encoding, path: filePath }
  77. if (mimetype.startsWith('image/')) {
  78. const imageDetails = await processImage(stream, path)
  79. fileDetails = { ...fileDetails, ...imageDetails }
  80. } else if (mimetype.startsWith('video/')) {
  81. const videoDetails = await processVideo(stream, path)
  82. fileDetails = { ...fileDetails, ...videoDetails }
  83. } else if (mimetype.startsWith('audio/')) {
  84. const audioDetails = await processAudio(stream, path)
  85. fileDetails = { ...fileDetails, ...audioDetails }
  86. } else {
  87. await saveStreamToFile(stream, path)
  88. }
  89. const { size } = await fs.promises.stat(filePath)
  90. return { ...fileDetails, size }
  91. }