@lcap/asl
Version:
NetEase Application Specific Language
268 lines (257 loc) • 7.19 kB
text/typescript
import { excludedInJSON, immutable } from '../decorators';
import { LEVEL_ENUM, Vertex, Service, WebService, MicroService, SERVICE_TYPE, utils, History, updateGenericTypeList } from '..';
import appService from '../../service/app';
interface AppLoadAllOptions {
asyncLoadServicesDetail?: boolean,
asyncLoadViewsDetail?: boolean,
}
/**
* 应用类
* @example OA
* @category App
*/
export class App extends Vertex {
/**
* 概念类型
*/
public readonly level: LEVEL_ENUM = LEVEL_ENUM.app;
/**
* App Id
*/
public readonly id: string = undefined;
/**
* Alias of id
*/
public readonly appId: string = undefined;
/**
* 应用标识
*/
public readonly name: string = undefined;
/**
* 应用标题
*/
public readonly title: string = undefined;
/**
* 应用图标
*/
public readonly icon: string = undefined;
/**
* 应用描述
*/
public readonly description: string = undefined;
/**
* 域名
*/
public readonly dnsAddr: string = undefined;
/**
* 官方类型
*/
public readonly officialType: 'offical' | 'nonofficial';
/**
* IDE 版本
*/
public readonly ideVersion: string = undefined;
/**
* 轻舟项目 Id
*/
public readonly projectId: string = undefined;
/**
* 租户 Id
*/
public readonly tenantId: string = undefined;
/**
* 租户 Id
*/
public readonly userGroupId: string = undefined;
/**
* h5 pc type
*/
public readonly scope: 'pc' | 'h5' = undefined;
/**
* 发布状态
*/
public readonly deploying: string = undefined;
/**
* 发布 Id,用于获取CICD详情
*/
public readonly deploymentId: string = undefined;
/**
* 应用下的服务
*/
public readonly services: Array<Service> = [];
/**
* 首个 Web 服务
* 后续 App 创建不了多个模块了,默认处理该服务
*/
public readonly firstWebService: WebService = undefined;
/**
* 首个 Web 服务
* 后续 App 创建不了多个模块了,默认处理该服务
*/
public readonly firstMicroService: MicroService = undefined;
/**
* 历史记录
* 用于处理撤销重做
*/
public readonly history: History = undefined;
/**
* @param source 需要合并的部分参数
*/
constructor(source?: Partial<App>) {
super();
source && this.assign(source);
this.history = new History({ app: this });
}
/**
* 加载详情并同步 envList 信息
* @requires this.id
*/
async loadEnvList(appDetail: any) {
if (!appDetail) {
appDetail = await appService.loadApp({
query: {
id: this.id,
},
});
}
const { envList } = appDetail.services
.find((service: any) => service.type === 'microService') || {};
this.assign({ envList });
}
/**
* 加载详情并同步 App 信息
* @requires this.id
*/
async load() {
const result = await appService.loadApp({
query: {
id: this.id,
},
});
await this.loadEnvList(result);
delete result.services;
this.assign(result);
return this;
}
/**
* 加载 App 下的所有服务
*/
async loadServices() {
const result = await appService.loadServices({
query: {
appId: this.id,
},
});
const services = result.map((service: Service) => {
if (service.type === SERVICE_TYPE.web) {
service = WebService.from(service, this);
if (!this.firstWebService)
this.assign({ firstWebService: service as WebService });
} else {
service = MicroService.from(service, this);
if (!this.firstMicroService)
this.assign({ firstMicroService: service as MicroService });
}
service.assign({ app: this });
return service;
});
await this.firstWebService.loadPackageInfo();
this.assign({ services });
return services;
}
/**
* 加载页面和逻辑详情
*/
async _loadViewsDetail() {
const tasks: Array<Promise<any>> = [];
this.firstWebService.pages.forEach((page) => {
utils.traverse((current) => {
if (current.node.level === 'view') {
const view = current.node;
view.$def.logics = []; // load syncDef 不会添加重复逻辑
tasks.push(view.load());
}
}, { node: page.rootView });
});
// 自动 load,不用 await
await Promise.all(tasks);
this.emit('loadViewsDetail');
}
/**
* 需要先调用 loadServices 之后再调用此函数
* 加载 App 下的服务具体内容
*/
private async _loadServicesDetail(options: AppLoadAllOptions = {
asyncLoadServicesDetail: false,
asyncLoadViewsDetail: false,
}) {
// 前端许多功能依赖后端数据,所以必须先 load 后端服务
// loadMicroService
await Promise.all([
this.firstMicroService.loadEntities(),
this.firstMicroService.loadStructures(),
this.firstMicroService.loadEnums(),
]);
// interfaces params 的 children 依赖 entities 和 structures,所以必须拆成两个 Promise
await Promise.all([
this.firstMicroService.loadInterfaces(),
this.firstMicroService.loadProcesses(),
]);
// loadWebService
await this.firstWebService.loadPages();
if (options.asyncLoadViewsDetail)
this._loadViewsDetail();
else
await this._loadViewsDetail();
this.emit('loadedAll');
}
/**
* 加载 App 下所有子节点
* @example
* const app = new App({ id: appId });
* await app.loadAll();
*/
async loadAll(options: AppLoadAllOptions = {
asyncLoadServicesDetail: false,
asyncLoadViewsDetail: false,
}) {
await Promise.all([
this.load(),
this.loadServices(),
updateGenericTypeList(),
]);
if (options.asyncLoadServicesDetail)
this._loadServicesDetail(options);
else
await this._loadServicesDetail(options);
}
/**
* 从后端 JSON 生成规范的 App 对象
* @param source JSON
*/
from(source: any) {
return new App(source);
}
}
export default App;