Files
supabase/apps/studio/components/interfaces/ProjectCreation/ProjectCreation.utils.ts
T
9952d6f10f [FE-4067] fix(studio): re-allow all regions in local project creation (#48704)
Local dev stacks can run in any of the three supported regions (e.g.
Bobbie's is in `ap-southeast-1`), but enabling High Availability on the
project creation form pinned local to Frankfurt only. This unrestricts
local so all three regions are selectable again.

**Changed:**
- `getHighAvailabilityRegionCode()` returns `undefined` for `local`
(same as prod), so `filterHighAvailabilityRegions()` no longer collapses
the list — staging stays pinned to `us-east-1`
- The three-region warning in `RegionSelector` now adds a local-only
recommendation: "Use Central EU (Frankfurt) unless you're on a personal
dev stack."
- Updated unit tests, including an `ap-southeast-1` fixture region to
prove pass-through

## To test

- On a local stack, open the new project form and enable High
Availability — the region selector should offer all three regions (East
US, Frankfurt, Southeast Asia) instead of locking to Frankfurt, and the
warning should recommend Frankfurt unless you're on a personal dev stack
- Confirm staging behavior is unchanged (HA still pins to East US)
- `pnpm --filter studio exec vitest run
components/interfaces/ProjectCreation`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Local development projects can now use high-availability regions
beyond Central EU.
* Region filtering and availability messaging now correctly reflect the
active environment, including staging restrictions.

* **User Experience**
* Added guidance recommending Central EU for local projects, unless
using a personal development stack.
* Region selection now provides clearer environment-specific information
when options are limited.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-08-05 14:51:57 +07:00

67 lines
2.3 KiB
TypeScript

import type { CloudProvider, Region } from 'shared-data'
import { AWS_REGIONS } from 'shared-data'
import { SMART_REGION_TO_EXACT_REGION_MAP } from 'shared-data/regions'
import { DesiredInstanceSize, instanceSizeSpecs } from '@/data/projects/new-project.constants'
export function smartRegionToExactRegion(smartOrExactRegion: string) {
return SMART_REGION_TO_EXACT_REGION_MAP.get(smartOrExactRegion) ?? smartOrExactRegion
}
export function getAvailableRegions(cloudProvider: CloudProvider): Region {
switch (cloudProvider) {
case 'AWS':
case 'AWS_K8S':
return AWS_REGIONS
case 'AWS_NIMBUS':
if (process.env.NEXT_PUBLIC_ENVIRONMENT !== 'prod') {
// Only allow Southeast Asia for Nimbus (local/staging)
return {
SOUTHEAST_ASIA: AWS_REGIONS.SOUTHEAST_ASIA,
}
}
// Only allow US East for Nimbus (prod)
return {
EAST_US: AWS_REGIONS.EAST_US,
}
default:
throw new Error('Invalid cloud provider')
}
}
/**
* When launching new projects, they only get assigned a compute size once successfully launched,
* this might assume wrong compute size, but only for projects being rapidly launched after one another on non-default compute sizes.
*
* Needs to be in the API in the future [kevin]
*/
export const monthlyInstancePrice = (instance: string | undefined): number => {
return instanceSizeSpecs[instance as DesiredInstanceSize]?.priceMonthly || 10
}
export const instanceLabel = (instance: string | undefined): string => {
return instanceSizeSpecs[instance as DesiredInstanceSize]?.label || 'Micro'
}
export const getHighAvailabilityRegionCode = (
environment = process.env.NEXT_PUBLIC_ENVIRONMENT
) => {
// Local dev stacks can run in any of the supported regions, so they're left unrestricted
if (environment === 'staging') return 'us-east-1'
if (environment === 'local') return 'eu-central-1'
return undefined
}
export const filterHighAvailabilityRegions = <T extends { code: string }>(
regions: T[],
highAvailability: boolean,
environment = process.env.NEXT_PUBLIC_ENVIRONMENT
) => {
const isLocal = environment === 'local'
const regionCode = getHighAvailabilityRegionCode(environment)
return highAvailability && !isLocal && regionCode !== undefined
? regions.filter((region) => region.code === regionCode)
: regions
}