{"version":3,"sources":["../src/index.ts","../src/directory-fetcher.ts","../src/url-fetcher.ts","../src/directory-urls-fetcher.ts","../src/lib/get-minimal-paths.ts","../src/mutate-paths.ts","../src/remove-files.ts","../src/remove-directory.ts","../src/upload.ts"],"sourcesContent":["export * from './lib/types';\n\nexport * from './directory-fetcher';\nexport * from './directory-urls-fetcher';\nexport * from './mutate-paths';\nexport * from './remove-directory';\nexport * from './remove-files';\nexport * from './upload';\nexport * from './url-fetcher';\n","import type { StorageFileApi } from './lib/types';\nimport type { FileObject } from '@supabase/storage-js';\n\nexport const fetchDirectory = async (\n  fileApi: StorageFileApi,\n  path: string,\n): Promise<FileObject[]> => {\n  const { data, error } = await fileApi.list(path);\n  if (error) throw error;\n  if (!Array.isArray(data)) return [];\n  return data;\n};\n","import type { StorageFileApi, StoragePrivacy } from './lib/types';\nimport type { TransformOptions } from '@supabase/storage-js';\n\ntype URLFetcher = (\n  fileApi: StorageFileApi,\n  path: string,\n) => Promise<string | undefined>;\n\nexport type URLFetcherConfig = {\n  expiresIn?: number;\n  ensureExistence?: boolean;\n  download?: string | boolean | undefined;\n  transform?: TransformOptions | undefined;\n};\n\nexport const createUrlFetcher = (\n  mode: StoragePrivacy,\n  config?: URLFetcherConfig,\n): URLFetcher => {\n  return async (\n    fileApi: StorageFileApi,\n    path: string,\n  ): Promise<string | undefined> => {\n    let params: Record<string, string> = {};\n\n    if (config?.ensureExistence) {\n      const lastSlash = path.lastIndexOf('/');\n      const prefix = lastSlash >= 0 ? path.substring(0, lastSlash) : undefined;\n      const fileName = lastSlash >= 0 ? path.substring(lastSlash + 1) : path;\n\n      const { data: files, error } = await fileApi.list(prefix ?? undefined, {\n        search: fileName,\n        limit: 1,\n      });\n\n      if (error) throw error;\n\n      const file = files?.find((f) => f.name === fileName);\n      if (!file) return;\n\n      params = {\n        updated_at: file.updated_at ?? '',\n      };\n    }\n\n    let url: string | undefined;\n    if (mode === 'private') {\n      const { data, error } = await fileApi.createSignedUrl(\n        path,\n        config?.expiresIn ?? 1800,\n        config,\n      );\n      if (error) throw error;\n      url = data.signedUrl;\n    } else if (mode === 'public') {\n      const { data } = fileApi.getPublicUrl(path, config);\n      url = data.publicUrl;\n    } else {\n      throw new Error(`Invalid mode: ${mode}`);\n    }\n    const fileURL = new URL(url);\n    Object.entries(params).forEach(([key, value]) => {\n      fileURL.searchParams.append(key, value);\n    });\n    return fileURL.toString();\n  };\n};\n","import { fetchDirectory } from './directory-fetcher';\nimport type { StorageFileApi, StoragePrivacy } from './lib/types';\nimport { type URLFetcherConfig, createUrlFetcher } from './url-fetcher';\nimport type { FileObject } from '@supabase/storage-js';\n\ntype DirectoryURLsFetcher = (\n  fileApi: StorageFileApi,\n  path: string,\n) => Promise<(FileObject & { url: string })[]>;\n\nexport const createDirectoryUrlsFetcher = (\n  mode: StoragePrivacy,\n  config?: Pick<URLFetcherConfig, 'expiresIn'>,\n): DirectoryURLsFetcher => {\n  const fetchUrl = createUrlFetcher(mode, config);\n  return async (fileApi: StorageFileApi, path) => {\n    const files = await fetchDirectory(fileApi, path);\n    const filesWithUrls = [];\n    for (const f of files) {\n      const url = await fetchUrl(fileApi, `${path}/${f.name}`);\n      if (url) filesWithUrls.push({ ...f, url });\n    }\n    return filesWithUrls;\n  };\n};\n","export const getMinimalPaths = (paths: string[]) =>\n  paths.reduce<string[]>((paths, path) => {\n    const matchingPaths = paths.filter((p) => p.startsWith(path));\n    return [...paths.filter((p) => !matchingPaths.includes(p)), path];\n  }, []);\n","import { getMinimalPaths } from './lib/get-minimal-paths';\nimport type { DecodedStorageKey } from './lib/types';\n\nexport type Cache<KeyType> = {\n  /**\n   * The keys currently present in the cache\n   */\n  cacheKeys: KeyType[];\n  /**\n   * Decode a key. Should return null if not a Storage key.\n   */\n  decode: (k: KeyType) => DecodedStorageKey | null;\n  /**\n   * The mutation function from the cache library\n   */\n  mutate: (key: KeyType) => Promise<void>;\n};\n\nexport const mutatePaths = async <KeyType>(\n  bucketId: string,\n  paths: string[],\n  { cacheKeys, decode, mutate }: Cache<KeyType>,\n) => {\n  const minimalPaths = getMinimalPaths(paths);\n  if (minimalPaths.length === 0) return;\n  await Promise.all(\n    cacheKeys.map(async (key) => {\n      const decodedKey = decode(key);\n      if (!decodedKey) return false;\n      if (decodedKey.bucketId !== bucketId) return false;\n      if (\n        minimalPaths.find(\n          (p) => p.startsWith(decodedKey.path) || decodedKey.path.startsWith(p),\n        )\n      ) {\n        mutate(key);\n      }\n    }),\n  );\n};\n","import type { StorageFileApi } from './lib/types';\n\nexport const createRemoveFilesFetcher =\n  (fileApi: StorageFileApi) => async (paths: string[]) => {\n    const { data, error } = await fileApi.remove(paths);\n    if (error) throw error;\n    return data;\n  };\n","import { fetchDirectory } from './directory-fetcher';\nimport type { StorageFileApi } from './lib/types';\nimport { createRemoveFilesFetcher } from './remove-files';\n\nexport const createRemoveDirectoryFetcher = (fileApi: StorageFileApi) => {\n  const removeFiles = createRemoveFilesFetcher(fileApi);\n  return async (path: string) => {\n    const files = await fetchDirectory(fileApi, path);\n    return await removeFiles(files.map((f) => [path, f.name].join('/')));\n  };\n};\n","import type { StorageFileApi } from './lib/types';\nimport type { FileOptions } from '@supabase/storage-js';\n\nexport type BuildFileNameFn = ({\n  path,\n  fileName,\n}: {\n  path?: string;\n  fileName: string;\n}) => string;\n\nconst defaultBuildFileName: BuildFileNameFn = ({ path, fileName }) =>\n  [path, fileName].filter(Boolean).join('/');\n\nexport type UploadFetcherConfig = Partial<\n  Pick<FileOptions, 'cacheControl' | 'upsert'>\n> & {\n  buildFileName?: BuildFileNameFn;\n};\n\nexport type UploadFileResponse = Awaited<ReturnType<StorageFileApi['upload']>>;\n\nexport type UploadFileInput = {\n  data: Parameters<StorageFileApi['upload']>[1];\n  type?: string;\n  name: string;\n  metadata?: NonNullable<Parameters<StorageFileApi['upload']>[2]>['metadata'];\n};\n\nexport type FileInput = File | UploadFileInput;\n\nconst isUploadFileInput = (i: FileInput): i is UploadFileInput =>\n  Boolean((i as UploadFileInput).data);\n\nexport const createUploadFetcher = (\n  fileApi: StorageFileApi,\n  config?: UploadFetcherConfig,\n) => {\n  const buildFileName = config?.buildFileName ?? defaultBuildFileName;\n  return async (\n    files: FileList | FileInput[],\n    path?: string,\n  ): Promise<UploadFileResponse[]> => {\n    // convert FileList into File[]\n    const inputFiles: FileInput[] = [];\n    for (let i = 0; i < files.length; i++) {\n      inputFiles.push(files[i]);\n    }\n    const uploading = inputFiles.map(async (f) => {\n      const res = await fileApi.upload(\n        buildFileName({\n          path,\n          fileName: f.name,\n        }).replace(\n          // remove double \"/\"\n          /\\/+/g,\n          '/',\n        ),\n        isUploadFileInput(f) ? f.data : f,\n        {\n          contentType: f.type,\n          metadata: isUploadFileInput(f) ? f.metadata : undefined,\n          ...config,\n        },\n      );\n      return res;\n    });\n    return await Promise.all(uploading);\n  };\n};\n"],"mappings":"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","names":["paths"]}