@etsoo/appscript
Version:
Applications shared TypeScript framework
132 lines (116 loc) • 2.9 kB
text/typescript
/**
* External endpoint
*/
export type ExternalEndpoint = {
/**
* API endpoint
*/
readonly endpoint: string;
/**
* Web url
*/
readonly webUrl: string;
};
/**
* External settings items
*/
export interface IExternalSettings extends ExternalEndpoint {
/**
* Message hub endpoint
*/
readonly messageHub?: string;
/**
* App root url
*/
readonly homepage: string;
/**
* Default hostname for substitution
* 用于替换的默认主机名
*/
hostname?: string;
/**
* Endpoints to other services
*/
readonly endpoints?: Record<
"platform" | "core" | "admin" | "finance" | "crm" | "oa" | "agile" | string,
ExternalEndpoint
>;
}
/**
* External settings namespace
*/
export namespace ExternalSettings {
/**
* Sub domain match regular expression
*/
export let subDomainMatch: RegExp = /(?<=\/\/)[0-9a-z]+(?=\.)/i;
/**
* Create settings instance
* @param settings Settings
* @returns Result
*/
export function create<T extends IExternalSettings = IExternalSettings>(
settings?: unknown,
hostname?: string
): T {
// Default settings reading from globalThis
settings ??= Reflect.get(globalThis, "settings");
if (settings) {
if (typeof settings === "string") {
settings = JSON.parse(settings);
}
if (
settings != null &&
typeof settings === "object" &&
"endpoint" in settings &&
"webUrl" in settings
) {
const s = settings as T;
if (hostname) s.hostname = hostname;
return s;
}
}
throw new Error("No external settings found");
}
/**
* Format the app
* @param hostname Hostname
* @param app App key
* @param endpoint Endpoint
* @returns Result
*/
export function formatApp(hostname: string, app: string, endpoint: string) {
return formatHost(endpoint, hostname).replace(subDomainMatch, app);
}
/**
* Format the host
* @param setting Setting
* @param hostname Hostname
* @returns Result
*/
export function formatHost(setting: string, hostname: string): string;
export function formatHost(
setting: Record<string, ExternalEndpoint>,
hostname?: string | null
): Record<string, ExternalEndpoint>;
export function formatHost(
setting: string | Record<string, ExternalEndpoint>,
hostname?: string | null
): string | Record<string, ExternalEndpoint> {
// Default hostname
hostname ??= globalThis.location.hostname;
if (typeof setting === "string") {
return setting.replace("{hostname}", hostname);
} else {
return Object.fromEntries(
Object.entries(setting).map(([key, value]) => [
key,
{
endpoint: formatApp(hostname, key, value.endpoint),
webUrl: formatApp(hostname, key, value.webUrl)
}
])
);
}
}
}