mirror of
https://github.com/supabase/supabase.git
synced 2026-10-09 11:25:06 +03:00
- Call trigger() after each field.onChange so zod validation runs immediately as the user types, surfacing errors via FormMessage - Simplify the S3 cap error message to 'Cannot exceed 100 versions' Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TiUEvmC84bRsteqsWXHY2p
79 lines
2.7 KiB
TypeScript
79 lines
2.7 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
import type { ExpirationMode, VersioningPlanLimits } from './StorageProtection.constants'
|
|
|
|
/**
|
|
* Shared zod fields for the object-versioning controls in the create/edit
|
|
* bucket modals. `''` is the in-form empty sentinel (per the react-hook-form
|
|
* convention) so the number inputs stay fully deletable/controlled; it's
|
|
* coerced to a real number on parse.
|
|
*/
|
|
const versioningNumberField = z.union([z.literal(''), z.coerce.number().int()])
|
|
|
|
/**
|
|
* S3 lifecycle policies support at most 100 noncurrent versions per rule.
|
|
* This is an absolute ceiling independent of the org's billing plan.
|
|
*/
|
|
export const S3_MAX_NONCURRENT_VERSIONS = 100
|
|
|
|
export const bucketProtectionFormFields = {
|
|
enable_versioning: z.boolean().default(false),
|
|
version_expiry_days: versioningNumberField.default(''),
|
|
max_noncurrent_versions: versioningNumberField.default(''),
|
|
expiration_mode: z.enum(['and', 'or']).default('and'),
|
|
}
|
|
|
|
export interface BucketProtectionFormValues {
|
|
enable_versioning: boolean
|
|
version_expiry_days: '' | number
|
|
max_noncurrent_versions: '' | number
|
|
expiration_mode: ExpirationMode
|
|
}
|
|
|
|
/**
|
|
* Validates the versioning fields against the org's plan limits. Call this
|
|
* from the parent modal's `.superRefine` so errors surface through the usual
|
|
* `FormItemLayout`/`FormMessage` rendering.
|
|
*
|
|
* Both fields are optional — an empty value means "no limit" for that
|
|
* condition. When a value IS provided it must fall within the plan's bounds.
|
|
*/
|
|
export const superRefineBucketProtection = (
|
|
data: BucketProtectionFormValues,
|
|
ctx: z.RefinementCtx,
|
|
planLimits: VersioningPlanLimits | null
|
|
) => {
|
|
if (!data.enable_versioning || !planLimits) return
|
|
|
|
if (
|
|
data.version_expiry_days !== '' &&
|
|
(data.version_expiry_days < planLimits.minRetentionDays ||
|
|
data.version_expiry_days > planLimits.maxRetentionDays)
|
|
) {
|
|
ctx.addIssue({
|
|
path: ['version_expiry_days'],
|
|
code: z.ZodIssueCode.custom,
|
|
message: `Must be between ${planLimits.minRetentionDays} and ${planLimits.maxRetentionDays} days on your plan`,
|
|
})
|
|
}
|
|
|
|
if (data.max_noncurrent_versions !== '') {
|
|
if (data.max_noncurrent_versions > S3_MAX_NONCURRENT_VERSIONS) {
|
|
ctx.addIssue({
|
|
path: ['max_noncurrent_versions'],
|
|
code: z.ZodIssueCode.custom,
|
|
message: `Cannot exceed ${S3_MAX_NONCURRENT_VERSIONS} versions`,
|
|
})
|
|
} else if (
|
|
data.max_noncurrent_versions < planLimits.minVersions ||
|
|
data.max_noncurrent_versions > planLimits.maxVersions
|
|
) {
|
|
ctx.addIssue({
|
|
path: ['max_noncurrent_versions'],
|
|
code: z.ZodIssueCode.custom,
|
|
message: `Must be between ${planLimits.minVersions} and ${planLimits.maxVersions} versions on your plan`,
|
|
})
|
|
}
|
|
}
|
|
}
|