TorbatYar/frontend/lib/tenant-host.ts
Mortezakoohjani 12c8615615 Ship enterprise Accounting FE/API with CRUD parity and production wiring.
Adds accounting-service PATCH/archive, fiscal helpers, COA templates and setup status, plus SuperApp Accounting UI (DS, scoreboard, masters, vouchers, ledger, ops modules) with session refresh and HTTPS public API URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 15:26:43 +03:30

83 lines
1.9 KiB
TypeScript

/** تشخیص host پلتفرم در برابر ساب‌دامین tenant. */
const DEFAULT_BASE =
process.env.NEXT_PUBLIC_PLATFORM_BASE_DOMAIN || "torbatyar.ir";
const RESERVED = new Set([
"www",
"api",
"auth",
"identity",
"admin",
"app",
"mail",
"webmail",
]);
export interface TenantHostInfo {
hostname: string;
baseDomain: string;
/** اگر روی ساب‌دامین tenant باشیم */
isTenantHost: boolean;
slug: string | null;
/** دامنه apex پلتفرم */
isPlatformHost: boolean;
}
export function getBaseDomain(): string {
return DEFAULT_BASE.toLowerCase();
}
export function resolveTenantHost(
hostname?: string,
baseDomain: string = getBaseDomain()
): TenantHostInfo {
const host = (hostname || (typeof window !== "undefined" ? window.location.hostname : "") || "")
.split(":")[0]
.trim()
.toLowerCase();
const base = baseDomain.toLowerCase();
if (!host || host === "localhost" || host === "127.0.0.1") {
return {
hostname: host || "localhost",
baseDomain: base,
isTenantHost: false,
slug: null,
isPlatformHost: true,
};
}
if (host === base || host === `www.${base}`) {
return {
hostname: host,
baseDomain: base,
isTenantHost: false,
slug: null,
isPlatformHost: true,
};
}
if (host.endsWith(`.${base}`)) {
const sub = host.slice(0, -(base.length + 1));
if (sub && !sub.includes(".") && !RESERVED.has(sub)) {
return {
hostname: host,
baseDomain: base,
isTenantHost: true,
slug: sub,
isPlatformHost: false,
};
}
}
// دامنه اختصاصی احتمالی — فعلاً مثل tenant host با slug=null؛ API از Host resolve می‌کند
return {
hostname: host,
baseDomain: base,
isTenantHost: true,
slug: null,
isPlatformHost: false,
};
}