Files
supabase/apps/studio/data/storage/keys.ts
T
Francesco SansalvadoreandClaude Sonnet 5 2d0bd7af69 feat(storage): add object versions data layer (#49207)
| # | Branch | Base |
| - | ------ | ---- |
| 1 | `feat/storage-versioning-private-alpha` — merged | `master` |
| 2 | `feat/storage-versioning/002-bucket-form-fields` | `master` |
| 3 | `feat/storage-versioning/003-bucket-modals` | 2 |
| 4 | `feat/storage-versioning/004-object-versions-data` ◀ | 3 |
| 5 | `feat/storage-versioning/005-file-preview-versions` | 4 |
| 6 | `feat/storage-versioning/006-billing-storage-retention` | 5 |
| 7 | `feat/storage-versioning/007-archived-objects-data` | 6 |
| 8 | `feat/storage-versioning/008-archived-rows` | 7 |
| 9 | `feat/storage-versioning/009-archived-preview-pane` | 8 |
| 10 | `feat/storage-versioning/010-replace-file` | 9 |

## [4/10] Storage object versioning: object versions data layer

**Base:** `feat/storage-versioning/003-bucket-modals` (PR 3)

### This PR

The query and mutation hooks for the version history UI, written to
`queryOptions` using the real Storage endpoints.

- `object-versions-query.ts` — the version list, plus `ObjectVersion`
and `LifecyclePolicy`
- `object-version-restore-mutation.ts` — promote a noncurrent version to
current
- `object-version-delete-mutation.ts` — remove one specific version
- `object-purge-mutation.ts` — delete an object and every version,
bypassing versioning
- `VersionHistory.utils.ts` — `computeVersionFate`, the pure rule
deciding what removal outlook each version row shows
- `BroomSparklesIcon.tsx` — inline SVG for a glyph absent from
lucide-react 0.436

Easier to test directly from next PR in the stack #49208 which wires the
queries to the real file preview panel ui.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 22:12:19 +02:00

121 lines
3.8 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,
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,
}