mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
93 lines
3.1 KiB
TypeScript
93 lines
3.1 KiB
TypeScript
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import {
|
|
type CanonicalNetworkEndpointRule,
|
|
HTTP_NETWORK_PROTOCOLS,
|
|
normalizeCanonicalNetworkEndpoint,
|
|
} from '@fluxer/instance_bootstrap/src/NetworkOrigin';
|
|
|
|
export const OFFICIAL_INSTANCE_NAME = 'Fluxer';
|
|
|
|
export const OFFICIAL_INSTANCE_DISPLAY_HOST = 'fluxer.app';
|
|
|
|
export const OFFICIAL_STABLE_MARKETING_ORIGIN = `https://${OFFICIAL_INSTANCE_DISPLAY_HOST}`;
|
|
|
|
export const OFFICIAL_CLIENT_API_ENDPOINTS = Object.freeze({
|
|
stable: 'https://web.fluxer.app/api',
|
|
canary: 'https://web.canary.fluxer.app/api',
|
|
} as const);
|
|
|
|
export type OfficialReleaseChannel = keyof typeof OFFICIAL_CLIENT_API_ENDPOINTS;
|
|
|
|
export const OFFICIAL_MARKETING_ORIGINS = Object.freeze({
|
|
stable: OFFICIAL_STABLE_MARKETING_ORIGIN,
|
|
canary: 'https://canary.fluxer.app',
|
|
} as const) satisfies Record<OfficialReleaseChannel, string>;
|
|
|
|
export function officialMarketingOrigin(releaseChannel: string | null | undefined): string {
|
|
return releaseChannel === 'stable' ? OFFICIAL_MARKETING_ORIGINS.stable : OFFICIAL_MARKETING_ORIGINS.canary;
|
|
}
|
|
|
|
const OFFICIAL_MIGRATED_WEB_APP_HOSTS = Object.freeze({
|
|
stable: 'fluxer.com',
|
|
canary: 'canary.fluxer.com',
|
|
} as const) satisfies Record<OfficialReleaseChannel, string>;
|
|
|
|
const OFFICIAL_CLIENT_API_PATH = '/api';
|
|
|
|
const OFFICIAL_RELEASE_CHANNELS: ReadonlyArray<OfficialReleaseChannel> = Object.freeze(['stable', 'canary']);
|
|
|
|
const OFFICIAL_CLIENT_API_HOST_CHANNELS: ReadonlyMap<string, OfficialReleaseChannel> = new Map(
|
|
OFFICIAL_RELEASE_CHANNELS.flatMap(
|
|
(channel): Array<[string, OfficialReleaseChannel]> => [
|
|
[new URL(OFFICIAL_CLIENT_API_ENDPOINTS[channel]).host, channel],
|
|
[OFFICIAL_MIGRATED_WEB_APP_HOSTS[channel], channel],
|
|
],
|
|
),
|
|
);
|
|
|
|
export function officialClientApiEndpointForAlias(apiEndpoint: string): string | null {
|
|
let url: URL;
|
|
try {
|
|
url = new URL(apiEndpoint.trim());
|
|
} catch {
|
|
return null;
|
|
}
|
|
if (url.protocol !== 'https:' || url.username || url.password || url.search || url.hash) {
|
|
return null;
|
|
}
|
|
if (url.pathname.replace(/\/+$/u, '') !== OFFICIAL_CLIENT_API_PATH) {
|
|
return null;
|
|
}
|
|
const channel = OFFICIAL_CLIENT_API_HOST_CHANNELS.get(url.host);
|
|
return channel === undefined ? null : OFFICIAL_CLIENT_API_ENDPOINTS[channel];
|
|
}
|
|
|
|
export const OFFICIAL_INSTANCE_HOSTS: ReadonlyArray<string> = Object.freeze([
|
|
OFFICIAL_INSTANCE_DISPLAY_HOST,
|
|
'web.fluxer.app',
|
|
'api.fluxer.app',
|
|
'canary.fluxer.app',
|
|
'web.canary.fluxer.app',
|
|
'api.canary.fluxer.app',
|
|
'fluxer.com',
|
|
'canary.fluxer.com',
|
|
]);
|
|
|
|
const OFFICIAL_HOST_LOOKUP_RULE: CanonicalNetworkEndpointRule = Object.freeze({
|
|
protocols: HTTP_NETWORK_PROTOCOLS,
|
|
allowPath: true,
|
|
allowRelative: false,
|
|
});
|
|
|
|
export function isOfficialInstanceHost(value: string): boolean {
|
|
const endpoint = normalizeCanonicalNetworkEndpoint(value, OFFICIAL_HOST_LOOKUP_RULE);
|
|
if (endpoint == null) {
|
|
return false;
|
|
}
|
|
const authority = endpoint.slice(endpoint.indexOf('//') + 2);
|
|
const pathStart = authority.indexOf('/');
|
|
const host = (pathStart === -1 ? authority : authority.slice(0, pathStart)).toLowerCase();
|
|
return OFFICIAL_INSTANCE_HOSTS.some((officialHost) => officialHost === host);
|
|
}
|