ext.mjs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import fse from 'fs-extra'
  2. import os from 'node:os'
  3. import path from 'node:path'
  4. import util from 'node:util'
  5. import { exec as execSync } from 'node:child_process'
  6. import { pipeline } from 'node:stream/promises'
  7. const exec = util.promisify(execSync)
  8. export default {
  9. key: 'sharp',
  10. title: 'Sharp',
  11. description: 'Process and transform images. Required to generate thumbnails of uploaded images and perform transformations.',
  12. async isCompatible () {
  13. return os.arch() === 'x64'
  14. },
  15. isInstalled: false,
  16. isInstallable: true,
  17. async check () {
  18. this.isInstalled = await fse.pathExists(path.join(WIKI.SERVERPATH, 'node_modules/sharp/wiki_installed.txt'))
  19. return this.isInstalled
  20. },
  21. async install () {
  22. try {
  23. const { stdout, stderr } = await exec('node install/check', {
  24. cwd: path.join(WIKI.SERVERPATH, 'node_modules/sharp'),
  25. timeout: 120000,
  26. windowsHide: true
  27. })
  28. await fse.ensureFile(path.join(WIKI.SERVERPATH, 'node_modules/sharp/wiki_installed.txt'))
  29. this.isInstalled = true
  30. WIKI.logger.info(stdout)
  31. WIKI.logger.warn(stderr)
  32. } catch (err) {
  33. WIKI.logger.error(err)
  34. }
  35. },
  36. sharp: null,
  37. async load () {
  38. if (!this.sharp) {
  39. this.sharp = (await import('sharp')).default
  40. }
  41. },
  42. /**
  43. * RESIZE IMAGE
  44. */
  45. async resize ({
  46. format = 'png',
  47. inputStream = null,
  48. inputPath = null,
  49. outputStream = null,
  50. outputPath = null,
  51. width = null,
  52. height = null,
  53. fit = 'cover',
  54. background = { r: 0, g: 0, b: 0, alpha: 0 },
  55. kernel = 'lanczos3'
  56. }) {
  57. await this.load()
  58. if (inputPath) {
  59. inputStream = fse.createReadStream(inputPath)
  60. }
  61. if (!inputStream) {
  62. throw new Error('Failed to open readable input stream for image resizing.')
  63. }
  64. if (outputPath) {
  65. outputStream = fse.createWriteStream(outputPath)
  66. }
  67. if (!outputStream) {
  68. throw new Error('Failed to open writable output stream for image resizing.')
  69. }
  70. if (format === 'svg') {
  71. return pipeline([inputStream, outputStream])
  72. } else {
  73. const transformer = this.sharp().resize({
  74. width,
  75. height,
  76. fit,
  77. background,
  78. kernel
  79. }).toFormat(format)
  80. return pipeline([inputStream, transformer, outputStream])
  81. }
  82. }
  83. }