StorageSettings.utils.ts 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { StorageSizeUnits } from './StorageSettings.constants'
  2. const k = 1024
  3. export const BUCKET_LIMIT_ERROR_PREFIX = 'bucketLimit:'
  4. type BucketLimitErrorBucket = { name: string; limit: number }
  5. export const convertFromBytes = (bytes: number, unit?: StorageSizeUnits) => {
  6. // Up to GB since that's our storage upload limit
  7. if (bytes <= 0) return { value: 0, unit: StorageSizeUnits.BYTES }
  8. const i =
  9. unit !== undefined
  10. ? Object.values(StorageSizeUnits).indexOf(unit)
  11. : Math.floor(Math.log(bytes) / Math.log(k))
  12. const formattedIdx = unit !== undefined ? (i < 0 ? 0 : i) : i > 3 ? 3 : i
  13. const formattedUnit = Object.values(StorageSizeUnits)[formattedIdx]
  14. const value = bytes / Math.pow(k, formattedIdx)
  15. return { value, unit: formattedUnit }
  16. }
  17. export const convertToBytes = (size: number, unit: StorageSizeUnits = StorageSizeUnits.BYTES) => {
  18. const i = Object.values(StorageSizeUnits).indexOf(unit)
  19. if (size < 0 || i < 0) return 0
  20. return size * Math.pow(k, i)
  21. }
  22. function getStorageURL(projectRef: string, protocol: string, endpoint?: string) {
  23. const projUrl = endpoint
  24. ? `${protocol}://${endpoint}`
  25. : `https://${projectRef}.storage.supabase.co`
  26. const url = new URL(projUrl)
  27. return url
  28. }
  29. export function getConnectionURL(projectRef: string, protocol: string, endpoint?: string) {
  30. const url = getStorageURL(projectRef, protocol, endpoint)
  31. url.pathname = '/storage/v1/s3'
  32. return url.toString()
  33. }
  34. export function getCatalogURI(projectRef: string, protocol: string, endpoint?: string) {
  35. const url = getStorageURL(projectRef, protocol, endpoint)
  36. url.pathname = '/storage/v1/iceberg'
  37. return url.toString()
  38. }
  39. export function getVectorURI(projectRef: string, protocol: string, endpoint?: string) {
  40. const url = getStorageURL(projectRef, protocol, endpoint)
  41. url.pathname = '/storage/v1/vector'
  42. return url.toString()
  43. }
  44. export const formatBytesForDisplay = (bytes: number) => {
  45. const { value, unit } = convertFromBytes(bytes)
  46. return `${value.toLocaleString(undefined, { maximumFractionDigits: 2 })} ${unit}`
  47. }
  48. export const encodeBucketLimitErrorMessage = (buckets: BucketLimitErrorBucket[]) => {
  49. const encodedBuckets = buckets
  50. .map(({ name, limit }) => `${encodeURIComponent(name)}|${limit}`)
  51. .join(',')
  52. return `${BUCKET_LIMIT_ERROR_PREFIX}${encodedBuckets}`
  53. }
  54. export const isBucketLimitErrorMessage = (message?: string) => {
  55. return message?.startsWith(BUCKET_LIMIT_ERROR_PREFIX)
  56. }
  57. export const decodeBucketLimitErrorMessage = (message?: string): BucketLimitErrorBucket[] => {
  58. if (!isBucketLimitErrorMessage(message)) return []
  59. const payload = message?.slice(BUCKET_LIMIT_ERROR_PREFIX.length) ?? ''
  60. if (payload.length === 0) return []
  61. return payload
  62. .split(',')
  63. .filter(Boolean)
  64. .map((entry) => {
  65. const parts = entry.split('|')
  66. if (parts.length !== 2) return undefined
  67. const name = decodeURIComponent(parts[0])
  68. if (!name) return undefined
  69. const limitString = parts[1]
  70. const limit = Number(limitString ?? 0)
  71. if (Number.isNaN(limit)) return undefined
  72. return { name, limit }
  73. })
  74. .filter((entry) => entry !== undefined)
  75. }