@simitgroup/simpleapp-generator 2.0.2-l-alpha → 2.0.2-n-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ReleaseNote.md +4 -0
- package/app-publish.sh +2 -0
- package/package.json +1 -1
- package/templates/basic/nest/schema.ts.eta +7 -5
- package/templates/nest/src/simple-app/_core/features/auth/keycloak/keycloak.guard.ts.eta +1 -1
- package/templates/nest/src/simple-app/_core/features/document-no-format/document-no-format.service.ts.eta +1 -1
- package/templates/nest/src/simple-app/_core/features/log/schemas/api-event.schema.ts.eta +3 -3
- package/templates/nest/src/simple-app/_core/features/log/schemas/document-event.schema.ts.eta +1 -1
- package/templates/nest/src/simple-app/_core/features/maintenance/schemas/db-update.ts.eta +3 -3
- package/templates/nest/src/simple-app/_core/features/profile/profile.schema.ts.eta +5 -5
- package/templates/nest/src/simple-app/_core/features/user-context/user.context.ts.eta +20 -18
- package/templates/nest/src/simple-app/_core/features/webhook/run-webhook.service.ts.eta +1 -1
- package/templates/nest/src/simple-app/_core/framework/base/simple-app.service.ts.eta +24 -26
- package/templates/nest/src/simple-app/_core/framework/schemas/others.schema.ts.eta +1 -1
- package/templates/nest/src/simple-app/_core/framework/schemas/simple-app.schema.ts.eta +2 -2
- package/templates/nest/src/simple-app/_core/framework/simple-app.interceptor.ts.eta +11 -14
- package/templates/nest/src/simple-app/_core/utils/string-utils.ts.eta +4 -1
package/ReleaseNote.md
CHANGED
package/app-publish.sh
CHANGED
package/package.json
CHANGED
|
@@ -19,6 +19,8 @@ export * from 'src/simple-app/_core/framework/schemas';
|
|
|
19
19
|
let tmptypename = typename.replace('[','').replace(']','')
|
|
20
20
|
if(proptype=='schema'){
|
|
21
21
|
tmptypename= upperFirstCase(tmptypename)
|
|
22
|
+
}else if(systemtypes.includes(typename)){
|
|
23
|
+
tmptypename = tmptypename.toLowerCase();
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
if(typename.includes('[')){
|
|
@@ -44,27 +46,27 @@ export * from 'src/simple-app/_core/framework/schemas';
|
|
|
44
46
|
@Prop({type: Object})
|
|
45
47
|
@Field(()=>GraphQLJSON)
|
|
46
48
|
@ApiProperty({ type:()=>Object,required: <%= required %>, default: {} })
|
|
47
|
-
<%= key %> <%=required ? '' :'?' %>:
|
|
49
|
+
<%= key %> <%=required ? '' :'?' %>: object;
|
|
48
50
|
<% } else { %>
|
|
49
51
|
|
|
50
52
|
@Prop()
|
|
51
53
|
@Field()
|
|
52
54
|
<% const newtypename= toTypeName(it.resourceName ,obj) %>
|
|
53
55
|
@ApiProperty({type: ()=><%=newtypename%>, required: <%= required %>})
|
|
54
|
-
<%= key %> <%=required ? '' :'?' %>: <%= newtypename %>;
|
|
56
|
+
<%= key %> <%=required ? '' :'?' %>: <%= getFieldType('type', newtypename, '') %>;
|
|
55
57
|
<% } %>
|
|
56
58
|
<%} else if(typeof obj.default !='undefined' && JSON.stringify(obj.default)=='{}'){%>
|
|
57
59
|
@Prop({type: Object})
|
|
58
60
|
@Field(()=>GraphQLJSON)
|
|
59
61
|
@ApiProperty({ type:()=>Object,required: <%= required %>, default: {} })
|
|
60
|
-
<%= key %> <%=required ? '' :'?' %>:
|
|
62
|
+
<%= key %> <%=required ? '' :'?' %>: object;
|
|
61
63
|
<% } else if( Array.isArray( obj)){%>
|
|
62
|
-
|
|
64
|
+
|
|
63
65
|
<% const newtypename= toTypeName(it.resourceName ,obj[0])%>
|
|
64
66
|
@Prop()
|
|
65
67
|
@Field(() => [<%=newtypename %>])
|
|
66
68
|
@ApiProperty({type: ()=>[<%= newtypename %>], required: <%= required %> })
|
|
67
|
-
<%= key %> <%=required ? '' :'?' %>: <%= newtypename %>[];
|
|
69
|
+
<%= key %> <%=required ? '' :'?' %>: <%= getFieldType('type', newtypename, '') %>[];
|
|
68
70
|
<% }else{%>
|
|
69
71
|
@Prop()
|
|
70
72
|
@Field()
|
|
@@ -31,7 +31,7 @@ export class CustomKeycloakGuard implements CanActivate {
|
|
|
31
31
|
// If API key is not present, fall back to Keycloak authentication
|
|
32
32
|
try {
|
|
33
33
|
const canActivate = await this.resourceGuard.canActivate(context);
|
|
34
|
-
return canActivate
|
|
34
|
+
return canActivate;
|
|
35
35
|
} catch (error) {
|
|
36
36
|
throw new UnauthorizedException('Invalid API key or Keycloak token');
|
|
37
37
|
}
|
|
@@ -23,7 +23,7 @@ export class SimpleAppDocumentNoFormatService {
|
|
|
23
23
|
{ $sort: { default: -1 } },
|
|
24
24
|
]);
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
const data: DocumentNoFormatPreview[] = [];
|
|
27
27
|
for (let i = 0; i < searchresult.length; i++) {
|
|
28
28
|
const s = searchresult[i];
|
|
29
29
|
if (s.active && s.docNoPattern) {
|
|
@@ -34,9 +34,9 @@ export class ApiEvent {
|
|
|
34
34
|
@Prop()
|
|
35
35
|
method: string;
|
|
36
36
|
@Prop({type:Object})
|
|
37
|
-
headers:
|
|
37
|
+
headers: object;
|
|
38
38
|
@Prop({type:Object})
|
|
39
|
-
data?:
|
|
39
|
+
data?: object;
|
|
40
40
|
@Prop()
|
|
41
41
|
statusCode: number;
|
|
42
42
|
@Prop()
|
|
@@ -44,7 +44,7 @@ export class ApiEvent {
|
|
|
44
44
|
@Prop()
|
|
45
45
|
errMsg?: string;
|
|
46
46
|
@Prop({type:Object})
|
|
47
|
-
errData?:
|
|
47
|
+
errData?: object;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export const ApiEventMongoSchema = SchemaFactory.createForClass(ApiEvent)
|
package/templates/nest/src/simple-app/_core/features/log/schemas/document-event.schema.ts.eta
CHANGED
|
@@ -74,7 +74,7 @@ export class DocumentEvent {
|
|
|
74
74
|
@Prop({ type: () => Object })
|
|
75
75
|
@Field(() => GraphQLJSON)
|
|
76
76
|
@ApiProperty({ type: () => Object, required: false, default: {} })
|
|
77
|
-
eventData:
|
|
77
|
+
eventData: object;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/***************************************** Start Auto Complete *****************************************/
|
|
@@ -9,9 +9,9 @@ import { ApiProperty } from '@nestjs/swagger';
|
|
|
9
9
|
|
|
10
10
|
export class UpgradeScript {
|
|
11
11
|
@ApiProperty({ type: String})
|
|
12
|
-
id:
|
|
12
|
+
id: string
|
|
13
13
|
@ApiProperty({ type: String})
|
|
14
|
-
subject:
|
|
14
|
+
subject:string
|
|
15
15
|
@ApiProperty({ type: String})
|
|
16
|
-
description:
|
|
16
|
+
description:string
|
|
17
17
|
}
|
|
@@ -103,9 +103,9 @@ export class ProfileUserBranch {
|
|
|
103
103
|
@ApiProperty({ type: BranchMinInfo })
|
|
104
104
|
branch: BranchMinInfo;
|
|
105
105
|
@ApiProperty({ type: String })
|
|
106
|
-
orgRecordId:
|
|
106
|
+
orgRecordId: string;
|
|
107
107
|
@ApiProperty({ type: String })
|
|
108
|
-
xOrg:
|
|
108
|
+
xOrg: string;
|
|
109
109
|
@ApiProperty({ type: Object, required: false })
|
|
110
110
|
organization?: any;
|
|
111
111
|
}
|
|
@@ -124,20 +124,20 @@ export class RegTenant {
|
|
|
124
124
|
examples: ['my company 1'],
|
|
125
125
|
default: '',
|
|
126
126
|
})
|
|
127
|
-
tenantName:
|
|
127
|
+
tenantName: string;
|
|
128
128
|
@ApiProperty({
|
|
129
129
|
type: String,
|
|
130
130
|
required: true,
|
|
131
131
|
examples: ['Asia/Kuala_Lumpur'],
|
|
132
132
|
default: '',
|
|
133
133
|
})
|
|
134
|
-
timeZone:
|
|
134
|
+
timeZone: string;
|
|
135
135
|
@ApiProperty({
|
|
136
136
|
type: Number,
|
|
137
137
|
required: true,
|
|
138
138
|
examples: [0, -460],
|
|
139
139
|
})
|
|
140
|
-
utcOffset:
|
|
140
|
+
utcOffset: number;
|
|
141
141
|
}
|
|
142
142
|
/****************------unchecked schema------********************/
|
|
143
143
|
|
|
@@ -578,15 +578,9 @@ export class UserContext extends UserContextInfo {
|
|
|
578
578
|
}
|
|
579
579
|
}
|
|
580
580
|
|
|
581
|
-
// Tenant permissions for DevSupport
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
Role.Tenant_access,
|
|
585
|
-
Role.Tenant_search,
|
|
586
|
-
Role.Tenant_create,
|
|
587
|
-
Role.Tenant_update,
|
|
588
|
-
Role.Tenant_delete,
|
|
589
|
-
];
|
|
581
|
+
// Tenant permissions for DevSupport and DevBilling roles
|
|
582
|
+
const tenantRoles = [Role.Tenant_access, Role.Tenant_search, Role.Tenant_create, Role.Tenant_update, Role.Tenant_delete];
|
|
583
|
+
if (this.roles.includes(Role.DevSupport) || this.roles.includes(Role.DevBilling)) {
|
|
590
584
|
for (let r = 0; r < tenantRoles.length; r++) {
|
|
591
585
|
if (!this.roles.includes(tenantRoles[r])) {
|
|
592
586
|
this.roles.push(tenantRoles[r]);
|
|
@@ -614,6 +608,20 @@ export class UserContext extends UserContextInfo {
|
|
|
614
608
|
}
|
|
615
609
|
}
|
|
616
610
|
|
|
611
|
+
// Grant Admin role to DevSupport and DevBilling for e-invoice
|
|
612
|
+
if (this.roles.includes(Role.DevSupport) || this.roles.includes(Role.DevBilling)) {
|
|
613
|
+
if (!this.roles.includes(Role.Admin)) {
|
|
614
|
+
this.roles.push(Role.Admin);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// Grant Billing role to DevBilling for tenant billing operations
|
|
619
|
+
if (this.roles.includes(Role.DevBilling)) {
|
|
620
|
+
if (!this.roles.includes(Role.Billing)) {
|
|
621
|
+
this.roles.push(Role.Billing);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
617
625
|
this.moreProps = this.setMoreProps(userProfile);
|
|
618
626
|
// this.package = userProfile['package'];
|
|
619
627
|
// this.appintegration = await this.setAppIntegration();
|
|
@@ -629,7 +637,7 @@ export class UserContext extends UserContextInfo {
|
|
|
629
637
|
// this.logger.verbose(`User ${this.uid} have _id (${this.getId()}), groups (${this.groups.join(',')}) and roles (${this.getRoles().join(',')}).`);
|
|
630
638
|
};
|
|
631
639
|
|
|
632
|
-
generateXOrg = (tenantId:
|
|
640
|
+
generateXOrg = (tenantId: number, orgId: number, branchId: number): string => {
|
|
633
641
|
return Base64URL.encodeText(`${tenantId}-${orgId}-${branchId}`);
|
|
634
642
|
};
|
|
635
643
|
|
|
@@ -870,7 +878,7 @@ export class UserContext extends UserContextInfo {
|
|
|
870
878
|
}
|
|
871
879
|
|
|
872
880
|
async getAllTenants(): Promise<TenantPermission[]> {
|
|
873
|
-
|
|
881
|
+
const results: TenantPermission[] = [];
|
|
874
882
|
if (this.getId() != '') {
|
|
875
883
|
const pipelines: PipelineStage[] = [
|
|
876
884
|
{
|
|
@@ -1160,13 +1168,7 @@ export class UserContext extends UserContextInfo {
|
|
|
1160
1168
|
}
|
|
1161
1169
|
|
|
1162
1170
|
if (this.roles.includes(Role.DevSupport)) {
|
|
1163
|
-
const tenantRoles = [
|
|
1164
|
-
Role.Tenant_access,
|
|
1165
|
-
Role.Tenant_search,
|
|
1166
|
-
Role.Tenant_create,
|
|
1167
|
-
Role.Tenant_update,
|
|
1168
|
-
Role.Tenant_delete,
|
|
1169
|
-
];
|
|
1171
|
+
const tenantRoles = [Role.Tenant_access, Role.Tenant_search, Role.Tenant_create, Role.Tenant_update, Role.Tenant_delete];
|
|
1170
1172
|
for (let r = 0; r < tenantRoles.length; r++) {
|
|
1171
1173
|
if (!this.roles.includes(tenantRoles[r])) {
|
|
1172
1174
|
this.roles.push(tenantRoles[r]);
|
|
@@ -140,7 +140,7 @@ export class RunWebhookService {
|
|
|
140
140
|
this.logger.warn(msg);
|
|
141
141
|
}
|
|
142
142
|
const logbody = options.body;
|
|
143
|
-
|
|
143
|
+
const body = typeof logbody == 'string' ? logbody : JSON.stringify(logbody, null, 4);
|
|
144
144
|
|
|
145
145
|
const whlog: WebhookLog = {
|
|
146
146
|
_id: crypto.randomUUID(),
|
|
@@ -17,14 +17,14 @@ import { AnyKeys, AnyObject, FilterQuery, Model, PipelineStage, mongo } from 'mo
|
|
|
17
17
|
// import { CloudApiService } from 'src/cloudapi/cloudapi.service';
|
|
18
18
|
import { foreignkeys } from '../../features/foreign-key/foreignkeys.dict';
|
|
19
19
|
|
|
20
|
+
import { Response } from 'express';
|
|
20
21
|
import { camelToKebab } from 'src/simple-app/_core/utils/string-utils';
|
|
21
22
|
import { SimpleAppDocumentNoFormatService } from '../../features/document-no-format/document-no-format.service';
|
|
22
23
|
import { SimpleAppLogService } from '../../features/log/log.service';
|
|
23
24
|
import { UserContext } from '../../features/user-context/user.context';
|
|
24
25
|
import { RunWebhookService } from '../../features/webhook/run-webhook.service';
|
|
25
|
-
import { DeleteResultType, IsolationType, MoreProjectionType, PatchManyRequest, SchemaFields,
|
|
26
|
+
import { DeleteResultType, IsolationType, MoreProjectionType, PatchManyRequest, SchemaFields, TextSearchBody, UniqueKeyExistResponse } from '../schemas';
|
|
26
27
|
import { SearchWithRelation } from './dto/simple-app-search-with-relation.dto';
|
|
27
|
-
import { Response } from 'express';
|
|
28
28
|
|
|
29
29
|
@Injectable()
|
|
30
30
|
export class SimpleAppService<T extends SchemaFields> {
|
|
@@ -209,12 +209,12 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
209
209
|
}
|
|
210
210
|
// return this;
|
|
211
211
|
}
|
|
212
|
-
async aggregateNoIsolation(appUser: UserContext, pipeline: PipelineStage[]) {
|
|
212
|
+
async aggregateNoIsolation<T>(appUser: UserContext, pipeline: PipelineStage[]) {
|
|
213
213
|
if (pipeline[0] && pipeline[0]['$match']) {
|
|
214
214
|
try {
|
|
215
215
|
this.logger.verbose(pipeline, `${this.documentName} aggregate:`);
|
|
216
216
|
|
|
217
|
-
return await this.doc.aggregate(pipeline, {
|
|
217
|
+
return await this.doc.aggregate<T>(pipeline, {
|
|
218
218
|
session: appUser.getDBSession(),
|
|
219
219
|
});
|
|
220
220
|
} catch (err) {
|
|
@@ -316,7 +316,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
316
316
|
const isolationFilter = { ...this.getIsolationFilter(appUser) };
|
|
317
317
|
this.polishIsolationFilter(isolationFilter);
|
|
318
318
|
|
|
319
|
-
const newfilters: FilterQuery<T> = { ...
|
|
319
|
+
const newfilters: FilterQuery<T> = { ...filters, ...isolationFilter };
|
|
320
320
|
|
|
321
321
|
let pageSize: number;
|
|
322
322
|
let pageNo: number;
|
|
@@ -345,7 +345,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
345
345
|
items = rows;
|
|
346
346
|
total = count;
|
|
347
347
|
} else {
|
|
348
|
-
const pipelines = this.searchToAggregate(appUser, newfilters, projection as any, sort
|
|
348
|
+
const pipelines = this.searchToAggregate(appUser, newfilters, projection as any, sort, lookup as any, { pageSize, pageNo });
|
|
349
349
|
|
|
350
350
|
const countPipeline: PipelineStage[] = [{ $match: newfilters }];
|
|
351
351
|
const collections = Object.keys(lookup);
|
|
@@ -430,7 +430,6 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
430
430
|
const pageNo = rawPageNo < 0 ? 0 : rawPageNo;
|
|
431
431
|
const skip = pageNo * finalPageSize;
|
|
432
432
|
|
|
433
|
-
|
|
434
433
|
return { pageSize: finalPageSize, skip, pageNo };
|
|
435
434
|
}
|
|
436
435
|
|
|
@@ -589,7 +588,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
589
588
|
await this.callWebhook(appUser, 'create', result);
|
|
590
589
|
return result as T;
|
|
591
590
|
} catch (err) {
|
|
592
|
-
await this.runErrorEvent(appUser, 'errorCreate', data, err)
|
|
591
|
+
await this.runErrorEvent(appUser, 'errorCreate', data, err);
|
|
593
592
|
throw new InternalServerErrorException(`createHook ${this.documentType} error: ${JSON.stringify(err)}`, `${this.documentType} createHook error`);
|
|
594
593
|
}
|
|
595
594
|
}
|
|
@@ -632,7 +631,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
632
631
|
ajv.addKeyword({ keyword: 'x-remote', schemaType: 'object' });
|
|
633
632
|
ajv.addKeyword({ keyword: 'x-readonly', schemaType: 'boolean' });
|
|
634
633
|
this.logger.debug('run hook during validation');
|
|
635
|
-
|
|
634
|
+
const issuccess = true;
|
|
636
635
|
// if (this.hooks.beforeValidation) {
|
|
637
636
|
// issuccess = await this.hooks.beforeValidation(appUser, data, _id);
|
|
638
637
|
// }
|
|
@@ -739,7 +738,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
739
738
|
if (err instanceof ForbiddenException) {
|
|
740
739
|
throw new ForbiddenException(err);
|
|
741
740
|
} else {
|
|
742
|
-
await this.runErrorEvent(appUser, 'errorDelete', deletedata, err)
|
|
741
|
+
await this.runErrorEvent(appUser, 'errorDelete', deletedata, err);
|
|
743
742
|
throw new InternalServerErrorException(err);
|
|
744
743
|
} //JSON.stringify(dependency),JSON.stringify(dependency)
|
|
745
744
|
}
|
|
@@ -862,7 +861,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
862
861
|
return result; // await this.findById(appUser, id);
|
|
863
862
|
} catch (err) {
|
|
864
863
|
this.logger.error(err);
|
|
865
|
-
await this.runErrorEvent(appUser, 'errorUpdate', data, err)
|
|
864
|
+
await this.runErrorEvent(appUser, 'errorUpdate', data, err);
|
|
866
865
|
throw new InternalServerErrorException(err.message);
|
|
867
866
|
}
|
|
868
867
|
};
|
|
@@ -1017,7 +1016,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
1017
1016
|
// };
|
|
1018
1017
|
|
|
1019
1018
|
const filter = data.filter;
|
|
1020
|
-
const patch = data.data as
|
|
1019
|
+
const patch = data.data as object;
|
|
1021
1020
|
|
|
1022
1021
|
const isolationFilter = { ...this.getIsolationFilter(appUser), ...(filter || {}) };
|
|
1023
1022
|
this.polishIsolationFilter(isolationFilter);
|
|
@@ -1115,7 +1114,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
1115
1114
|
await this.runEvent(appUser, 'beforeSetStatus', { docStatus: docstatus, prevData: existdata, newData: data }, false);
|
|
1116
1115
|
|
|
1117
1116
|
// if (this.hooks.beforeSetStatus) await this.hooks.beforeSetStatus(appUser, docstatus, data, existdata);
|
|
1118
|
-
try{
|
|
1117
|
+
try {
|
|
1119
1118
|
if (data && !data['created']) {
|
|
1120
1119
|
const createresult = await this.create(appUser, data);
|
|
1121
1120
|
await this.runEvent(appUser, 'afterSetStatus', { docStatus: docstatus, data: createresult }, false);
|
|
@@ -1132,8 +1131,8 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
1132
1131
|
await this.callWebhook(appUser, docstatus, finaldata);
|
|
1133
1132
|
return updateresult;
|
|
1134
1133
|
}
|
|
1135
|
-
}catch(e){
|
|
1136
|
-
await this.runErrorEvent(appUser, 'errorSetStatus', data, e)
|
|
1134
|
+
} catch (e) {
|
|
1135
|
+
await this.runErrorEvent(appUser, 'errorSetStatus', data, e);
|
|
1137
1136
|
}
|
|
1138
1137
|
}
|
|
1139
1138
|
|
|
@@ -1167,7 +1166,7 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
1167
1166
|
* @return {Promise} { description_of_the_return_value }
|
|
1168
1167
|
*/
|
|
1169
1168
|
async runEvent(appUser: UserContext, shortEventName: string, payloads: any, enforce: boolean = true) {
|
|
1170
|
-
const eventName = this.setHookName(shortEventName)
|
|
1169
|
+
const eventName = this.setHookName(shortEventName);
|
|
1171
1170
|
try {
|
|
1172
1171
|
if (enforce && !this.eventEmitter.hasListeners(eventName)) {
|
|
1173
1172
|
throw new InternalServerErrorException(`${eventName} seems no listener`);
|
|
@@ -1189,17 +1188,16 @@ export class SimpleAppService<T extends SchemaFields> {
|
|
|
1189
1188
|
}
|
|
1190
1189
|
}
|
|
1191
1190
|
|
|
1192
|
-
|
|
1193
|
-
const eventName = this.setHookName(shortEventName)
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
}
|
|
1199
|
-
}catch(e){
|
|
1200
|
-
//runErrorEvent wont handle more error
|
|
1191
|
+
async runErrorEvent(appUser: UserContext, shortEventName: string, payloads: any, error: any) {
|
|
1192
|
+
const eventName = this.setHookName(shortEventName);
|
|
1193
|
+
try {
|
|
1194
|
+
if (this.eventEmitter.hasListeners(eventName)) {
|
|
1195
|
+
console.log('run eventName', eventName);
|
|
1196
|
+
const res = await this.eventEmitter.emitAsync(eventName, appUser, payloads, error);
|
|
1201
1197
|
}
|
|
1202
|
-
|
|
1198
|
+
} catch (e) {
|
|
1199
|
+
//runErrorEvent wont handle more error
|
|
1200
|
+
}
|
|
1203
1201
|
}
|
|
1204
1202
|
// startWorkflow(appUser: UserContext, processName: WorkflowName, workflowData: any) {
|
|
1205
1203
|
// return this.eventEmitter.emit('workflow.start', appUser, processName, workflowData);
|
|
@@ -18,12 +18,12 @@ export class DocNumberFormatResult {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export class SearchBody {
|
|
21
|
-
filter?:
|
|
21
|
+
filter?: object;
|
|
22
22
|
|
|
23
23
|
fields?: any[];
|
|
24
24
|
|
|
25
25
|
sorts?: any[];
|
|
26
|
-
lookup?:
|
|
26
|
+
lookup?: object;
|
|
27
27
|
pagination?: {
|
|
28
28
|
pageSize?: number;
|
|
29
29
|
pageNo?: number;
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
* last change 2023-03-17
|
|
5
5
|
* Author: Ks Tan
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import { Observable, throwError } from 'rxjs';
|
|
9
|
-
import { catchError, tap, map } from 'rxjs/operators';
|
|
10
|
-
import { Model, Connection, ClientSession } from 'mongoose';
|
|
7
|
+
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
|
|
11
8
|
import { InjectConnection, InjectModel } from '@nestjs/mongoose';
|
|
9
|
+
import { Connection, Model } from 'mongoose';
|
|
10
|
+
import { Observable } from 'rxjs';
|
|
11
|
+
import { catchError, map, tap } from 'rxjs/operators';
|
|
12
12
|
import { UserContext } from '../features/user-context/user.context';
|
|
13
13
|
import { ApiEvent } from './schemas';
|
|
14
14
|
import { SimpleAppDbRevertService } from './simple-app-db-revert.service';
|
|
@@ -17,11 +17,10 @@ export class SimpleAppInterceptor implements NestInterceptor {
|
|
|
17
17
|
constructor(
|
|
18
18
|
@InjectConnection() private readonly connection: Connection,
|
|
19
19
|
@InjectModel('ApiEvent') private apieventmodel: Model<ApiEvent>,
|
|
20
|
-
private simpleAppDbRevertService:SimpleAppDbRevertService
|
|
20
|
+
private simpleAppDbRevertService: SimpleAppDbRevertService,
|
|
21
21
|
) {}
|
|
22
22
|
|
|
23
23
|
async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
|
|
24
|
-
|
|
25
24
|
//not http request then exclude such as graphql
|
|
26
25
|
if (context.getType() != 'http') {
|
|
27
26
|
// obtain usersession here
|
|
@@ -35,7 +34,6 @@ export class SimpleAppInterceptor implements NestInterceptor {
|
|
|
35
34
|
const resp = context.switchToHttp().getResponse();
|
|
36
35
|
//console.log("want to get user session:", Object.keys(req))
|
|
37
36
|
|
|
38
|
-
|
|
39
37
|
if (req.url == '/health') {
|
|
40
38
|
return next.handle().pipe(
|
|
41
39
|
tap(async () => {
|
|
@@ -44,7 +42,6 @@ export class SimpleAppInterceptor implements NestInterceptor {
|
|
|
44
42
|
);
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
|
|
48
45
|
const usersession: UserContext = req['sessionuser'];
|
|
49
46
|
//console.log("after read user session:",usersession)
|
|
50
47
|
const method = req['method'];
|
|
@@ -86,7 +83,7 @@ export class SimpleAppInterceptor implements NestInterceptor {
|
|
|
86
83
|
return next.handle().pipe(
|
|
87
84
|
map((data) => {
|
|
88
85
|
if (data && typeof data === 'object' && 'pagination' in data && 'items' in data) {
|
|
89
|
-
return data;
|
|
86
|
+
return data;
|
|
90
87
|
}
|
|
91
88
|
return data;
|
|
92
89
|
}),
|
|
@@ -94,7 +91,7 @@ export class SimpleAppInterceptor implements NestInterceptor {
|
|
|
94
91
|
// console.log('**************catchError at interceptor ',method,url)
|
|
95
92
|
if (usersession.inTransaction()) {
|
|
96
93
|
// await usersession.rollBackTransaction();
|
|
97
|
-
await usersession.rollBackTransaction(this.simpleAppDbRevertService)
|
|
94
|
+
await usersession.rollBackTransaction(this.simpleAppDbRevertService);
|
|
98
95
|
|
|
99
96
|
canCommit = false;
|
|
100
97
|
}
|
|
@@ -127,12 +124,12 @@ export class SimpleAppInterceptor implements NestInterceptor {
|
|
|
127
124
|
|
|
128
125
|
if (process.env.DRYRUN == 'true') {
|
|
129
126
|
// console.warn('--------dryrun! roll back everything-----------');
|
|
130
|
-
if (
|
|
131
|
-
await usersession.rollBackTransaction(this.simpleAppDbRevertService)
|
|
127
|
+
if (canCommit) {
|
|
128
|
+
await usersession.rollBackTransaction(this.simpleAppDbRevertService);
|
|
132
129
|
}
|
|
133
130
|
} else {
|
|
134
|
-
if (
|
|
135
|
-
await usersession.commitTransaction()
|
|
131
|
+
if (canCommit) {
|
|
132
|
+
await usersession.commitTransaction();
|
|
136
133
|
}
|
|
137
134
|
}
|
|
138
135
|
await usersession.endSession();
|
|
@@ -1 +1,4 @@
|
|
|
1
|
-
export const camelToKebab = (value) => value.replace(/([a-z])([A-Z])/g,
|
|
1
|
+
export const camelToKebab = (value) => value.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
2
|
+
|
|
3
|
+
export const escapeRegExp = (value: string): string =>
|
|
4
|
+
value.replace(/[\\^$.*+?()\[\]{}|]/g, '\\$&');
|