refactor: 统一userProject查询参数传递逻辑

This commit is contained in:
xiaojunnuo
2026-06-04 00:00:40 +08:00
parent cdb812ef63
commit 2cbacb4338
30 changed files with 158 additions and 134 deletions
+2
View File
@@ -15,6 +15,8 @@
代码可读性优先于短写法。遇到包含业务分支的复杂三元表达式、内联对象、链式调用或条件组合时,优先拆成命名清晰的中间变量、独立分支或小函数,让读代码的人能一眼看出业务意图;不要为了少写几行把逻辑压成难读的一坨。
在对象字面量、查询条件或函数参数里不要内联调用多层 helper,例如 `{ domain, ...this.buildUserProjectQuery(userId, projectId) }`。应先用命名变量承接结果,例如 `const userProjectQuery = this.buildUserProjectQuery(userId, projectId)`,再在对象里展开 `...userProjectQuery`,让条件构造和业务字段都更容易阅读。
## DRY
遵守 DRY 原则:同一业务规则、字段转换、权限判断、Repository 选择、事务传播、金额计算等逻辑不要在多个地方复制粘贴。第二次出现时可以先保持清晰,第三次出现前应优先抽成局部 helper、service 方法或已有公共工具;抽象要服务于减少真实重复和降低修改风险,不要为了形式上的“复用”制造过度设计。
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
+2 -1
View File
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
@@ -57,7 +57,7 @@ export abstract class BaseService<T> {
}
protected buildUserProjectQuery(userId: number, projectId?: number) {
const query: { userId: number; projectId?: number } = {
const query: { userId: number; projectId?: number; [key: string]: any } = {
userId,
};
if (projectId != null) {
@@ -282,12 +282,12 @@ export abstract class BaseService<T> {
async batchDelete(ids: number[], userId: number,projectId?:number) {
ids = this.filterIds(ids);
if(userId!=null){
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const list = await this.getRepository().find({
where: {
// @ts-ignore
id: In(ids),
userId,
projectId,
...userProjectQuery,
},
})
// @ts-ignore
@@ -225,11 +225,11 @@ export class AccessService extends BaseService<AccessEntity> {
if (userId == null) {
return [];
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
return await this.repository.find({
where: {
id: In(ids),
userId,
projectId,
...userProjectQuery,
},
select: {
id: true,
@@ -96,11 +96,11 @@ export class AddonService extends BaseService<AddonEntity> {
if (userId==null) {
return [];
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
return await this.repository.find({
where: {
id: In(ids),
userId,
projectId
...userProjectQuery,
},
select: {
id: true,
@@ -117,11 +117,11 @@ export class AddonService extends BaseService<AddonEntity> {
async getDefault(userId: number, addonType: string,projectId?:number): Promise<any> {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const res = await this.repository.findOne({
where: {
userId,
addonType,
projectId
...userProjectQuery,
},
order: {
isDefault: "DESC"
@@ -154,27 +154,17 @@ export class AddonService extends BaseService<AddonEntity> {
if (userId==null) {
throw new ValidateException("userId不能为空");
}
await this.repository.update(
{
userId,
addonType,
projectId
},
{
isDefault: false
}
);
await this.repository.update(
{
id,
userId,
addonType,
projectId
},
{
isDefault: true
}
);
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const query = {
addonType,
...userProjectQuery,
};
await this.repository.update(query, {
isDefault: false
});
await this.repository.update({ ...query, id }, {
isDefault: true
});
}
async getOrCreateDefault(opts: { addonType: string, type: string, inputs: any, userId: any,projectId?:number }) {
@@ -202,12 +192,12 @@ export class AddonService extends BaseService<AddonEntity> {
}
async getOneByType(req:{addonType:string,type:string,userId:number,projectId?:number}) {
const userProjectQuery = this.buildUserProjectQuery(req.userId, req.projectId);
return await this.repository.findOne({
where: {
addonType: req.addonType,
type: req.type,
userId: req.userId,
projectId: req.projectId
...userProjectQuery,
}
});
}
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}
@@ -1,7 +1,8 @@
<template>
<div class="refresh-input">
<div class="refresh-input-line">
<a-input class="refresh-input-control" :value="value" :placeholder="placeholder" :allow-clear="!disabled" :disabled="disabled" @update:value="emit('update:value', $event)"></a-input>
<a-input v-if="type !== 'textarea'" class="refresh-input-control" :value="value" :placeholder="placeholder" :allow-clear="!disabled" :disabled="disabled" @update:value="emit('update:value', $event)"></a-input>
<a-textarea v-else class="refresh-input-control" :value="value" :placeholder="placeholder" :rows="rows" :allow-clear="!disabled" :disabled="disabled" @update:value="emit('update:value', $event)"></a-textarea>
<fs-button :loading="loading" :disabled="disabled" type="primary" :text="buttonText" :icon="icon" @click="doRefresh"></fs-button>
</div>
<div class="helper" :class="{ error: hasError }">
@@ -26,6 +27,8 @@ type RefreshInputProps = ComponentPropsType & {
placeholder?: string;
successMessage?: string;
disabled?: boolean;
type?: string;
rows?: number;
};
const fromType: any = inject("getFromType");
@@ -84,10 +84,7 @@ export class DomainController extends CrudController<DomainService> {
@Post("/deleteByIds", { description: Constants.per.authOnly, summary: "批量删除域名" })
async deleteByIds(@Body(ALL) body: any) {
const { projectId, userId } = await this.getProjectUserIdRead();
await this.service.delete(body.ids, {
userId: userId,
projectId: projectId,
});
await this.service.batchDelete(body.ids, userId, projectId);
return this.ok();
}
@@ -82,10 +82,7 @@ export class CnameRecordController extends CrudController<CnameRecordService> {
@Post("/deleteByIds", { description: Constants.per.authOnly, summary: "批量删除CNAME记录" })
async deleteByIds(@Body(ALL) body: any) {
const { userId, projectId } = await this.getProjectUserIdWrite();
await this.service.delete(body.ids, {
userId,
projectId,
});
await this.service.batchDelete(body.ids, userId, projectId);
return this.ok();
}
@Post("/getByDomain", { description: Constants.per.authOnly, summary: "根据域名获取CNAME记录" })
@@ -54,9 +54,10 @@ export class CertApplyTemplateService extends BaseService<CertApplyTemplateEntit
}
async getDefault(userId: number, projectId?: number) {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
return await this.repository.findOne({
where: {
...this.buildUserProjectQuery(userId, projectId),
...userProjectQuery,
isDefault: true,
disabled: false,
},
@@ -84,10 +85,11 @@ export class CertApplyTemplateService extends BaseService<CertApplyTemplateEntit
}
private async getTemplateById(id: number, userId: number, projectId?: number) {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const template = await this.repository.findOne({
where: {
id,
...this.buildUserProjectQuery(userId, projectId),
...userProjectQuery,
},
});
if (!template) {
@@ -161,13 +161,13 @@ export class DnsPersistRecordService extends BaseService<DnsPersistRecordEntity>
}
async add(param: any) {
const record = await this.buildRecordByAcmeAccount(param);
const userProjectQuery = this.buildUserProjectQuery(param.userId, param.projectId);
const exists = await this.findOne({
where: {
domain: record.domain,
caType: record.caType,
acmeAccountAccessId: record.acmeAccountAccessId,
userId: param.userId,
projectId: param.projectId,
...userProjectQuery,
},
});
if (exists) {
@@ -225,13 +225,13 @@ export class DnsPersistRecordService extends BaseService<DnsPersistRecordEntity>
async getByDomain(req: DnsPersistRecordBuildReq & { userId: number; projectId?: number; createOnNotFound?: boolean }) {
const account = await this.getAcmeAccount(req);
const domain = this.normalizeDomain(req.domain);
const userProjectQuery = this.buildUserProjectQuery(req.userId, req.projectId);
let record = await this.findOne({
where: {
domain,
caType: account.caType,
acmeAccountAccessId: account.accessId,
userId: req.userId,
projectId: req.projectId,
...userProjectQuery,
},
});
if (!record && req.createOnNotFound) {
@@ -310,11 +310,11 @@ export class DnsPersistRecordService extends BaseService<DnsPersistRecordEntity>
const domainParser = new DomainParser(subDomainsGetter, logger);
const mainDomain = record.mainDomain || (await domainParser.parse(record.domain));
const domains = [...new Set([record.domain, mainDomain].filter(Boolean))];
const userProjectQuery = this.buildUserProjectQuery(record.userId, record.projectId);
const list = await this.domainRepository.find({
where: {
domain: In(domains),
userId: record.userId,
projectId: record.projectId,
...userProjectQuery,
challengeType: "dns",
disabled: false,
},
@@ -136,11 +136,11 @@ export class DomainService extends BaseService<DomainEntity> {
allDomains = [...new Set(allDomains)];
//从 domain 表中获取配置
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const domainRecords = await this.find({
where: {
domain: In(allDomains),
userId,
projectId,
...userProjectQuery,
disabled: false,
},
});
@@ -163,8 +163,7 @@ export class DomainService extends BaseService<DomainEntity> {
const cnameRecords = await this.cnameRecordService.find({
where: {
domain: In(allDomains),
userId,
projectId,
...userProjectQuery,
status: "valid",
},
});
@@ -286,11 +285,11 @@ export class DomainService extends BaseService<DomainEntity> {
domain = domain.slice(0, -1);
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const old = await this.findOne({
where: {
domain,
userId,
projectId,
...userProjectQuery,
},
});
if (old) {
@@ -573,19 +572,18 @@ export class DomainService extends BaseService<DomainEntity> {
const expireDays = setting.willExpireDays || 30;
const ltTime = dayjs().add(expireDays, "day").valueOf();
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const total = await this.repository.count({
where: {
userId,
projectId,
...userProjectQuery,
disabled: false,
},
});
//开始检查域名过期时间
const list = await this.repository.find({
where: {
userId,
projectId,
...userProjectQuery,
disabled: false,
expirationDate: LessThan(ltTime),
},
@@ -178,7 +178,13 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
if (userId == null) {
throw new ValidateException("userId不能为空");
}
let record = await this.getRepository().findOne({ where: { domain, userId, projectId } });
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
let record = await this.getRepository().findOne({
where: {
domain,
...userProjectQuery,
},
});
if (record == null) {
if (createOnNotFound) {
record = await this.add({ domain, userId, projectId });
@@ -501,12 +507,12 @@ export class CnameRecordService extends BaseService<CnameRecordEntity> {
async _import(req: { userId: number; projectId: number; domains: string[]; cnameProviderId: any }, task: BackTask) {
const userId = req.userId;
const userProjectQuery = this.buildUserProjectQuery(req.userId, req.projectId);
for (const domain of req.domains) {
const old = await this.getRepository().findOne({
where: {
userId: req.userId,
domain,
projectId: req.projectId,
...userProjectQuery,
},
});
if (old) {
@@ -37,23 +37,23 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
};
}
async getByKey(key: string, userId: number, projectId: number): Promise<UserSettingsEntity | null> {
async getByKey(key: string, userId: number, projectId?: number): Promise<UserSettingsEntity | null> {
if (userId == null) {
throw new Error("userId is required");
}
if (!key) {
return null;
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
return await this.repository.findOne({
where: {
key,
userId,
projectId,
...userProjectQuery,
},
});
}
async getSettingByKey(key: string, userId: number, projectId: number): Promise<any | null> {
async getSettingByKey(key: string, userId: number, projectId?: number): Promise<any | null> {
if (userId == null) {
throw new Error("userId is required");
}
@@ -65,11 +65,11 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
}
async save(bean: UserSettingsEntity) {
const userProjectQuery = this.buildUserProjectQuery(bean.userId, bean.projectId);
const entity = await this.repository.findOne({
where: {
key: bean.key,
userId: bean.userId,
projectId: bean.projectId,
...userProjectQuery,
},
});
if (entity) {
@@ -81,13 +81,13 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
}
}
async getSetting<T>(userId: number, projectId: number, type: any, cache = false): Promise<T> {
async getSetting<T>(userId: number, projectId: number | undefined, type: any, cache = false): Promise<T> {
if (userId == null) {
throw new Error("userId is required");
}
const key = type.__key__;
let cacheKey = key + "_" + userId;
if (projectId) {
if (projectId != null) {
cacheKey += "_" + projectId;
}
@@ -108,7 +108,7 @@ export class UserSettingsService extends BaseService<UserSettingsEntity> {
return newSetting;
}
async saveSetting<T extends BaseSettings>(userId: number, projectId: number, bean: T) {
async saveSetting<T extends BaseSettings>(userId: number, projectId: number | undefined, bean: T) {
if (userId == null) {
throw new Error("userId is required");
}
@@ -56,11 +56,11 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
}
async updateDomains(pipelineId: number, userId: number, projectId: number, domains: string[], fromType?: string) {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const found = await this.repository.findOne({
where: {
pipelineId,
userId,
projectId,
...userProjectQuery,
},
});
const bean = new CertInfoEntity();
@@ -112,6 +112,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
});
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const list = await this.find({
select: {
id: true,
@@ -120,8 +121,7 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
pipelineId: true,
},
where: {
userId,
projectId,
...userProjectQuery,
},
order: {
id: "DESC",
@@ -210,27 +210,25 @@ export class CertInfoService extends BaseService<CertInfoEntity> {
}
async count({ userId, projectId }: { userId: number; projectId?: number }) {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const total = await this.repository.count({
where: {
userId,
...userProjectQuery,
expiresTime: Not(IsNull()),
projectId,
},
});
const expired = await this.repository.count({
where: {
userId,
...userProjectQuery,
expiresTime: LessThan(new Date().getTime()),
projectId,
},
});
const expiring = await this.repository.count({
where: {
userId,
...userProjectQuery,
expiresTime: Between(new Date().getTime(), new Date().getTime() + 15 * 24 * 60 * 60 * 1000),
projectId,
},
});
@@ -531,7 +531,7 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
}
const query: any = { disabled: false };
query.userId = userId;
if (projectId) {
if (projectId != null) {
query.projectId = projectId;
}
const siteCount = await this.repository.count({
@@ -584,10 +584,10 @@ export class SiteInfoService extends BaseService<SiteInfoEntity> {
}
async batchDelete(ids: number[], userId: number, projectId?: number): Promise<void> {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
await this.repository.delete({
id: In(ids),
userId,
projectId,
...userProjectQuery,
});
}
}
@@ -285,11 +285,11 @@ export class SiteIpService extends BaseService<SiteIpEntity> {
throw new Error("siteId is required");
}
const userProjectQuery = this.buildUserProjectQuery(req.userId, req.projectId);
const siteEntity = await this.siteInfoRepository.findOne({
where: {
id: req.siteId,
userId: req.userId,
projectId: req.projectId,
...userProjectQuery,
},
});
if (!siteEntity) {
@@ -50,7 +50,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
this.checkNeedPlus(bean.type);
const res = await super.add(bean);
if (bean.isDefault) {
await this.setDefault(res.id, bean.userId);
await this.setDefault(res.id, bean.userId, bean.projectId);
}
bean.keyId = "nt_" + utils.id.simpleNanoId();
return res;
@@ -65,7 +65,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
delete bean.keyId;
const res = await super.update(bean);
if (bean.isDefault) {
await this.setDefault(bean.id, old.userId);
await this.setDefault(bean.id, old.userId, old.projectId);
}
return res;
@@ -86,11 +86,11 @@ export class NotificationService extends BaseService<NotificationEntity> {
if (userId == null) {
throw new ValidateException("userId不能为空");
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const res = await this.repository.findOne({
where: {
id,
userId,
projectId,
...userProjectQuery,
},
});
if (!res) {
@@ -111,10 +111,10 @@ export class NotificationService extends BaseService<NotificationEntity> {
}
async getDefault(userId: number, projectId?: number): Promise<NotificationInstanceConfig> {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const res = await this.repository.findOne({
where: {
userId,
projectId,
...userProjectQuery,
},
order: {
isDefault: "DESC",
@@ -133,12 +133,7 @@ export class NotificationService extends BaseService<NotificationEntity> {
if (userId == null) {
throw new ValidateException("userId不能为空");
}
const query: any = {
userId,
};
if (projectId) {
query.projectId = projectId;
}
const query = this.buildUserProjectQuery(userId, projectId);
await this.repository.update(query, {
isDefault: false,
});
@@ -876,41 +876,50 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
async count(param: { userId?: any; projectId?: number }) {
const query: any = {
userId: param.userId,
isTemplate: false,
};
if (param.projectId != null) {
query.projectId = param.projectId;
}
const count = await this.repository.count({
where: {
userId: param.userId,
projectId: param.projectId,
isTemplate: false,
},
where: query,
});
return count;
}
async statusCount(param: { userId?: any; projectId?: number } = {}) {
const query: any = {
userId: param.userId,
isTemplate: false,
};
if (param.projectId != null) {
query.projectId = param.projectId;
}
const statusCount = await this.repository
.createQueryBuilder()
.select("status")
.addSelect("count(1)", "count")
.where({
userId: param.userId,
projectId: param.projectId,
isTemplate: false,
})
.where(query)
.groupBy("status")
.getRawMany();
return statusCount;
}
async enableCount(param: { userId?: any; projectId?: number } = {}) {
const query: any = {
userId: param.userId,
isTemplate: false,
};
if (param.projectId != null) {
query.projectId = param.projectId;
}
const statusCount = await this.repository
.createQueryBuilder()
.select("disabled")
.addSelect("count(1)", "count")
.where({
userId: param.userId,
projectId: param.projectId,
isTemplate: false,
})
.where(query)
.groupBy("disabled")
.getRawMany();
const result = {
@@ -924,6 +933,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
async latestExpiringList({ userId, projectId }: any) {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
let list = await this.repository.find({
select: {
id: true,
@@ -931,9 +941,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
status: true,
},
where: {
userId,
...userProjectQuery,
disabled: false,
projectId,
isTemplate: false,
},
});
@@ -1262,6 +1271,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
}
async getSimplePipelines(pipelineIds: number[], userId?: number, projectId?: number) {
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
return await this.repository.find({
select: {
id: true,
@@ -1269,8 +1279,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
},
where: {
id: In(pipelineIds),
userId,
projectId,
...userProjectQuery,
},
});
}
@@ -26,10 +26,10 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
if (userId == null) {
return [];
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const list = await this.find({
where: {
userId,
projectId,
...userProjectQuery,
disabled: false,
},
});
@@ -45,11 +45,11 @@ export class SubDomainService extends BaseService<SubDomainEntity> {
if (userId == null) {
throw new Error("用户ID不能为空");
}
const userProjectQuery = this.buildUserProjectQuery(userId, projectId);
const exist = await this.repository.findOne({
where: {
domain,
userId,
projectId,
...userProjectQuery,
},
});
if (exist) {
@@ -144,20 +144,36 @@ export class AcmeAccountAccess extends BaseAccess {
action: "GenerateAccount",
buttonText: "生成ACME账号",
successMessage: "ACME账号已生成,请保存授权配置",
type:"textarea",
rows:4,
},
col:{span:24},
required: true,
helper: "请生成ACME账号,账号一旦生成不允许修改",
encrypt: true,
mergeScript: `
return {
component: {
disabled: ctx.compute(({form})=> !!form.access?.account)
disabled: ctx.compute(({form})=> !!form.access?.account && !form.access?.editAccount)
}
}
`,
})
account = "";
@AccessInput({
title: "修改ACME账号",
component: {
name: "a-switch",
vModel: "checked",
},
required: false,
helper: "是否开启修改ACME账号,注意,开启后,会影响DNS持久验证记录",
encrypt: false,
})
editAccount = false;
getDirectoryUrl() {
if (this.caType === "custom") {
if (!this.directoryUrl) {
@@ -180,7 +196,7 @@ export class AcmeAccountAccess extends BaseAccess {
throw new Error("该颁发机构需要填写EAB KID和EAB HMAC Key后才能生成账号");
}
const account = await this.createAccountInfo();
return JSON.stringify(account);
return JSON.stringify(account, null, 2);
}
private async createAccountInfo(): Promise<AcmeAccountInfo> {
+2 -1
View File
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"sourceMap": false,
"inlineSourceMap": false
"inlineSourceMap": false,
"declarationMap": true
}
}