mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge pull request #2942 from appwrite/fix/api-endpoint-double-region-subdomain
fix: normalize regional API base URL and prevent invalid multi-region…
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import {
|
||||
REGION_FRA,
|
||||
REGION_NYC,
|
||||
REGION_SFO,
|
||||
REGION_SGP,
|
||||
REGION_SYD,
|
||||
REGION_TOR,
|
||||
SUBDOMAIN_FRA,
|
||||
SUBDOMAIN_NYC,
|
||||
SUBDOMAIN_SFO,
|
||||
SUBDOMAIN_SGP,
|
||||
SUBDOMAIN_SYD,
|
||||
SUBDOMAIN_TOR
|
||||
} from '$lib/constants';
|
||||
|
||||
/** Ordered list of region DNS prefixes (e.g. `fra.`) for stripping from API hostnames. */
|
||||
const REGION_SUBDOMAIN_PREFIXES: readonly string[] = [
|
||||
SUBDOMAIN_FRA,
|
||||
SUBDOMAIN_NYC,
|
||||
SUBDOMAIN_SYD,
|
||||
SUBDOMAIN_SFO,
|
||||
SUBDOMAIN_SGP,
|
||||
SUBDOMAIN_TOR
|
||||
];
|
||||
|
||||
/**
|
||||
* Removes leading Appwrite Cloud region label(s) from `hostname` (e.g. `fra.`).
|
||||
* Strips repeatedly so a doubled prefix (`fra.fra.cloud...`) does not become
|
||||
* `nyc.fra.cloud...` after prepending another region.
|
||||
*/
|
||||
export function stripLeadingRegionSubdomain(hostname: string): string {
|
||||
let host = hostname;
|
||||
let changed = true;
|
||||
while (changed) {
|
||||
changed = false;
|
||||
for (const prefix of REGION_SUBDOMAIN_PREFIXES) {
|
||||
if (host.startsWith(prefix)) {
|
||||
host = host.slice(prefix.length);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return host;
|
||||
}
|
||||
|
||||
/** Region prefix (e.g. `fra.`) used before the API hostname when multi-region is enabled. */
|
||||
export function getRegionSubdomain(region?: string): string {
|
||||
switch (region) {
|
||||
case REGION_FRA:
|
||||
return SUBDOMAIN_FRA;
|
||||
case REGION_SYD:
|
||||
return SUBDOMAIN_SYD;
|
||||
case REGION_NYC:
|
||||
return SUBDOMAIN_NYC;
|
||||
case REGION_SFO:
|
||||
return SUBDOMAIN_SFO;
|
||||
case REGION_SGP:
|
||||
return SUBDOMAIN_SGP;
|
||||
case REGION_TOR:
|
||||
return SUBDOMAIN_TOR;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the `/v1` API base URL (protocol + host + `/v1`).
|
||||
* When `isMultiRegion` is true and a region is selected, strips any known region prefix from the host,
|
||||
* then prepends that region. If multi-region is on but no region is requested (`region` missing or
|
||||
* unknown), the hostname is left unchanged so a default region baked into `APPWRITE_ENDPOINT` is kept.
|
||||
*/
|
||||
export function buildRegionalV1Endpoint(
|
||||
protocol: string,
|
||||
hostname: string,
|
||||
region: string | undefined,
|
||||
isMultiRegion: boolean
|
||||
): string {
|
||||
if (!isMultiRegion) {
|
||||
return `${protocol}//${hostname}/v1`;
|
||||
}
|
||||
|
||||
const subdomain = getRegionSubdomain(region);
|
||||
if (!subdomain) {
|
||||
return `${protocol}//${hostname}/v1`;
|
||||
}
|
||||
|
||||
const hostWithoutRegion = stripLeadingRegionSubdomain(hostname);
|
||||
return `${protocol}//${subdomain}${hostWithoutRegion}/v1`;
|
||||
}
|
||||
+2
-42
@@ -28,21 +28,8 @@ import {
|
||||
Realtime,
|
||||
Organizations
|
||||
} from '@appwrite.io/console';
|
||||
import { buildRegionalV1Endpoint } from '$lib/helpers/apiEndpoint';
|
||||
import { Sources } from '$lib/sdk/sources';
|
||||
import {
|
||||
REGION_FRA,
|
||||
REGION_NYC,
|
||||
REGION_SYD,
|
||||
REGION_SFO,
|
||||
REGION_SGP,
|
||||
REGION_TOR,
|
||||
SUBDOMAIN_FRA,
|
||||
SUBDOMAIN_NYC,
|
||||
SUBDOMAIN_SFO,
|
||||
SUBDOMAIN_SYD,
|
||||
SUBDOMAIN_SGP,
|
||||
SUBDOMAIN_TOR
|
||||
} from '$lib/constants';
|
||||
import { building } from '$app/environment';
|
||||
|
||||
export function getApiEndpoint(region?: string): string {
|
||||
@@ -50,37 +37,10 @@ export function getApiEndpoint(region?: string): string {
|
||||
const url = new URL(
|
||||
VARS.APPWRITE_ENDPOINT ? VARS.APPWRITE_ENDPOINT : globalThis?.location?.toString()
|
||||
);
|
||||
const protocol = url.protocol;
|
||||
const hostname = url.host; // "hostname:port" (or just "hostname" if no port)
|
||||
|
||||
// If instance supports multi-region, add the region subdomain.
|
||||
let subdomain = isMultiRegionSupported(url) ? getSubdomain(region) : '';
|
||||
if (subdomain && hostname.startsWith(subdomain)) {
|
||||
subdomain = '';
|
||||
}
|
||||
|
||||
return `${protocol}//${subdomain}${hostname}/v1`;
|
||||
return buildRegionalV1Endpoint(url.protocol, url.host, region, isMultiRegionSupported(url));
|
||||
}
|
||||
|
||||
const getSubdomain = (region?: string) => {
|
||||
switch (region) {
|
||||
case REGION_FRA:
|
||||
return SUBDOMAIN_FRA;
|
||||
case REGION_SYD:
|
||||
return SUBDOMAIN_SYD;
|
||||
case REGION_NYC:
|
||||
return SUBDOMAIN_NYC;
|
||||
case REGION_SFO:
|
||||
return SUBDOMAIN_SFO;
|
||||
case REGION_SGP:
|
||||
return SUBDOMAIN_SGP;
|
||||
case REGION_TOR:
|
||||
return SUBDOMAIN_TOR;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
function createConsoleSdk(client: Client) {
|
||||
return {
|
||||
client,
|
||||
|
||||
Reference in New Issue
Block a user