mirror of
https://github.com/supabase/supabase.git
synced 2026-10-17 07:09:07 +03:00
## Problem When uploading a file with same name of already existing file, the ui automatically creates a new file with incremental number and doesn't consider the scenario of giving the possibility of storing the new upload as a version of the already existing file. ## Solution Provide modal to chose the behaviour when name conflict happens when uploading a file: - Replace existing file (same file with version history) - Keep both (new file with incremental numbering) https://github.com/user-attachments/assets/ee192be9-4087-4e14-89f1-1c82acf550cd Manage edge case of clashes with files created when bucket had versioning enabled (so with `is_versioned` flag to true) and clashing upload happens when bucket is in SUSPENDED state. https://github.com/user-attachments/assets/00694c77-07c1-405e-bd54-bdf0bf99d274 Unrelated fix: - add "Delete permanently" action when selecting multiple files with versioning enabled <img width="510" height="203" alt="Screenshot 2026-10-13 at 15 59 27" src="https://github.com/user-attachments/assets/5692fc23-2fd3-4259-9de2-3932aecbccd0" />
128 lines
4.1 KiB
TypeScript
128 lines
4.1 KiB
TypeScript
export const storageKeys = {
|
|
bucket: (projectRef: string | undefined, bucketId: string | undefined) =>
|
|
['projects', projectRef, 'buckets', bucketId] as const,
|
|
buckets: (projectRef: string | undefined) => ['projects', projectRef, 'buckets'] as const,
|
|
bucketsList: (
|
|
projectRef: string | undefined,
|
|
params: {
|
|
limit?: number
|
|
search?: string
|
|
sortColumn?: string
|
|
sortOrder?: string
|
|
} = {}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'buckets',
|
|
'list',
|
|
{
|
|
limit: params.limit,
|
|
search: params.search,
|
|
sortColumn: params.sortColumn,
|
|
sortOrder: params.sortOrder,
|
|
},
|
|
] as const,
|
|
analyticsBuckets: (projectRef: string | undefined) =>
|
|
['projects', projectRef, 'analytics-buckets'] as const,
|
|
vectorBuckets: (projectRef: string | undefined) =>
|
|
['projects', projectRef, 'vector-buckets'] as const,
|
|
vectorBucket: (projectRef: string | undefined, vectorbucketName: string | undefined) =>
|
|
['projects', projectRef, 'vector-bucket', vectorbucketName] as const,
|
|
vectorBucketsIndexes: (projectRef: string | undefined, vectorBucketName: string | undefined) =>
|
|
['projects', projectRef, 'vector-buckets', vectorBucketName, 'indexes'] as const,
|
|
archive: (projectRef: string | undefined) => ['projects', projectRef, 'archive'] as const,
|
|
publicBucketsWithSelectPolicies: (projectRef: string | undefined, bucketId: string | undefined) =>
|
|
['projects', projectRef, 'public-buckets-with-select-policies', bucketId] as const,
|
|
objects: (
|
|
projectRef: string | undefined,
|
|
bucketId: string | undefined,
|
|
path: string,
|
|
params: {
|
|
limit?: number
|
|
search?: string
|
|
sortColumn?: string
|
|
sortOrder?: string
|
|
} = {}
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'buckets',
|
|
bucketId,
|
|
'objects',
|
|
...(path ? [path] : []),
|
|
...(params ? [params] : []),
|
|
] as const,
|
|
folders: (projectRef: string | undefined, bucketId: string | undefined) =>
|
|
['projects', projectRef, 'buckets', bucketId, 'folders'] as const,
|
|
bucketLifecycle: (projectRef: string | undefined, bucketId: string | undefined) =>
|
|
['projects', projectRef, 'buckets', bucketId, 'lifecycle'] as const,
|
|
/** The policy is part of the key: the API derives each version's expiry from it. */
|
|
objectVersions: (
|
|
projectRef: string | undefined,
|
|
bucketId: string | undefined,
|
|
objectName: string | undefined,
|
|
lifecyclePolicy?: { expiryDays: number | null; maxVersions: number | null }
|
|
) =>
|
|
[
|
|
'projects',
|
|
projectRef,
|
|
'buckets',
|
|
bucketId,
|
|
'object-versions',
|
|
objectName,
|
|
...(lifecyclePolicy ? [lifecyclePolicy] : []),
|
|
] as const,
|
|
/** Omit `versionId` for a prefix that matches every version's URL for one object. */
|
|
fileUrl: ({
|
|
projectRef,
|
|
isBucketPublic,
|
|
bucketId,
|
|
path,
|
|
versionId,
|
|
}: {
|
|
projectRef?: string
|
|
isBucketPublic?: boolean
|
|
bucketId?: string
|
|
path: string
|
|
versionId?: string
|
|
}) =>
|
|
[
|
|
projectRef,
|
|
'buckets',
|
|
isBucketPublic,
|
|
bucketId,
|
|
'file',
|
|
path,
|
|
...(versionId === undefined ? [] : [versionId]),
|
|
] as const,
|
|
archivedObjects: (projectRef: string | undefined, bucketId: string | undefined) =>
|
|
['projects', projectRef, 'buckets', bucketId, 'archived-objects'] as const,
|
|
archivedObjectNames: (
|
|
projectRef: string | undefined,
|
|
bucketId: string | undefined,
|
|
path: string
|
|
) => ['projects', projectRef, 'buckets', bucketId, 'archived-object-names', path] as const,
|
|
icebergNamespaces: ({ projectRef, warehouse }: { projectRef?: string; warehouse?: string }) =>
|
|
[projectRef, 'warehouse', warehouse, 'namespaces'] as const,
|
|
icebergNamespace: ({
|
|
projectRef,
|
|
warehouse,
|
|
namespace,
|
|
}: {
|
|
projectRef?: string
|
|
warehouse: string
|
|
namespace: string
|
|
}) => [projectRef, 'warehouse', warehouse, 'namespaces', namespace] as const,
|
|
icebergNamespaceTables: ({
|
|
projectRef,
|
|
warehouse,
|
|
namespace,
|
|
}: {
|
|
projectRef?: string
|
|
warehouse?: string
|
|
namespace?: string
|
|
}) => [projectRef, 'warehouse', warehouse, 'namespaces', namespace, 'tables'] as const,
|
|
}
|