upload-root.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. import path from 'node:path'
  2. /**
  3. * Where this installation keeps the files people upload.
  4. *
  5. * `DATA_ROOT` moves the whole data directory, which is what a self-hosted
  6. * install wants when the disk with room on it is not the disk the app was
  7. * unpacked on. Unset — which is every install that has not been told
  8. * otherwise — it is `data` beside the app, exactly where every file has
  9. * always been written.
  10. *
  11. * The seed script has honoured this variable since it was written and the app
  12. * never did, so anyone who set it had their uploads written to the default
  13. * anyway. Reads therefore try the configured root and then the old default,
  14. * which is what makes turning this on lossless: files already on disk keep
  15. * resolving, and new ones go where the variable says.
  16. */
  17. /** The data directory: `DATA_ROOT`, or `data` beside the app. */
  18. export function dataRoot(): string {
  19. return process.env.DATA_ROOT || path.join(process.cwd(), 'data')
  20. }
  21. /** Where uploads live now. */
  22. export function uploadsRoot(): string {
  23. return path.join(dataRoot(), 'uploads')
  24. }
  25. /**
  26. * Where uploads lived before the app read `DATA_ROOT`. The same directory
  27. * unless the variable is set, and the reason an upgrade loses nothing.
  28. */
  29. export function legacyUploadsRoot(): string {
  30. return path.join(process.cwd(), 'data', 'uploads')
  31. }
  32. /** Every root a stored file could be under, nearest first. */
  33. export function uploadsRoots(): string[] {
  34. const roots = [uploadsRoot()]
  35. const legacy = legacyUploadsRoot()
  36. if (legacy !== roots[0]) roots.push(legacy)
  37. return roots
  38. }
  39. /** One organisation's upload directory, optionally a category within it. */
  40. export function orgUploadDir(organizationId: string, ...segments: string[]): string {
  41. return path.join(uploadsRoot(), organizationId, ...segments)
  42. }