@simitgroup/simpleapp-generator 1.6.6-u-alpha → 1.6.6-v-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 CHANGED
@@ -1,3 +1,6 @@
1
+ [1.6.6v-alpha]
2
+ 1. Fix webhook no store logs, and add api to obtain webhook execution histories
3
+
1
4
  [1.6.6u-alpha]
2
5
  1. Fix repo crash
3
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/buildinschemas/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA8B,MAAM,SAAS,CAAC;AAEjE,eAAO,MAAM,OAAO,EAAE,UAsIrB,CAAA"}
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/buildinschemas/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA8B,MAAM,SAAS,CAAC;AAEjE,eAAO,MAAM,OAAO,EAAE,UA+IrB,CAAA"}
@@ -10,7 +10,17 @@ exports.webhook = {
10
10
  "isolationType": type_1.IsolationType.branch,
11
11
  "uniqueKey": "title",
12
12
  "documentTitle": "title",
13
- "resourceName": "webhook"
13
+ "resourceName": "webhook",
14
+ additionalApis: [
15
+ {
16
+ action: 'getHistories',
17
+ entryPoint: ':id/histories',
18
+ requiredRole: ["Admin"],
19
+ method: type_1.RESTMethods.get,
20
+ responseType: '[Webhooklog]',
21
+ description: 'Get webhook execute histories'
22
+ }
23
+ ]
14
24
  },
