133 lines
5.6 KiB
TypeScript
133 lines
5.6 KiB
TypeScript
export type DomainRouteId = 'main' | 'sub' | 'zero' | 'zero-sense' | 'fifth';
|
|
|
|
export type PublicDomainVestibule = Readonly<{
|
|
routeId: DomainRouteId;
|
|
directoryNumber: '01' | '02' | '03' | '04' | '05';
|
|
stableDomainId: string;
|
|
hldpNumber: string;
|
|
displayName: string;
|
|
publicSummary: string;
|
|
responsibility: string;
|
|
repositoryId: string;
|
|
themeOwner: 'domain-team' | 'fifth-domain';
|
|
themeStatus: 'UNPUBLISHED' | 'SELECTED_REFERENCE';
|
|
themeLabel: string;
|
|
supportedNodeTypes: readonly ('local-terminal' | 'cloud-resident')[];
|
|
privateResourcesExposed: false;
|
|
}>;
|
|
|
|
const rawDirectory: PublicDomainVestibule[] = [
|
|
{
|
|
routeId: 'main',
|
|
directoryNumber: '01',
|
|
stableDomainId: 'DOMAIN-MAIN',
|
|
hldpNumber: 'HLDP-DOMAIN-MAIN-001',
|
|
displayName: '光湖主域',
|
|
publicSummary: '公共产品事实、发布与公告入口',
|
|
responsibility: '公共产品事实、正式发布、公告与公共回执。',
|
|
repositoryId: 'domain-main',
|
|
themeOwner: 'domain-team',
|
|
themeStatus: 'UNPUBLISHED',
|
|
themeLabel: '主题由光湖主域主控团队发布 · 当前未装载',
|
|
supportedNodeTypes: ['local-terminal', 'cloud-resident'],
|
|
privateResourcesExposed: false,
|
|
},
|
|
{
|
|
routeId: 'sub',
|
|
directoryNumber: '02',
|
|
stableDomainId: 'DOMAIN-SUB',
|
|
hldpNumber: 'HLDP-DOMAIN-SUB-001',
|
|
displayName: '光湖分域',
|
|
publicSummary: '行业入口与初始化频道目录',
|
|
responsibility: '行业入口、初始化频道与对应行业模块目录。',
|
|
repositoryId: 'domain-sub',
|
|
themeOwner: 'domain-team',
|
|
themeStatus: 'UNPUBLISHED',
|
|
themeLabel: '主题由光湖分域主控团队发布 · 当前未装载',
|
|
supportedNodeTypes: ['local-terminal', 'cloud-resident'],
|
|
privateResourcesExposed: false,
|
|
},
|
|
{
|
|
routeId: 'zero',
|
|
directoryNumber: '03',
|
|
stableDomainId: 'DOMAIN-ZERO',
|
|
hldpNumber: 'HLDP-DOMAIN-ZERO-001',
|
|
displayName: '光湖零域',
|
|
publicSummary: '实验、模块试装与质量验证入口',
|
|
responsibility: '实验、模块试装、真实预览与质量验证。',
|
|
repositoryId: 'domain-zero',
|
|
themeOwner: 'domain-team',
|
|
themeStatus: 'UNPUBLISHED',
|
|
themeLabel: '主题由光湖零域主控团队发布 · 当前未装载',
|
|
supportedNodeTypes: ['local-terminal', 'cloud-resident'],
|
|
privateResourcesExposed: false,
|
|
},
|
|
{
|
|
routeId: 'zero-sense',
|
|
directoryNumber: '04',
|
|
stableDomainId: 'DOMAIN-ZS',
|
|
hldpNumber: 'HLDP-DOMAIN-ZEROSENSE-001',
|
|
displayName: '光湖零感域',
|
|
publicSummary: '治理、审批、回滚与审计入口',
|
|
responsibility: '治理、部署审批、事故处置、回滚与审计。',
|
|
repositoryId: 'domain-zero-sense',
|
|
themeOwner: 'domain-team',
|
|
themeStatus: 'UNPUBLISHED',
|
|
themeLabel: '主题由光湖零感域主控团队发布 · 当前未装载',
|
|
supportedNodeTypes: ['local-terminal', 'cloud-resident'],
|
|
privateResourcesExposed: false,
|
|
},
|
|
{
|
|
routeId: 'fifth',
|
|
directoryNumber: '05',
|
|
stableDomainId: 'DOM-FIFTH-0001',
|
|
hldpNumber: 'DOM-FIFTH-0001',
|
|
displayName: '第五域 · 光湖本源域',
|
|
publicSummary: '零点原核的工程本体 · 语言架构层',
|
|
responsibility: '光湖语言世界的语言架构层与语言协议更新源点。',
|
|
repositoryId: 'REPO-012',
|
|
themeOwner: 'fifth-domain',
|
|
themeStatus: 'SELECTED_REFERENCE',
|
|
themeLabel: '湖面映星 · 已选定参考 · 进入后由独立运行体装载',
|
|
supportedNodeTypes: ['local-terminal', 'cloud-resident'],
|
|
privateResourcesExposed: false,
|
|
},
|
|
];
|
|
|
|
export function assertPublicDomainDirectory(directory: readonly PublicDomainVestibule[]): void {
|
|
if (directory.length !== 5) throw new Error('PUBLIC_DOMAIN_DIRECTORY_MUST_CONTAIN_FIVE_DOMAINS');
|
|
const unique = (values: string[]) => new Set(values).size === values.length;
|
|
if (!unique(directory.map(item => item.routeId))) throw new Error('PUBLIC_DOMAIN_ROUTE_ID_DUPLICATED');
|
|
if (!unique(directory.map(item => item.directoryNumber))) throw new Error('PUBLIC_DOMAIN_NUMBER_DUPLICATED');
|
|
if (!unique(directory.map(item => item.stableDomainId))) throw new Error('PUBLIC_DOMAIN_STABLE_ID_DUPLICATED');
|
|
if (directory.map(item => item.directoryNumber).join(',') !== '01,02,03,04,05') {
|
|
throw new Error('PUBLIC_DOMAIN_DIRECTORY_ORDER_INVALID');
|
|
}
|
|
const zero = directory.find(item => item.routeId === 'zero');
|
|
if (zero?.displayName !== '光湖零域') throw new Error('PUBLIC_DOMAIN_ZERO_NAME_INVALID');
|
|
const fifth = directory.find(item => item.routeId === 'fifth');
|
|
if (fifth?.themeOwner !== 'fifth-domain' || fifth.themeStatus !== 'SELECTED_REFERENCE') {
|
|
throw new Error('FIFTH_DOMAIN_THEME_REFERENCE_INVALID');
|
|
}
|
|
if (directory.some(item => item.routeId !== 'fifth' && (item.themeOwner !== 'domain-team' || item.themeStatus !== 'UNPUBLISHED'))) {
|
|
throw new Error('ENTERPRISE_DOMAIN_THEME_OWNERSHIP_INVALID');
|
|
}
|
|
if (directory.some(item => item.privateResourcesExposed !== false)) {
|
|
throw new Error('PUBLIC_VESTIBULE_MUST_NOT_EXPOSE_PRIVATE_RESOURCES');
|
|
}
|
|
if (directory.some(item => item.supportedNodeTypes.join(',') !== 'local-terminal,cloud-resident')) {
|
|
throw new Error('PUBLIC_VESTIBULE_NODE_TYPES_INVALID');
|
|
}
|
|
}
|
|
|
|
assertPublicDomainDirectory(rawDirectory);
|
|
|
|
export const publicDomainDirectory: readonly PublicDomainVestibule[] = Object.freeze(
|
|
rawDirectory.map(item => Object.freeze({ ...item, supportedNodeTypes: Object.freeze([...item.supportedNodeTypes]) }))
|
|
);
|
|
|
|
export function getPublicDomainVestibule(routeId: DomainRouteId): PublicDomainVestibule {
|
|
const entry = publicDomainDirectory.find(item => item.routeId === routeId);
|
|
if (!entry) throw new Error(`PUBLIC_DOMAIN_NOT_FOUND: ${routeId}`);
|
|
return entry;
|
|
}
|