15
25
  "required": [
16
26
  "title",
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/buildinschemas/webhook.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/buildinschemas/webhook.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"webhooklog.d.ts","sourceRoot":"","sources":["../../src/buildinschemas/webhooklog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA8B,MAAM,SAAS,CAAC;AAEjE,eAAO,MAAM,UAAU,EAAE,UAwExB,CAAA"}
1
+ {"version":3,"file":"webhooklog.d.ts","sourceRoot":"","sources":["../../src/buildinschemas/webhooklog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA8B,MAAM,SAAS,CAAC;AAEjE,eAAO,MAAM,UAAU,EAAE,UA4ExB,CAAA"}
@@ -13,6 +13,7 @@ exports.webhooklog = {
13
13
  },
14
14
  "required": [
15
15
  "title",
16
+ "webHookId",
16
17
  "body",
17
18
  "msg"
18
19
  ],
@@ -20,6 +21,9 @@ exports.webhooklog = {
20
21
  "_id": {
21
22
  "type": "string"
22
23
  },
24
+ "webHookId": {
25
+ "type": "string"
26
+ },
23
27
  "created": {
24
28
  "type": "string"
25
29
  },
@@ -1 +1 @@
1
- {"version":3,"file":"webhooklog.js","sourceRoot":"","sources":["../../src/buildinschemas/webhooklog.ts"],"names":[],"mappings":";;;AAAA,kCAAiE;AAEpD,QAAA,UAAU,GAAe;IACpC,MAAM,EAAE,QAAQ;IAChB,oBAAoB,EAAE;QACpB,cAAc,EAAE,YAAY;QAC5B,cAAc,EAAE,YAAY;QAC5B,eAAe,EAAE,oBAAa,CAAC,MAAM;QACrC,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,YAAY;KAC7B;IACD,UAAU,EAAE;QACV,OAAO;QACP,MAAM;QACN,KAAK;KACN;IACD,YAAY,EAAE;QACZ,KAAK,EAAE;YACL,MAAM,EAAE,QAAQ;SACjB;QACD,SAAS,EAAE;YACT,MAAM,EAAE,QAAQ;SACjB;QACD,SAAS,EAAE;YACT,MAAM,EAAE,QAAQ;SACjB;QACD,WAAW,EAAE;YACX,MAAM,EAAE,QAAQ;SACjB;QACD,WAAW,EAAE;YACX,MAAM,EAAE,QAAQ;SACjB;QACD,UAAU,EAAE;YACV,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;SACb;QACD,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;SACb;QACD,UAAU,EAAE;YACV,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;SACb;QACD,OAAO,EAAE;YACP,MAAM,EAAE,QAAQ;YAChB,WAAW,EAAE,CAAC;SACf;QACD,UAAU,EAAE;YACV,MAAM,EAAE,QAAQ;SACjB;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,QAAQ;SACjB;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,QAAQ;SACjB;QACD,QAAQ,EAAE;YACR,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAC,CAAC,SAAS,EAAC,QAAQ,CAAC;SAC5B;QACD,MAAM,EAAE;YACN,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAC,MAAM;YACf,WAAW,EAAC,CAAC;SACd;QACD,KAAK,EAAC;YACJ,MAAM,EAAC,QAAQ;SAChB;KAEF;CACF,CAAA"}
1
+ {"version":3,"file":"webhooklog.js","sourceRoot":"","sources":["../../src/buildinschemas/webhooklog.ts"],"names":[],"mappings":";;;AAAA,kCAAiE;AAEpD,QAAA,UAAU,GAAe;IACpC,MAAM,EAAE,QAAQ;IAChB,oBAAoB,EAAE;QACpB,cAAc,EAAE,YAAY;QAC5B,cAAc,EAAE,YAAY;QAC5B,eAAe,EAAE,oBAAa,CAAC,MAAM;QACrC,WAAW,EAAE,KAAK;QAClB,cAAc,EAAE,YAAY;KAC7B;IACD,UAAU,EAAE;QACV,OAAO;QACP,WAAW;QACX,MAAM;QACN,KAAK;KACN;IACD,YAAY,EAAE;QACZ,KAAK,EAAE;YACL,MAAM,EAAE,QAAQ;SACjB;QACD,WAAW,EAAE;YACX,MAAM,EAAE,QAAQ;SACjB;QACD,SAAS,EAAE;YACT,MAAM,EAAE,QAAQ;SACjB;QACD,SAAS,EAAE;YACT,MAAM,EAAE,QAAQ;SACjB;QACD,WAAW,EAAE;YACX,MAAM,EAAE,QAAQ;SACjB;QACD,WAAW,EAAE;YACX,MAAM,EAAE,QAAQ;SACjB;QACD,UAAU,EAAE;YACV,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;SACb;QACD,OAAO,EAAE;YACP,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;SACb;QACD,UAAU,EAAE;YACV,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC;SACb;QACD,OAAO,EAAE;YACP,MAAM,EAAE,QAAQ;YAChB,WAAW,EAAE,CAAC;SACf;QACD,UAAU,EAAE;YACV,MAAM,EAAE,QAAQ;SACjB;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,QAAQ;SACjB;QACD,YAAY,EAAE;YACZ,MAAM,EAAE,QAAQ;SACjB;QACD,QAAQ,EAAE;YACR,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAC,CAAC,SAAS,EAAC,QAAQ,CAAC;SAC5B;QACD,MAAM,EAAE;YACN,MAAM,EAAE,QAAQ;YAChB,QAAQ,EAAC,MAAM;YACf,WAAW,EAAC,CAAC;SACd;QACD,KAAK,EAAC;YACJ,MAAM,EAAC,QAAQ;SAChB;KAEF;CACF,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simitgroup/simpleapp-generator",
3
- "version": "1.6.6u-alpha",
3
+ "version": "1.6.6v-alpha",
4
4
  "description": "frontend nuxtjs and backend nests code generator using jsonschema",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -8,7 +8,16 @@ export const webhook: SchemaType = {
8
8
  "isolationType":IsolationType.branch,
9
9
  "uniqueKey": "title",
10
10
  "documentTitle": "title",
11
- "resourceName": "webhook"
11
+ "resourceName": "webhook",
12
+ additionalApis: [
13
+ {
14
+ action: 'getHistories',
15
+ entryPoint: ':id/histories',
16
+ requiredRole: ["Admin"],
17
+ method: RESTMethods.get,
18
+ responseType: '[Webhooklog]',
19
+ description: 'Get webhook execute histories'
20
+ }]
12
21
  },
13
22
  "required": [
14
23
  "title",
@@ -11,6 +11,7 @@ export const webhooklog: SchemaType = {
11
11
  },
12
12
  "required": [
13
13
  "title",
14
+ "webHookId",
14
15
  "body",
15
16
  "msg"
16
17
  ],
@@ -18,6 +19,9 @@ export const webhooklog: SchemaType = {
18
19
  "_id": {
19
20
  "type": "string"
20
21
  },
22
+ "webHookId": {
23
+ "type": "string"
24
+ },
21
25
  "created": {
22
26
  "type": "string"
23
27
  },
@@ -4,10 +4,10 @@
4
4
  * last change 2024-03-17
5
5
  * Author: Ks Tan
6
6
  */
7
- import { BadRequestException, Injectable,Inject, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common';
7
+ import { BadRequestException, Injectable, Inject, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common';
8
8
  import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
9
9
  import { UserContext } from './user.context';
10
- import { Webhook,Webhooklog } from '../types';
10
+ import { Webhook, Webhooklog } from '../types';
11
11
  import { alldocuments } from 'src/simpleapp/generate/commons/dicts/documents';
12
12
 
13
13
  @Injectable()
@@ -16,22 +16,21 @@ export class RunWebhookService {
16
16
  protected eventEmitter: EventEmitter2;
17
17
 
18
18
  protected logger = new Logger();
19
- protected maxRetries = 5
19
+ protected maxRetries = 5;
20
20
  public constructor() {}
21
21
 
22
-
23
-
24
22
  /**
25
23
  * trigger
26
24
  */
27
25
  async run(appuser: UserContext, documentName: string, actionName: string, data: any) {
28
- return await this.runRealtimeWebHook(appuser,documentName,actionName,data)
26
+ if (process.env.WEBHOOK_ONOFF && process.env.WEBHOOK_ONOFF.toLowerCase() == 'on') return await this.runRealtimeWebHook(appuser, documentName, actionName, data);
27
+ else this.logger.warn(`Webhook off, not run for ${documentName}:${actionName}`);
29
28
  }
30
29
  /**
31
30
  * get/delete
32
31
  * http://myendpoint.com/{orgid}/invoice/{documentid}/delete
33
32
  * http://myendpoint.com/{orgid}/invoice/{documentid}?action=delete
34
- *
33
+ *
35
34
  * post/put/patch
36
35
  * http://myendpoint.com/{orgid}/invoice/{documentid}
37
36
  * {json body}
@@ -40,131 +39,138 @@ export class RunWebhookService {
40
39
  this.logger.debug(`Run webhook ${documentName}, ${actionName}`);
41
40
  // console.log(`Run webhook ${documentName}, ${actionName}`);
42
41
 
43
-
44
- const webhooks = appuser.getWebHooks().filter(wh=>
45
- wh.resourceName==documentName && wh.eventType==actionName
46
- )
42
+ const webhooks = appuser.getWebHooks().filter((wh) => wh.resourceName == documentName && wh.eventType == actionName);
47
43
  // console.log(webhooks);
48
-
49
- //same resource,actionName may have multiple webhook, run 1 by 1
50
- for(let whNo=0;whNo<webhooks.length;whNo++){
51
44
 
52
- const webhook = webhooks[whNo]
53
- const reqMethod = webhook.requestMethod
54
- this.logger.verbose(webhook)
45
+ const systemVars = {
46
+ $xOrg: appuser.getXOrg(),
47
+ $accessToken: appuser.getUserToken(),
48
+ $fullName: appuser.getFullname(),
49
+ $email: appuser.getEmail(),
50
+ $uid: appuser.getUid(),
51
+ $resourceName: documentName,
52
+ $actionName: actionName,
53
+ };
54
+
55
+ //same resource,actionName may have multiple webhook, run 1 by 1
56
+ for (let whNo = 0; whNo < webhooks.length; whNo++) {
57
+ const webhook = webhooks[whNo];
58
+ const reqMethod = webhook.requestMethod;
59
+ let webhookUrl = webhook.url;
60
+ // this.logger.verbose(webhook);
55
61
  const headers = {};
56
-
62
+
63
+ Object.keys(systemVars).forEach((k) => {
64
+ webhookUrl = webhookUrl.replace('{{' + k + '}}', systemVars[k]);
65
+ });
66
+
57
67
  if (Array.isArray(webhook.headers)) {
58
68
  webhook.headers.forEach((h) => {
59
- h.value = h.value.replace('{{access_token}}',appuser.getUserToken())
60
- headers[h.name] = h.value;
69
+ let headerValue = h.value;
70
+ Object.keys(systemVars).forEach((k) => {
71
+ headerValue = headerValue.replace('{{' + k + '}}', systemVars[k]);
72
+ });
73
+
74
+ headers[h.name] = headerValue;
61
75
  });
62
76
  }
63
77
  headers['accept'] = 'application/json';
64
78
  headers['content-type'] = 'application/json';
65
- headers['x-org']=appuser.getXOrg()
66
- headers['x-resource-name']=documentName
67
- headers['x-action-name']=actionName
68
79
 
69
- if(webhook.authentication=='basic')
70
- headers['Authorization']= 'Basic ' + Buffer.from(webhook.basicAuth.user + ":" + webhook.basicAuth.password).toString('base64');
80
+ if (webhook.authentication == 'basic') headers['Authorization'] = 'Basic ' + Buffer.from(webhook.basicAuth.user + ':' + webhook.basicAuth.password).toString('base64');
81
+
82
+ // console.log(webhook)
71
83
 
72
- let tries = webhook.retryAttemps ?? 0
84
+ let tries: number = webhook.retryAttemps ?? 0;
73
85
  //first try need + 1
74
- tries = tries+1
86
+ tries = tries + 1;
75
87
  //hardcode max retries
76
- if(tries > this.maxRetries) tries = this.maxRetries
77
- const options:RequestInit = {
88
+ if (tries > this.maxRetries) tries = this.maxRetries;
89
+ const options: RequestInit = {
78
90
  method: reqMethod.toUpperCase(),
79
91
  headers: headers,
80
-
81
92
  };
82
- try {
83
- if(['POST','PUT','PATCH'].includes(options.method)){
84
- options.body= this.prepareBody(webhook,data)
85
- }
86
-
87
93
 
94
+ if (['POST', 'PUT', 'PATCH'].includes(options.method)) {
95
+ options.body = this.prepareBody(appuser, webhook, data, systemVars);
96
+ }
88
97
 
89
-
90
- while(tries>0){
91
- tries--
92
- console.log("Excute webhook id",webhook._id)
93
- const req = await fetch(webhook.url, options);
94
- const statusCode = req.status;
95
-
96
-
97
-
98
+ while (tries > 0) {
99
+ // console.log(`Excute webhook id ${webhook._id} max ${tries}`);
100
+ tries--;
101
+ let req: Response;
102
+ let msg = '';
103
+ let statusCode = 0;
104
+ try {
105
+ req = await fetch(webhookUrl, options);
106
+ statusCode = req.status;
107
+ //sucess, break and no more retry
98
108
  if (statusCode >= 200 && statusCode <= 300) {
99
109
  //success, continue next webhook
100
- const msg = `webhook triggered successfully for ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
101
- this.addLog(appuser,documentName,webhook,actionName,data,options,"success",statusCode,msg)
110
+ msg = `webhook triggered successfully for ${documentName}:${actionName}. ${reqMethod} ${webhookUrl}, try:${tries}, ${statusCode},${req.statusText}`;
111
+ this.addLog(appuser, documentName, webhook, actionName, data, options, 'success', statusCode, msg);
102
112
  break;
103
- }else if(tries<=0 && webhook.jobType=='roll-back-when-failed'){
104
- //failed, trigger server error for roll back
105
- const msg = `webhook faied, data roll back ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
106
- this.addLog(appuser,documentName,webhook,actionName,data,options,'failed',statusCode,msg)
107
- throw new InternalServerErrorException(msg);
108
- }else if(tries<=0 && webhook.jobType=='realtime'){
109
- //failed, but no need to trigger server error/rollback
110
- const msg = `webhook failed, ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
111
- this.addLog(appuser,documentName,webhook,actionName,data,options,'failed',statusCode,msg)
112
- }else{
113
- //failed, but still continue retry
114
- const msg = `webhook ${documentName}:${actionName}. ${reqMethod} ${webhook.url}, try:${tries}, ${statusCode},${req.statusText}`
115
- this.addLog(appuser,documentName,webhook,actionName,data,options,'warn',statusCode,msg)
113
+ } else {
114
+ //common error like 404
115
+ msg = `webhook ${statusCode} failed, ${documentName}:${actionName}. ${reqMethod} ${webhookUrl}, try:${tries}, ${statusCode},${req.statusText}`;
116
+ this.addLog(appuser, documentName, webhook, actionName, data, options, 'failed', statusCode, msg);
116
117
  }
117
-
118
+ } catch (e) {
119
+ // exception, usually server not accessible. use error 500
120
+ msg = `Webhook error ${documentName}:${actionName} (${webhook._id}) ${e} at ${webhookUrl}`;
121
+ this.addLog(appuser, documentName, webhook, actionName, data, options, 'failed', 500, msg);
118
122
  }
119
123
 
120
- // const body = req.body;
121
- } catch (e) {
122
- throw new InternalServerErrorException(e);
123
- }
124
-
125
- }
124
+ //finish tries, throw error
125
+ if (tries == 0 && webhook.jobType == 'roll-back-when-failed') {
126
+ throw new InternalServerErrorException(msg);
127
+ }
128
+ } //end retries
129
+ } //next webhook
126
130
 
127
- return true
131
+ return true;
128
132
  }
129
133
 
130
-
131
- addLog(appuser: UserContext, documentName: string, webhook:Webhook, actionName: string, data: any,options,status:string,statusCode:number,msg:string){
132
-
133
-
134
- if(status=='warn'){
135
- status="failed"
136
- this.logger.warn(msg)
134
+ addLog(appuser: UserContext, documentName: string, webhook: Webhook, actionName: string, data: any, options, status: string, statusCode: number, msg: string) {
135
+ if (status == 'success') {
136
+ this.logger.debug(msg);
137
+ } else {
138
+ this.logger.warn(msg);
137
139
  }
138
- else if(status=='success')
139
- this.logger.debug(msg)
140
- else
141
- this.logger.error (msg)
140
+ const logbody = options.body;
141
+ let body = JSON.stringify(logbody, null, 4);
142
142
 
143
- let body = JSON.stringify(options,null,4)
144
-
145
143
  const whlog: Webhooklog = {
144
+ _id: crypto.randomUUID(),
145
+ tenantId: appuser.getTenantId(),
146
+ orgId: appuser.getOrgId(),
147
+ branchId: appuser.getBranchId(),
148
+ webHookId: webhook._id,
149
+ created: new Date().toISOString(),
150
+ createdBy: appuser.getUid(),
146
151
  title: `${webhook.requestMethod} ${webhook.url}`,
147
152
  resource: documentName,
148
153
  actionName: actionName,
149
154
  status: status,
150
155
  statusCode: statusCode,
151
- body: body,
152
- msg:msg
153
- }
156
+ body: body,
157
+ msg: msg,
158
+ };
154
159
 
155
- this.eventEmitter.emit('webhooklog.add', appuser,whlog);
160
+ this.eventEmitter.emit('webhooklog.add', appuser, whlog);
156
161
  }
157
- prepareBody(webhook:Webhook,data:any){
158
- const cleandata = JSON.parse(JSON.stringify(data))
162
+ prepareBody(appuser: UserContext, webhook: Webhook, data: any, systemVars: any) {
163
+ const cleandata = JSON.parse(JSON.stringify(data));
159
164
 
160
- if(webhook.body?.trim()=='*'){
161
- return JSON.stringify(cleandata)
165
+ if (webhook.body?.trim() == '*') {
166
+ return JSON.stringify(cleandata);
162
167
  }
163
- const parse = require('json-templates');
164
- const template = parse(webhook.body);
165
- const x:BodyInit =template(cleandata)
166
- // this.logger.log(x)
167
- return JSON.parse(JSON.stringify(x))
168
- }
169
-
168
+ const finaldata = { ...cleandata, ...systemVars };
169
+
170
+ const parse = require('json-templates');
171
+ const template = parse(webhook.body);
172
+ const x: BodyInit = template(finaldata);
173
+ // this.logger.log(x)
174
+ return JSON.parse(JSON.stringify(x));
175
+ }
170
176
  }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR
4
+ * last change 2024-07-10
5
+ * Author: Ks Tan
6
+ * Last Modified By: Yong Xiang
7
+ */
8
+ import { UserContext } from '../commons/user.context';
9
+ import * as sharelibs from '../sharelibs';
10
+ import { Injectable } from '@nestjs/common';
11
+ import { InjectModel } from '@nestjs/mongoose';
12
+ import jsonpath from 'jsonpath';
13
+ import { Model } from 'mongoose';
14
+ import { WebhooklogJsonSchema } from '../jsonschemas/webhooklog.jsonschema';
15
+ import { SimpleAppService } from './simpleapp.processor';
16
+ import { IsolationType } from '../types';
17
+ import { DocNumberFormatGenerator } from '../commons/docnogenerator.service';
18
+ import { Webhooklog } from '../types/webhooklog.type';
19
+ import { DefaultWebhooklog } from '../defaults/webhooklog.default';
20
+ import { EventEmitter2, OnEvent } from '@nestjs/event-emitter';
21
+
22
+ @Injectable()
23
+ export class WebhooklogProcessor extends SimpleAppService<Webhooklog> {
24
+ protected documentIdentityCode = '_id';
25
+ protected documentIdentityLabel = '';
26
+
27
+ protected foreignkeys = {};
28
+ constructor(mydoc: Model<Webhooklog>) {
29
+ super('WEBHOOKLOG', 'webhooklog', mydoc, IsolationType.branch);
30
+ this.setSchema(WebhooklogJsonSchema);
31
+ this.setData(DefaultWebhooklog(crypto.randomUUID()));
32
+ }
33
+
34
+ reCalculateValue(data: Webhooklog) {
35
+ //console.log('trigger new recalculate')
36
+ const $data = data;
37
+ }
38
+ @OnEvent('webhooklog.add')
39
+ addLog(appuser: UserContext, whlog: Webhooklog) {
40
+ const newdoc = new this.doc(whlog);
41
+ newdoc.save();
42
+ }
43
+
44
+ /***************************** additional execute *****************************************/
45
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator. It is changable
3
+ * --remove-this-line-to-prevent-override--
4
+ * last change 2024-02-23
5
+ * Author: Ks Tan
6
+ */
7
+
8
+ import { InjectModel } from '@nestjs/mongoose';
9
+ import { Model } from 'mongoose';
10
+ import { Injectable } from '@nestjs/common';
11
+ import { UserContext } from '../generate/commons/user.context';
12
+ import { WebhookProcessor } from '../generate/processors/webhook.processor';
13
+ //import { Webhook,WebhookHooks} from '../generate/types';
14
+ import * as types from '../generate/types';
15
+ import { WebhooklogService } from './webhooklog.service';
16
+ export { Webhook } from '../generate/types';
17
+
18
+ @Injectable()
19
+ export class WebhookService extends WebhookProcessor {
20
+ //protected hooks: types.WebhookHooks = {}
21
+ constructor(
22
+ @InjectModel('Webhook') mydoc: Model<types.Webhook>,
23
+ private webhooklogService: WebhooklogService,
24
+ ) {
25
+ super(mydoc);
26
+ }
27
+
28
+ /***************************** begin x-document-api definitions *****************************************/
29
+
30
+
31
+ async runGetHistories(appuser: UserContext, id: string) {
32
+ const results = await this.webhooklogService.search(appuser, { webHookId: id });
33
+ return results;
34
+ }
35
+
36
+ /***************************** end x-document-api definitions *****************************************/
37
+ }
@@ -5,33 +5,40 @@
5
5
  * Author: Ks Tan
6
6
  */
7
7
 
8
- import { Webhook } from "../generate/types";
9
- const branch_hooks:Webhook[] = []
8
+ import { Webhook } from '../generate/types';
9
+ const branch_hooks: Webhook[] = [];
10
10
 
11
- branch_hooks.push({
12
- "_id": "branch.update",
13
- "title": "branch_update",
14
- "url": "https://localhost:8080",
15
- "requestMethod": "post",
16
- "authentication": "none",
17
- "description": "aa",
18
- "body": '{ "id":"{{_id}}", "code":"{{branchCode}}","name":"{{branchName}}" }',
19
- "active": false,
20
- "resourceName": "branch",
21
- "eventType": "update",
22
- "jobType": "realtime",
23
- "retryAttemps": 2,
24
- "basicAuth": {
25
- "user": "",
26
- "password": ""
11
+
12
+
13
+ branch_hooks.push({
14
+ _id: 'branch.create.welcome-msg',
15
+ title: 'branch first send well come message',
16
+ url: 'https://mywebhook.app.com/init-new-branch',
17
+ requestMethod: 'post',
18
+ authentication: 'none',
19
+ description: '',
20
+ body: `{
21
+ "email":"{{email}}",
22
+ "name":"{{$fullName}}",
23
+ "centerName":"{{branchName}}",
24
+ "centerUrl":"https://myurl.com"
25
+ }`,
26
+ active: false,
27
+ resourceName: 'branch',
28
+ eventType: 'update',
29
+ // jobType: 'roll-back-when-failed',
30
+ jobType: 'realtime',
31
+ retryAttemps: 2,
32
+ basicAuth: {
33
+ user: '',
34
+ password: '',
27
35
  },
28
- "headers": [
36
+ headers: [
29
37
  {
30
- "name": "token",
31
- "value": "{{access_token}}"
32
- }
33
- ]
34
- })
35
-
38
+ name: 'x-api-key',
39
+ value: 'xxxxxxxxxx',
40
+ },
41
+ ],
42
+ });
36
43
 
37
- export default branch_hooks
44
+ export default branch_hooks;
@@ -1,224 +0,0 @@
1
- /**
2
- * This file was automatically generated by simpleapp generator. Every
3
- * MODIFICATION OVERRIDE BY GENERATEOR
4
- * last change 2024-07-10
5
- * Author: Ks Tan
6
- * Last Modified By: Yong Xiang
7
- */
8
- import { UserContext } from '../commons/user.context';
9
- import * as sharelibs from '../sharelibs';
10
- import { Injectable, InternalServerErrorException, } from '@nestjs/common';
11
- import { InjectModel } from '@nestjs/mongoose';
12
- import jsonpath from 'jsonpath';
13
- import { Model } from 'mongoose';
14
- import { WebhookJsonSchema } from '../jsonschemas/webhook.jsonschema';
15
- import { SimpleAppService } from './simpleapp.processor';
16
- import * as types from '../types';
17
- import { DocNumberFormatGenerator } from '../commons/docnogenerator.service';
18
- import {
19
- WebhookBasicAuth,
20
- WebhookHeaders,
21
- Webhook,
22
- } from '../types/webhook.type';
23
- import {
24
- DefaultWebhookBasicAuth,
25
- DefaultWebhookHeaders,
26
- DefaultWebhook,
27
- } from '../defaults/webhook.default';
28
-
29
- @Injectable()
30
- export class WebhookProcessor extends SimpleAppService<Webhook> {
31
- protected documentIdentityCode = 'title';
32
- protected documentIdentityLabel = 'title';
33
- private webhookApiKey = process.env.WEBHOOK_SERVER_APIKEY
34
- private webhookAppId=process.env.WEBHOOK_SERVER_APP_ID
35
- private webhookurl = process.env.WEBHOOK_SERVER_URL;
36
- private webhookprefix = process.env.PROJECT_CODE+'.'
37
- private webhooksubscribtionurl = `${process.env.WEBHOOK_SERVER_URL}/subscriptions/`;
38
-
39
- protected hooks: types.WebhookHooks = {
40
- beforeCreate: async (appuser: UserContext, data: types.Webhook) =>
41
- this.beforeCreate(appuser, data),
42
- beforeUpdate: async (
43
- appuser: UserContext,
44
- id: string,
45
- prevdata: types.Webhook,
46
- newdata: types.Webhook,
47
- ) => this.beforeUpdate(appuser, id, prevdata, newdata),
48
- afterDelete: async (
49
- appuser: UserContext,
50
- result: types.DeleteResultType<types.Webhook>,
51
- id: string,
52
- ) => this.afterDelete(appuser, result, id),
53
- };
54
-
55
-
56
- protected foreignkeys = {};
57
- constructor(mydoc: Model<Webhook>) {
58
- super('WEBHOOK', 'webhook', mydoc, types.IsolationType.tenant);
59
- this.setSchema(WebhookJsonSchema);
60
- this.setData(DefaultWebhook(crypto.randomUUID()));
61
- }
62
-
63
- reCalculateValue(data: Webhook) {
64
- //console.log('trigger new recalculate')
65
- const $data = data;
66
- }
67
-
68
- async beforeCreate(appuser: UserContext, data: types.Webhook) {
69
- const createResult = await this.addRemoteWebhook(appuser, data);
70
- if (!createResult['subscription_id'])
71
- throw new InternalServerErrorException(
72
- 'syncronize webhook server failed',
73
- );
74
- data.serverSubscriptionId = createResult.subscription_id;
75
- data.serverSubscriptionSecret = createResult.secret;
76
- // throw new BadRequestException("fail purposely")
77
- }
78
-
79
- async beforeUpdate(
80
- appuser: UserContext,
81
- id: string,
82
- prevdata: types.Webhook,
83
- newdata: types.Webhook,
84
- ) {
85
-
86
- if(!prevdata.serverSubscriptionId){
87
- const createResult = await this.addRemoteWebhook(appuser, newdata);
88
- if (!createResult['subscription_id'])
89
- throw new InternalServerErrorException(
90
- 'syncronize webhook server failed',
91
- );
92
- newdata.serverSubscriptionId = createResult.subscription_id;
93
- newdata.serverSubscriptionSecret = createResult.secret;
94
- }else{
95
- await this.updateRemoteWebhook(appuser,newdata)
96
- }
97
- }
98
-
99
- async afterDelete(
100
- appuser: UserContext,
101
- result: types.DeleteResultType<types.Webhook>,
102
- id: string,
103
- ) {
104
- await this.removeRemoteWebhook(appuser,result,id)
105
- }
106
-
107
- async removeRemoteWebhook(
108
- appuser: UserContext,
109
- result: types.DeleteResultType<types.Webhook>,
110
- id: string,
111
- ){
112
- const options = {
113
- method: 'DELETE',
114
- headers: {Authorization: this.webhookApiKey}
115
- };
116
-
117
-
118
- const subscriptionId=result.data.serverSubscriptionId
119
- if(!subscriptionId)return
120
-
121
- try{
122
- const res = await fetch(
123
- `${this.webhooksubscribtionurl}/${subscriptionId}?application_id=${this.webhookAppId}`,
124
- options)
125
- }catch(e){
126
- throw new InternalServerErrorException(e)
127
- }
128
-
129
- }
130
- async addRemoteWebhook(appuser: UserContext, data: types.Webhook) {
131
- const headers = {};
132
- data.headers.forEach((h) => {
133
- headers[h.name] = h.value;
134
- });
135
-
136
- const options = {
137
- method: 'POST',
138
- headers: {
139
- Authorization: this.webhookApiKey,
140
- accept: 'application/json',
141
- 'content-type': 'application/json',
142
- },
143
- body: JSON.stringify({
144
- application_id: this.webhookAppId,
145
- description: data.title,
146
- metadata: {
147
- tenantId: data.tenantId.toString(),
148
- creator: appuser.getUname(),
149
- },
150
- is_enabled: data.active,
151
- event_types: data.eventTypes.map(
152
- (item) => this.webhookprefix + item,
153
- ),
154
- label_key: 'tenantId',
155
- label_value: data.tenantId.toString(),
156
- target: {
157
- headers: headers,
158
- type: 'http',
159
- method: data.requestMethod.toUpperCase(),
160
- url: data.url,
161
- },
162
- }),
163
- };
164
- try {
165
- const res = await fetch(this.webhooksubscribtionurl, options);
166
- return await res.json();
167
- if (res.status >= 300) {
168
- this.logger.error(res.statusText, 'create webhook failed');
169
- throw new InternalServerErrorException('create webhook failed');
170
- }
171
- } catch (e) {
172
- throw new InternalServerErrorException(e);
173
- }
174
- }
175
-
176
- async updateRemoteWebhook(appuser: UserContext, data: types.Webhook) {
177
- const headers = {};
178
- data.headers.forEach((h) => {
179
- headers[h.name] = h.value;
180
- });
181
-
182
- const options = {
183
- method: 'PUT',
184
- headers: {
185
- Authorization: this.webhookApiKey,
186
- accept: 'application/json',
187
- 'content-type': 'application/json',
188
- },
189
- body: JSON.stringify({
190
- application_id: this.webhookAppId,
191
- description: data.title,
192
- metadata: {
193
- tenantId: data.tenantId.toString(),
194
- creator: appuser.getUname(),
195
- },
196
- is_enabled: data.active,
197
- event_types: data.eventTypes.map(
198
- (item) => this.webhookprefix + item,
199
- ),
200
- label_key: 'tenantId',
201
- label_value: data.tenantId.toString(),
202
- target: {
203
- headers: headers,
204
- type: 'http',
205
- method: data.requestMethod.toUpperCase(),
206
- url: data.url,
207
- },
208
- }),
209
- };
210
- try {
211
- const subscriptionId = data.serverSubscriptionId
212
- const res = await fetch(`${this.webhooksubscribtionurl}/${subscriptionId}`, options);
213
- return await res.json();
214
- if (res.status >= 300) {
215
- this.logger.error(res.statusText, 'updateRemoteWebhook webhook failed');
216
- throw new InternalServerErrorException('update webhook failed');
217
- }
218
- } catch (e) {
219
- throw new InternalServerErrorException(e);
220
- }
221
- }
222
-
223
- /***************************** additional execute *****************************************/
224
- }