@simitgroup/simpleapp-generator 1.2.1 → 1.2.3

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.
Files changed (22) hide show
  1. package/package.json +1 -1
  2. package/templates/basic/nest/service.ts.eta +4 -42
  3. package/templates/basic/nest/type.ts.eta +7 -0
  4. package/templates/basic/nuxt/pages.landing.vue.eta +1 -1
  5. package/templates/nest/src/simpleapp/generate/commons/interceptors/response.interceptor.ts.eta +1 -1
  6. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +59 -35
  7. package/templates/nest/src/simpleapp/generate/types/index.ts.eta +5 -57
  8. package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +76 -0
  9. package/templates/nest/src/simpleapp/services/autoinc.service.ts.eta +3 -35
  10. package/templates/nest/src/simpleapp/services/branch.service.ts.eta +19 -43
  11. package/templates/nest/src/simpleapp/services/docno.service.ts.eta +3 -36
  12. package/templates/nest/src/simpleapp/services/org.service.ts.eta +8 -36
  13. package/templates/nest/src/simpleapp/services/perm.service.ts.eta +3 -46
  14. package/templates/nest/src/simpleapp/services/tenant.service.ts.eta +9 -39
  15. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +17 -11
  16. package/templates/nuxt/components/simpleApp/SimpleAppForm.vue.eta +9 -6
  17. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +4 -1
  18. package/templates/nuxt/composables/stringHelper.generate.ts.eta +4 -1
  19. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +4 -4
  20. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +1 -1
  21. package/templates/nuxt/simpleapp/generate/defaults/index.ts.eta +4 -0
  22. package/templates/nest/src/simpleapp/generate/types/apievent.type.ts.eta +0 -22
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simitgroup/simpleapp-generator",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "frontend nuxtjs and backend nests code generator using jsonschema",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -9,9 +9,9 @@ import { Model } from 'mongoose';
9
9
  import { Injectable } from '@nestjs/common';
10
10
  import { UserContext } from '../generate/commons/user.context';
11
11
  import { <%= it.typename %>Processor } from '../generate/processors/<%= it.doctype %>.processor';
12
- import { <%= it.typename %>} from '../generate/types/<%= it.doctype %>.type';
13
- import {HookType} from '../generate/types'
14
- export { <%= it.typename %>} from '../generate/types/<%= it.doctype %>.type';
12
+ import { <%= it.typename %>,<%= it.typename %>Hooks} from '../generate/types';
13
+
14
+ export { <%= it.typename %>} from '../generate/types';
15
15
 
16
16
 
17
17
  @Injectable()
@@ -19,51 +19,13 @@ export class <%= it.typename %>Service extends <%= it.typename %>Processor {
19
19
  <% const config = it.jsonschema['x-simpleapp-config']%>
20
20
  <%if(config['loseDataIsolation']){%>protected strictIsolation = false;<%}%>
21
21
 
22
-
22
+ public hooks: <%= it.typename %>Hooks = {}
23
23
  constructor(
24
24
  @InjectModel('<%= it.typename %>') mydoc: Model<<%= it.typename %>>
25
25
  ){
26
26
  super(mydoc)
27
27
  }
28
28
 
29
- // hook = async (appuser:UserContext,type: HookType, data?: any) => {
30
- // switch(type){
31
- // case HookType.init: //data = undefined
32
- // break;
33
- // case HookType.beforeSearch: //data = filters
34
- // break;
35
- // case HookType.afterSearch: //data = search result
36
- // break;
37
- // case HookType.beforeValidation: //data = documentdata
38
- // break;
39
- // case HookType.afterValidation: //data = documentdata
40
- // break;
41
- // case HookType.beforeCreate: //data = documentdata
42
- // break;
43
- // case HookType.afterCreate: //data = after create result (final data from mongodb)
44
- // break;
45
- // case HookType.beforeUpdate: //data = documentdata
46
- // break;
47
- // case HookType.afterUpdate: //data = after update result (return from mongodb)
48
- // break;
49
- // case HookType.beforeDelete: //data = record _id
50
- // break;
51
- // case HookType.afterDelete: //data = deleted result
52
- // break;
53
- // case HookType.beforeFetchRecord: //data = record _id
54
- // break;
55
- // case HookType.afterFetchRecord: //data = document data
56
- // break;
57
- // case HookType.beforeSetStatus: //data = document data
58
- // break;
59
- // case HookType.afterSetStatus: //data = document data
60
- // break;
61
- // default:
62
- // break;
63
- // }
64
- // return true;
65
- // };
66
-
67
29
  /***************************** begin x-document-api definitions *****************************************/
68
30
  <% for(let i=0;i<it.apiSettings.length;i++){%>
69
31
  <% let api = it.apiSettings[i] %>
@@ -5,6 +5,7 @@
5
5
  * last change 2023-09-09
6
6
  * Author: Ks Tan
7
7
  */
8
+ import {DefaultHooks} from "../types"
8
9
 
9
10
  <%Object.keys(it.models).forEach(function(prop){ %>
10
11
  <% let schema = it.models[prop] %>
@@ -26,3 +27,9 @@
26
27
  }
27
28
  <%})%>
28
29
 
30
+
31
+
32
+ export type <%=it.typename%>Hooks = DefaultHooks<<%=it.typename%>> & {
33
+
34
+
35
+ }
@@ -12,7 +12,7 @@
12
12
  <script setup lang="ts">
13
13
  /**
14
14
  * This file was automatically generated by simpleapp everytime regenerate code.
15
- * delete file "delete-me-for-avoid-override" if you want to modify this file and
15
+ * delete file "delete-me.txt" if you want to modify this file and
16
16
  * prevent regenerate code override it.
17
17
  * last change 2023-09-09
18
18
  * author: Ks Tan
@@ -17,7 +17,7 @@ import { catchError, tap } from 'rxjs/operators';
17
17
  import { Model, Connection, ClientSession } from 'mongoose';
18
18
  import { InjectConnection, InjectModel } from '@nestjs/mongoose';
19
19
  import { UserContext } from '../user.context';
20
- import { ApiEvent } from '../../types/apievent.type';
20
+ import { ApiEvent } from '../../types';
21
21
  @Injectable()
22
22
  export class ResponseInterceptor implements NestInterceptor {
23
23
  constructor(
@@ -7,7 +7,8 @@
7
7
  import { Injectable, Logger, Inject } from '@nestjs/common';
8
8
  import { InjectModel } from '@nestjs/mongoose';
9
9
  import jsonpath from 'jsonpath';
10
- import { uniq } from 'lodash';
10
+ import _ from 'lodash';
11
+
11
12
  import { AuditTrail } from '../commons/audittrail.service';
12
13
  import { foreignkeys } from '../commons/dicts/foreignkeys';
13
14
  import { EventEmitter2 } from '@nestjs/event-emitter';
@@ -31,12 +32,12 @@ import {
31
32
  } from '@nestjs/common/exceptions';
32
33
  import { UserContext } from '../commons/user.context';
33
34
  import { DocNumberFormatGenerator } from '../commons/docnogenerator.service';
34
- import { IsolationType, HookType, MoreProjectionType } from '../types';
35
+ import { IsolationType, DefaultHooks, MoreProjectionType } from '../types';
35
36
  @Injectable()
36
37
  export class SimpleAppService<T extends { _id?: string }> {
37
38
  @Inject(EventEmitter2)
38
39
  protected eventEmitter: EventEmitter2;
39
-
40
+ protected hooks: DefaultHooks<T> = {};
40
41
  protected logger = new Logger();
41
42
  protected strictIsolation = true;
42
43
  protected jsonschema = { type: 'object', properties: {}, required: [] };
@@ -73,14 +74,15 @@ export class SimpleAppService<T extends { _id?: string }> {
73
74
  this.documentName = docname;
74
75
  this.doc = newdoc;
75
76
  this.isolationtype = isolationtype;
76
- this.hook(undefined, HookType.init, undefined);
77
+ if (this.hooks.init) this.hooks.init();
77
78
  // this.tenantdoc = tenantdoc
78
79
  }
79
80
  getDocumentType = () => this.documentType;
80
- getDocumentName = () => this.documentName;
81
+ getDocumentName = (capFirst:boolean=false) => capFirst ? _.upperFirst(this.documentName) :this.documentName;
81
82
  getRecordId = (): string => this.data._id;
82
83
  setSchema = (newschema) => (this.jsonschema = newschema);
83
84
  getSchema = () => this.doc.schema.obj;
85
+ getHooks = () => this.hooks;
84
86
  getData = () => {
85
87
  //console.log('thisdata', this.data);
86
88
  return this.data;
@@ -181,12 +183,15 @@ export class SimpleAppService<T extends { _id?: string }> {
181
183
  */
182
184
  private async searchNoIsolation(appuser: UserContext, filters: Object) {
183
185
  try {
184
- await this.hook(appuser, HookType.beforeSearch, filters);
186
+ if (this.hooks.beforeSearch)
187
+ await this.hooks.beforeSearch(appuser, filters);
185
188
  const products = await this.doc.find(filters);
186
189
  const productlist = products.map((p: T) => {
187
190
  return p;
188
191
  });
189
- await this.hook(appuser, HookType.afterSearch, productlist);
192
+ if (this.hooks.afterSearch)
193
+ await this.hooks.afterSearch(appuser, productlist);
194
+
190
195
  // console.log(products);
191
196
  return productlist;
192
197
  } catch (err) {
@@ -224,7 +229,9 @@ export class SimpleAppService<T extends { _id?: string }> {
224
229
 
225
230
  // console.log("initial search",filters)
226
231
  const newfilters = { ...filters, ...isolationFilter };
227
- await this.hook(appuser, HookType.beforeSearch, newfilters);
232
+
233
+ if (this.hooks.beforeSearch)
234
+ await this.hooks.beforeSearch(appuser, newfilters);
228
235
  // console.log("before _find",newfilters)
229
236
  // console.log("this.doc",this.doc)
230
237
  const products = await this.doc
@@ -235,7 +242,9 @@ export class SimpleAppService<T extends { _id?: string }> {
235
242
  return p;
236
243
  });
237
244
  // console.log("after map",productlist)
238
- await this.hook(appuser, HookType.afterSearch, productlist);
245
+ if (this.hooks.afterSearch)
246
+ await this.hooks.afterSearch(appuser, productlist);
247
+
239
248
  // console.log(products);
240
249
  return productlist;
241
250
  } catch (err) {
@@ -244,9 +253,12 @@ export class SimpleAppService<T extends { _id?: string }> {
244
253
  // return this;
245
254
  }
246
255
  async findById(appuser: UserContext, id: string) {
247
- await this.hook(appuser, HookType.beforeFetchRecord, id);
256
+ if (this.hooks.beforeFetchRecord)
257
+ await this.hooks.beforeFetchRecord(appuser, id);
248
258
  const data = await this.search(appuser, { _id: id });
249
- await this.hook(appuser, HookType.afterFetchRecord, data[0]);
259
+ if (this.hooks.afterFetchRecord)
260
+ await this.hooks.afterFetchRecord(appuser, data[0]);
261
+
250
262
  if (data.length == 1) {
251
263
  // console.log('data0', data[0]);
252
264
  return data[0];
@@ -276,8 +288,7 @@ export class SimpleAppService<T extends { _id?: string }> {
276
288
  await this.genNewDocNo(appuser, data);
277
289
  }
278
290
 
279
- await this.hook(appuser, HookType.beforeCreate, data);
280
-
291
+ if (this.hooks.beforeCreate) await this.hooks.beforeCreate(appuser, data);
281
292
  let isolationFilter: any = { ...appuser.getCreateFilter() };
282
293
  isolationFilter = this.polishIsolationFilter(isolationFilter, data);
283
294
 
@@ -288,10 +299,9 @@ export class SimpleAppService<T extends { _id?: string }> {
288
299
  Object.assign(data, isolationFilter);
289
300
  this.reCalculateValue(data);
290
301
  await this.validateData(appuser, data);
291
- this.logger.debug('Create record', 'SimpleAppService');
292
- this.logger.debug(data, 'SimpleAppService');
293
-
302
+ this.logger.debug(data, `after create validation`);
294
303
  this.applyNestedDateTime(appuser, data, 'create');
304
+ this.logger.debug(data, `Create Record ${this.documentName}`);
295
305
  const newdoc = new this.doc(data);
296
306
  await this.identifyForeignKeys(appuser, data);
297
307
  try {
@@ -306,7 +316,8 @@ export class SimpleAppService<T extends { _id?: string }> {
306
316
  // this.doc
307
317
 
308
318
  // result = await newdoc.save()
309
- await this.hook(appuser, HookType.afterCreate, result);
319
+
320
+ if (this.hooks.afterCreate) await this.hooks.afterCreate(appuser, result);
310
321
 
311
322
  return result as T;
312
323
  }
@@ -345,9 +356,6 @@ export class SimpleAppService<T extends { _id?: string }> {
345
356
  }
346
357
  }
347
358
  };
348
- hook = async (appuser: UserContext, type: string, data?: any) => {
349
- return true;
350
- };
351
359
  async validateData(appuser: UserContext, data: T) {
352
360
  const ajv = new Ajv({ allErrors: true, useDefaults: true });
353
361
  addFormats(ajv);
@@ -360,14 +368,18 @@ export class SimpleAppService<T extends { _id?: string }> {
360
368
 
361
369
  ajv.addKeyword({ keyword: 'x-foreignkey', schemaType: 'string' });
362
370
  ajv.addKeyword({ keyword: 'x-simpleapp-config', schemaType: 'object' });
363
-
364
- const issuccess = await this.hook(appuser, HookType.beforeValidation, data);
371
+ this.logger.debug('run hook during validation');
372
+ let issuccess = true;
373
+ if (this.hooks.beforeValidation) {
374
+ issuccess = await this.hooks.beforeValidation(appuser, data);
375
+ }
376
+ // const issuccess = await this.hook(appuser, HookType.beforeValidation, data);
365
377
  if (!issuccess) {
366
378
  const errormsg: string[] = [];
367
379
  for (let i = 0; i < this.errorlist.length; i++) {
368
380
  errormsg.push(this.errorlist[i].message);
369
381
  }
370
- this.logger.log('run hook during validation');
382
+
371
383
  throw new BadRequestException(
372
384
  'Before validation hook failed',
373
385
  errormsg as HttpExceptionOptions,
@@ -389,7 +401,8 @@ export class SimpleAppService<T extends { _id?: string }> {
389
401
  validate.errors as HttpExceptionOptions,
390
402
  );
391
403
  }
392
- await this.hook(appuser, HookType.afterValidation, data);
404
+ if (this.hooks.afterValidation)
405
+ await this.hooks.afterValidation(appuser, data);
393
406
  }
394
407
 
395
408
  polishIsolationFilter = (filterIsolation: any, data: any = {}) => {
@@ -431,7 +444,7 @@ export class SimpleAppService<T extends { _id?: string }> {
431
444
 
432
445
  let dependency;
433
446
  try {
434
- await this.hook(appuser, HookType.beforeDelete, id);
447
+ if (this.hooks.beforeDelete) await this.hooks.beforeDelete(appuser, id);
435
448
  this.logger.debug('delete record', this.documentName, id);
436
449
  dependency = await this.getRelatedRecords(id);
437
450
  //console.log('dependency', dependency);
@@ -452,8 +465,9 @@ export class SimpleAppService<T extends { _id?: string }> {
452
465
  ' delete result' + this.doc.collection.name,
453
466
  );
454
467
  // this.doc.findByIdAndDelete(id)
455
- await this.hook(appuser, HookType.afterDelete, deleteresult);
456
468
 
469
+ if (this.hooks.afterDelete)
470
+ await this.hooks.afterDelete(appuser, deleteresult, id);
457
471
  //this.doc.findByIdAndDelete(id);
458
472
  return deleteresult;
459
473
  } else {
@@ -481,7 +495,9 @@ export class SimpleAppService<T extends { _id?: string }> {
481
495
  if (!existingdata) {
482
496
  throw new NotFoundException(`${id} not found`, 'not found');
483
497
  }
484
- await this.hook(appuser, HookType.beforeUpdate, data);
498
+
499
+ if (this.hooks.beforeUpdate)
500
+ await this.hooks.beforeUpdate(appuser, id, data);
485
501
 
486
502
  const dbsession = appuser.getDBSession();
487
503
  if (!dbsession.inTransaction()) {
@@ -508,7 +524,9 @@ export class SimpleAppService<T extends { _id?: string }> {
508
524
  .findOneAndUpdate(isolationFilter, data)
509
525
  .session(dbsession);
510
526
  appuser.addUpdatedRecordId(this.documentName, data._id);
511
- await this.hook(appuser, HookType.afterUpdate, result);
527
+
528
+ if (this.hooks.afterUpdate)
529
+ await this.hooks.afterUpdate(appuser, id, result);
512
530
  return await this.findById(appuser, id);
513
531
  } catch (err) {
514
532
  throw new InternalServerErrorException(err.message);
@@ -590,17 +608,23 @@ export class SimpleAppService<T extends { _id?: string }> {
590
608
  }
591
609
 
592
610
  data['documentStatus'] = docstatus;
593
- await this.hook(appuser, HookType.beforeSetStatus, data);
611
+ // await this.hook(appuser, HookType.beforeSetStatus, data);
612
+ if (this.hooks.beforeSetStatus)
613
+ await this.hooks.beforeSetStatus(appuser, docstatus, data);
594
614
  if (data && !data['created']) {
595
615
  const createresult = await this.create(appuser, data);
596
- await this.hook(appuser, HookType.afterSetStatus, createresult);
616
+ if (this.hooks.afterSetStatus)
617
+ await this.hooks.afterSetStatus(appuser, docstatus, createresult);
618
+
597
619
  return createresult;
598
620
  } else {
599
- const originalresult = await this.findById(appuser,id)
600
- const newdata = {...originalresult,...data}
621
+ const originalresult = await this.findById(appuser, id);
622
+ const newdata = { ...originalresult, ...data };
601
623
  const updateresult = await this.findIdThenUpdate(appuser, id, newdata);
602
- const finaldata = await this.findById(appuser,id)
603
- await this.hook(appuser, HookType.afterSetStatus, finaldata);
624
+ const finaldata = await this.findById(appuser, id);
625
+ if (this.hooks.afterSetStatus)
626
+ await this.hooks.afterSetStatus(appuser, docstatus, finaldata);
627
+
604
628
  return updateresult;
605
629
  }
606
630
  }
@@ -655,7 +679,7 @@ export class SimpleAppService<T extends { _id?: string }> {
655
679
 
656
680
  if (results.length > 0) {
657
681
  if (results.length > 1) {
658
- results = uniq<string>(results);
682
+ results = _.uniq<string>(results);
659
683
  }
660
684
 
661
685
  keystore[collectionname] = results;
@@ -1,59 +1,7 @@
1
- /**
2
- * This file was automatically generated by simpleapp generator. Every
3
- * MODIFICATION OVERRIDE BY GENERATEOR
4
- * last change 2023-10-28
5
- * Author: Ks Tan
6
- */
7
- export type ForeignKey = {
8
- _id: string;
9
- label: string;
10
- };
11
- export type ModifiedCollection = {
12
- [key: string]: string[];
13
- };
14
- export type ModifiedRecords = {
15
- createds: ModifiedCollection;
16
- updateds: ModifiedCollection;
17
- deleteds: ModifiedCollection;
18
- };
19
- export type DocNumberFormatResult = {
20
- formatId: string;
21
- formatName: string;
22
- result: string;
23
- };
24
1
 
25
- export type SearchBody = {
26
- filter?: Object;
27
2
 
28
- fields?: any[];
29
-
30
- sorts?: any[];
31
- };
32
-
33
-
34
- export enum IsolationType {
35
- 'none' = 'none',
36
- 'org' = 'org',
37
- 'tenant' = 'tenant',
38
- 'branch' = 'branch',
39
- }
40
- export enum HookType {
41
- 'init' = 'init',
42
- 'beforeSearch' = 'beforeSearch',
43
- 'afterSearch' = 'afterSearch',
44
- 'beforeValidation' = 'beforeValidation',
45
- 'afterValidation' = 'afterValidation',
46
- 'beforeCreate' = 'beforeCreate',
47
- 'afterCreate' = 'afterCreate',
48
- 'beforeUpdate' = 'beforeUpdate',
49
- 'afterUpdate' = 'afterUpdate',
50
- 'beforeDelete' = 'beforeDelete',
51
- 'afterDelete' = 'afterDelete',
52
- 'beforeFetchRecord' = 'beforeFetchRecord',
53
- 'afterFetchRecord' = 'afterFetchRecord',
54
- 'beforeSetStatus'='beforeSetStatus',
55
- 'afterSetStatus'='afterSetStatus'
56
- }
57
- export type MoreProjectionType = {
58
- [key: string]: string;
59
- };
3
+ <%for(let i=0; i<it.modules.length;i++){ %>
4
+ <% const d = it.modules[i] %>
5
+ export * from './<%= d['doctype']%>.type'
6
+ <%}%>
7
+ export * from './simpleapp.type'
@@ -0,0 +1,76 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR
4
+ * last change 2024-01-25
5
+ * Author: Ks Tan
6
+ */
7
+ import { UserContext } from 'src/simpleapp/generate/commons/user.context';
8
+ export type ForeignKey = {
9
+ _id: string;
10
+ label: string;
11
+ };
12
+ export type ModifiedCollection = {
13
+ [key: string]: string[];
14
+ };
15
+ export type ModifiedRecords = {
16
+ createds: ModifiedCollection;
17
+ updateds: ModifiedCollection;
18
+ deleteds: ModifiedCollection;
19
+ };
20
+ export type DocNumberFormatResult = {
21
+ formatId: string;
22
+ formatName: string;
23
+ result: string;
24
+ };
25
+
26
+ export type SearchBody = {
27
+ filter?: Object;
28
+
29
+ fields?: any[];
30
+
31
+ sorts?: any[];
32
+ };
33
+
34
+
35
+ export enum IsolationType {
36
+ 'none' = 'none',
37
+ 'org' = 'org',
38
+ 'tenant' = 'tenant',
39
+ 'branch' = 'branch',
40
+ }
41
+ export type DefaultHooks<T> = {
42
+ init?: () => Promise<void> ;
43
+ beforeSearch?: (appuser:UserContext,filter:any) => Promise<void> ;
44
+ afterSearch?: (appuser:UserContext,data:T[]) => Promise<void> ;
45
+ beforeValidation?: (appuser:UserContext,data:T) => Promise<boolean> ;
46
+ afterValidation?: (appuser:UserContext,data:T) => Promise<void> ;
47
+ beforeCreate?: (appuser:UserContext,data:T) => Promise<void> ;
48
+ afterCreate?: (appuser:UserContext,data:T) => Promise<void> ;
49
+ beforeUpdate?: (appuser:UserContext,id:string,data:T) => Promise<void> ;
50
+ afterUpdate?: (appuser:UserContext,id:string,data:T) => Promise<void> ;
51
+ beforeDelete?: (appuser:UserContext,id:string) => Promise<void> ;
52
+ afterDelete?: (appuser:UserContext,data:any,id:string) => Promise<void> ;
53
+ beforeFetchRecord?: (appuser:UserContext,id:string) => Promise<void> ;
54
+ afterFetchRecord?: (appuser:UserContext,data:T) => Promise<void> ;
55
+ beforeSetStatus?: (appuser:UserContext,id:string,data:T) => Promise<void> ;
56
+ afterSetStatus ?: (appuser:UserContext,id:string,data:T) => Promise<void> ;
57
+ };
58
+ export type MoreProjectionType = {
59
+ [key: string]: string;
60
+ };
61
+ export type ApiEvent = {
62
+ _id: string
63
+ created: string
64
+ updated?:string
65
+ duration: number
66
+ createdBy: string
67
+ path: string
68
+ ip: string
69
+ method: string
70
+ headers: any
71
+ data?: any
72
+ statusCode:number
73
+ status:string
74
+ errMsg?:string
75
+ errData?: any
76
+ }
@@ -9,49 +9,17 @@ import { Model } from 'mongoose';
9
9
  import { Injectable } from '@nestjs/common';
10
10
  import { AutoincreamentProcessor } from '../generate/processors/autoinc.processor';
11
11
 
12
- import { Autoincreament } from '../generate/types/autoinc.type';
12
+ import { Autoincreament,AutoincreamentHooks } from '../generate/types';
13
13
  import { UserContext } from '../generate/commons/user.context';
14
- export { Autoincreament } from '../generate/types/autoinc.type';
14
+ export { Autoincreament } from '../generate/types';
15
15
 
16
16
  @Injectable()
17
17
  export class AutoincreamentService extends AutoincreamentProcessor {
18
+ hooks: AutoincreamentHooks = {};
18
19
  constructor(@InjectModel('Autoincreament') mydoc: Model<Autoincreament>) {
19
20
  super(mydoc);
20
21
  }
21
22
 
22
- // hook = async (appuser:UserContext,type: string, data?: any) => {
23
- // switch(type){
24
- // case 'init':
25
- // break;
26
- // case 'beforeSearch':
27
- // break;
28
- // case 'afterSearch':
29
- // break;
30
- // case 'beforeValidation':
31
- // break;
32
- // case 'afterValidation':
33
- // break;
34
- // case 'beforeCreate':
35
- // break;
36
- // case 'afterCreate':
37
- // break;
38
- // case 'beforeUpdate':
39
- // break;
40
- // case 'afterUpdate':
41
- // break;
42
- // case 'beforeDelete':
43
- // break;
44
- // case 'afterDelete':
45
- // break;
46
- // case 'beforeFetchRecord':
47
- // break;
48
- // case 'afterFetchRecord':
49
- // break;
50
- // default:
51
- // break;
52
- // }
53
- // return true;
54
- // };
55
23
 
56
24
  async runGenerateNextNo(
57
25
  appuser: UserContext,
@@ -8,16 +8,22 @@ import { InjectModel } from '@nestjs/mongoose';
8
8
  import { Model } from 'mongoose';
9
9
  import { Injectable, InternalServerErrorException } from '@nestjs/common';
10
10
  import { BranchProcessor } from '../generate/processors/branch.processor';
11
- import { Branch } from '../generate/types/branch.type';
11
+ import { Branch, BranchHooks } from '../generate/types';
12
12
  import { alldocuments } from '../generate/commons/dicts/documents';
13
- export { Branch } from '../generate/types/branch.type';
13
+
14
14
  import { AutoincreamentService } from './autoinc.service';
15
15
  import { UserContext } from '../generate/commons/user.context';
16
16
  import { Docnoformat, DocnoformatService } from './docno.service';
17
+
18
+ export { Branch } from '../generate/types';
17
19
  // import { Docnoformat } from '../generate/types/docno.type';
18
20
  @Injectable()
19
21
  export class BranchService extends BranchProcessor {
20
22
  protected strictIsolation = false;
23
+ protected hooks: BranchHooks = {
24
+ beforeCreate: async (appuser: UserContext, data: Branch) => await this.branchBeforeCreate(appuser,data),
25
+ afterCreate: async (appuser: UserContext, data: Branch) => await this.branchAfterCreate(appuser,data),
26
+ };
21
27
  constructor(
22
28
  @InjectModel('Branch') mydoc: Model<Branch>,
23
29
  private increament: AutoincreamentService,
@@ -25,47 +31,17 @@ export class BranchService extends BranchProcessor {
25
31
  ) {
26
32
  super(mydoc);
27
33
  }
28
-
29
- hook = async (appuser: UserContext, type: string, data?: any) => {
30
- switch (type) {
31
- // case 'init':
32
- // break;
33
- // case 'beforeSearch':
34
- // break;
35
- // case 'afterSearch':
36
- // break;
37
- // case 'beforeValidation':
38
- // break;
39
- // case 'afterValidation':
40
- // break;
41
- case 'beforeCreate':
42
- const searchresult = await this.increament.runGenerateNextNo(
43
- appuser,
44
- 'branch',
45
- 'branchId',
46
- );
47
- data.branchId = searchresult.nextno;
48
- break;
49
- case 'afterCreate':
50
- await this.generateDefaultDocNumbers(appuser, data);
51
- break;
52
- // case 'beforeUpdate':
53
- // break;
54
- // case 'afterUpdate':
55
- // break;
56
- // case 'beforeDelete':
57
- // break;
58
- // case 'afterDelete':
59
- // break;
60
- // case 'beforeFetchRecord':
61
- // break;
62
- // case 'afterFetchRecord':
63
- // break;
64
- // default:
65
- // break;
66
- }
67
- return true;
68
- };
34
+ async branchBeforeCreate(appuser: UserContext, data: Branch) {
35
+ const searchresult = await this.increament.runGenerateNextNo(
36
+ appuser,
37
+ 'branch',
38
+ 'branchId',
39
+ );
40
+ data.branchId = searchresult.nextno;
41
+ }
42
+ async branchAfterCreate(appuser: UserContext, data: Branch) {
43
+ await this.generateDefaultDocNumbers(appuser, data);
44
+ }
69
45
 
70
46
  generateDefaultDocNumbers = async (appuser, data) => {
71
47
  const branchName = data.branchName;
@@ -8,55 +8,22 @@ import { InjectModel } from '@nestjs/mongoose';
8
8
  import { Model } from 'mongoose';
9
9
  import { Injectable, InternalServerErrorException } from '@nestjs/common';
10
10
  import { DocnoformatProcessor } from '../generate/processors/docno.processor';
11
- import { Docnoformat } from '../generate/types/docno.type';
11
+ import { Docnoformat,DocnoformatHooks } from '../generate/types';
12
12
  import { UserContext } from '../generate/commons/user.context';
13
13
  import * as moment from 'moment';
14
14
  import { DocNumberFormatGenerator } from '../generate/commons/docnogenerator.service';
15
- export { Docnoformat } from '../generate/types/docno.type';
15
+ export { Docnoformat } from '../generate/types';
16
16
 
17
17
  @Injectable()
18
18
  export class DocnoformatService extends DocnoformatProcessor {
19
19
  protected strictIsolation = false;
20
+ hooks: DocnoformatHooks = {};
20
21
  constructor(
21
22
  @InjectModel('Docnoformat') mydoc: Model<Docnoformat>,
22
23
  ) {
23
24
  super(mydoc);
24
25
  }
25
26
 
26
- // hook = async (type: string, data?: any) => {
27
- // switch(type){
28
- // case 'init':
29
- // break;
30
- // case 'beforeSearch':
31
- // break;
32
- // case 'afterSearch':
33
- // break;
34
- // case 'beforeValidation':
35
- // break;
36
- // case 'afterValidation':
37
- // break;
38
- // case 'beforeCreate':
39
- // break;
40
- // case 'afterCreate':
41
- // break;
42
- // case 'beforeUpdate':
43
- // break;
44
- // case 'afterUpdate':
45
- // break;
46
- // case 'beforeDelete':
47
- // break;
48
- // case 'afterDelete':
49
- // break;
50
- // case 'beforeFetchRecord':
51
- // break;
52
- // case 'afterFetchRecord':
53
- // break;
54
- // default:
55
- // break;
56
- // }
57
- // return true;
58
- // };
59
-
60
27
  /**
61
28
  * list document number format and prepare sample of docformat
62
29
  * @param appuser
@@ -8,14 +8,17 @@ import { InjectModel } from '@nestjs/mongoose';
8
8
  import { Model } from 'mongoose';
9
9
  import { Injectable } from '@nestjs/common';
10
10
  import { OrganizationProcessor } from '../generate/processors/org.processor';
11
- import { Organization } from '../generate/types/org.type';
12
- export { Organization } from '../generate/types/org.type';
11
+ import { Organization,OrganizationHooks } from '../generate/types';
12
+ export { Organization } from '../generate/types';
13
13
  import { AutoincreamentService } from './autoinc.service';
14
14
  import { UserContext } from '../generate/commons/user.context';
15
15
 
16
16
  @Injectable()
17
17
  export class OrganizationService extends OrganizationProcessor {
18
18
  protected strictIsolation = false;
19
+ protected hooks : OrganizationHooks = {
20
+ beforeCreate: async (appuser: UserContext, data: Organization) => await this.orgBeforeCreate(appuser,data),
21
+ };
19
22
  constructor(
20
23
  @InjectModel('Organization') mydoc: Model<Organization>,
21
24
  private increament: AutoincreamentService,
@@ -23,43 +26,12 @@ export class OrganizationService extends OrganizationProcessor {
23
26
  super(mydoc);
24
27
  }
25
28
 
26
- hook = async (appuser: UserContext, type: string, data?: any) => {
27
- switch (type) {
28
- // case 'init':
29
- // break;
30
- // case 'beforeSearch':
31
- // break;
32
- // case 'afterSearch':
33
- // break;
34
- // case 'beforeValidation':
35
- // break;
36
- // case 'afterValidation':
37
- // break;
38
- case 'beforeCreate':
39
- const searchresult = await this.increament.runGenerateNextNo(
29
+ async orgBeforeCreate(appuser:UserContext,data:Organization){
30
+ const searchresult = await this.increament.runGenerateNextNo(
40
31
  appuser,
41
32
  'organization',
42
33
  'orgId',
43
34
  );
44
35
  data.orgId = searchresult.nextno;
45
- break;
46
- // case 'afterCreate':
47
- // break;
48
- // case 'beforeUpdate':
49
- // break;
50
- // case 'afterUpdate':
51
- // break;
52
- // case 'beforeDelete':
53
- // break;
54
- // case 'afterDelete':
55
- // break;
56
- // case 'beforeFetchRecord':
57
- // break;
58
- // case 'afterFetchRecord':
59
- // break;
60
- // default:
61
- // break;
62
- }
63
- return true;
64
- };
36
+ }
65
37
  }
@@ -8,63 +8,20 @@ import { InjectModel } from '@nestjs/mongoose';
8
8
  import { Model, PipelineStage } from 'mongoose';
9
9
  import { Injectable } from '@nestjs/common';
10
10
  import { PermissionProcessor } from '../generate/processors/perm.processor';
11
- import { Permission } from '../generate/types/perm.type';
11
+ import { Permission,PermissionHooks } from '../generate/types';
12
12
  import { UserContext } from '../generate/commons/user.context';
13
-
14
- export { Permission } from '../generate/types/perm.type';
13
+ export { Permission } from '../generate/types';
15
14
 
16
15
  @Injectable()
17
16
  export class PermissionService extends PermissionProcessor {
18
17
  protected strictIsolation = false;
18
+ protected hooks : PermissionHooks = {};
19
19
  constructor(
20
20
  @InjectModel('Permission') mydoc: Model<Permission>,
21
21
  ) {
22
22
  super(mydoc);
23
23
  }
24
24
 
25
- hook = async (appuser: UserContext, type: string, data?: any) => {
26
- switch (
27
- type
28
- // case 'init':
29
- // break;
30
- // case 'beforeSearch':
31
- // break;
32
- // case 'afterSearch':
33
- // break;
34
- // case 'beforeValidation':
35
- // break;
36
- // case 'afterValidation':
37
- // break;
38
- // case 'beforeCreate':
39
- // break;
40
- // case 'afterCreate':
41
- // break;
42
- // case 'beforeUpdate':
43
- // break;
44
- // case 'afterUpdate':
45
- // break;
46
- // case 'beforeDelete':
47
- // break;
48
- // case 'afterDelete':
49
- // case 'beforeDeleteMany':
50
- // this.logger.log(data, 'beforeDeleteMany');
51
- // this.deleteMany(appuser,data)
52
- // break;
53
- // case 'afterDeleteMany':
54
- // this.logger.log(data, 'afterDeleteMany', data);
55
- // break;
56
-
57
- // break;
58
- // case 'beforeFetchRecord':
59
- // break;
60
- // case 'afterFetchRecord':
61
- // break;
62
- // default:
63
- // break;
64
- ) {
65
- }
66
- return true;
67
- };
68
25
 
69
26
  async runListUser(appuser: UserContext) {
70
27
  const getallrecords: PipelineStage = { $match: {} };
@@ -9,13 +9,16 @@ import { InjectModel } from '@nestjs/mongoose';
9
9
  import { Model } from 'mongoose';
10
10
  import { Injectable } from '@nestjs/common';
11
11
  import { TenantProcessor } from '../generate/processors/tenant.processor';
12
- import { Tenant } from '../generate/types/tenant.type';
12
+ import { Tenant,TenantHooks } from '../generate/types';
13
13
  import { AutoincreamentService } from './autoinc.service';
14
14
  import { UserContext } from '../generate/commons/user.context';
15
- export { Tenant } from '../generate/types/tenant.type';
15
+ export { Tenant } from '../generate/types';
16
16
 
17
17
  @Injectable()
18
18
  export class TenantService extends TenantProcessor {
19
+ protected hooks : TenantHooks = {
20
+ beforeCreate: async (appuser: UserContext, data: Tenant) => await this.tenantBeforeCreate(appuser,data),
21
+ };
19
22
  constructor(
20
23
  @InjectModel('Tenant') mydoc: Model<Tenant>,
21
24
  private increament: AutoincreamentService,
@@ -24,45 +27,12 @@ export class TenantService extends TenantProcessor {
24
27
  super(mydoc);
25
28
  }
26
29
 
27
- hook = async (appuser: UserContext, type: string, data?: any) => {
28
- switch (type) {
29
- // case 'init':
30
- // break;
31
- // case 'beforeSearch':
32
- // break;
33
- // case 'afterSearch':
34
- // break;
35
- // case 'beforeValidation':
36
- // break;
37
- // case 'afterValidation':
38
- // break;
39
- case 'beforeCreate':
40
- const searchresult = await this.increament.runGenerateNextNo(
30
+ async tenantBeforeCreate(appuser:UserContext,data:Tenant){
31
+ const searchresult = await this.increament.runGenerateNextNo(
41
32
  appuser,
42
33
  'tenant',
43
34
  'tenantId',
44
35
  );
45
- data.tenantId = searchresult.nextno;
46
- data.uuid = crypto.randomUUID()
47
- break;
48
- // case 'afterCreate':
49
- // console.log('this.data',data)
50
- // break;
51
- // case 'beforeUpdate':
52
- // break;
53
- // case 'afterUpdate':
54
- // break;
55
- // case 'beforeDelete':
56
- // break;
57
- // case 'afterDelete':
58
- // break;
59
- // case 'beforeFetchRecord':
60
- // break;
61
- // case 'afterFetchRecord':
62
- // break;
63
- // default:
64
- // break;
65
- }
66
- return true;
67
- };
36
+ data.tenantId = searchresult.nextno;
37
+ }
68
38
  }
@@ -21,16 +21,15 @@
21
21
  <div v-else class="p-3 border rounded-lg border-gray-300 dark:border-blue-900/40 ">
22
22
  <span :readonly="readonly" class="cursor-pointer text-primary-600 dark:text-primary-400 "
23
23
  tabindex="0" @click="openViewer(true)">{{ modelValue && modelValue.label ? modelValue.label:'-' }}</span>
24
- </div>
24
+ </div>
25
25
  </template>
26
26
  <script setup lang="ts">
27
27
  import { isNull } from 'lodash';
28
+ import * as jsonpath from 'jsonpath';
28
29
  import {autocompletetype,SchemaConfig,SchemaType} from '~/types'
29
30
  const autocompleteinput = ref()
30
31
  const {$event} = useNuxtApp()
31
32
  const list = ref<any[]>([])
32
- const emptyautocomplete =():autocompletetype=> ({_id:'',code:'',label:''})
33
-
34
33
  const props = withDefaults(defineProps<{
35
34
  setting:any
36
35
  allowAddNew?:boolean
@@ -41,15 +40,22 @@ const props = withDefaults(defineProps<{
41
40
  }>(),{
42
41
  allowAddNew:true,showNull:true
43
42
  })
44
- const autocompleteitem = ref<autocompletetype>(emptyautocomplete())
43
+
44
+ const path = '$'+props.setting.instancepath
45
+ const modifiedpath = path.replaceAll('/','.')
46
+ const queryresult = jsonpath.query(props.setting.defaultValue,modifiedpath)[0]
47
+
48
+ const emptyautocomplete = computed(():autocompletetype=> queryresult)
49
+
50
+ const autocompleteitem = ref<autocompletetype>(emptyautocomplete.value)
45
51
  const modelValue = defineModel<autocompletetype>()
46
52
  if(modelValue.value && modelValue.value._id){
47
53
  autocompleteitem.value={...modelValue.value}
48
54
  }
49
55
  //clear auto complete auto set value = empty
50
56
  const clear = ()=>{
51
- autocompleteitem.value = emptyautocomplete()
52
- modelValue.value = emptyautocomplete()
57
+ autocompleteitem.value = emptyautocomplete.value
58
+ modelValue.value = emptyautocomplete.value
53
59
  }
54
60
  const buttonClass=computed(()=>modelValue.value?._id ? 'pi pi-link' : 'pi pi-angle-down')
55
61
 
@@ -63,7 +69,7 @@ const beforeShow = ()=>{
63
69
  //recorrect data if lose focus
64
70
  const onBlurAutocomplete = ()=>{
65
71
  if( autocompleteitem.value === null){
66
- autocompleteitem.value = emptyautocomplete()
72
+ autocompleteitem.value = emptyautocomplete.value
67
73
  }
68
74
  if(isNull(modelValue.value )){
69
75
  modelValue.value = autocompleteitem.value
@@ -94,13 +100,13 @@ const pickAutoComplete = (event:any)=>{
94
100
  console.log("event",event,'event.value._id',"'"+event.value._id+"'")
95
101
  if(event.value._id===''){
96
102
 
97
- modelValue.value = emptyautocomplete()
98
- autocompleteitem.value = emptyautocomplete()
103
+ modelValue.value = emptyautocomplete.value
104
+ autocompleteitem.value = emptyautocomplete.value
99
105
  console.log(modelValue.value )
100
106
  } else if(event.value._id==='new'){
101
107
 
102
- modelValue.value = emptyautocomplete()
103
- autocompleteitem.value = emptyautocomplete()
108
+ modelValue.value = emptyautocomplete.value
109
+ autocompleteitem.value = emptyautocomplete.value
104
110
  openViewer(false)
105
111
  }
106
112
  else if(typeof event.value.query == 'undefined'){
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <form class="simpleapp-form" @submit.prevent="true">
2
+ <form class="simpleapp-form" @submit.prevent="true">
3
3
  <slot name="header"><h3 class="flex flex-col">{{ title }}</h3></slot>
4
4
  <slot name="default" :data="document.getData()" :getField="getField"></slot>
5
5
  </form>
@@ -9,7 +9,8 @@
9
9
  import * as jsonpath from 'jsonpath';
10
10
  import { SimpleAppClient } from '~/simpleapp/generate/clients/SimpleAppClient'
11
11
  import type { JSONSchema7,JSONSchema7Definition } from 'json-schema';
12
- import _ from 'lodash'
12
+ import * as alldefaults from '~/simpleapp/generate/defaults'
13
+ import _, { upperFirst } from 'lodash'
13
14
  const props = defineProps<{
14
15
  title?:string,
15
16
  document: SimpleAppClient<any,any>
@@ -29,7 +30,11 @@ import _ from 'lodash'
29
30
  const fieldsetting = getPathObject(schema,path)
30
31
  // console.log("setting",fieldsetting)
31
32
 
33
+ type defaulttype = typeof alldefaults
34
+ type keytype = keyof defaulttype
32
35
 
36
+ const x : keytype = 'Default'+ props.document.getDocName(true) as keytype
37
+ const defaultvalue = alldefaults[x](crypto.randomUUID())
33
38
  return {
34
39
  path: path,
35
40
  key: _.last(path.split('/')),
@@ -41,15 +46,13 @@ import _ from 'lodash'
41
46
  modelField: 'email',
42
47
  isrequired: getIsRequired(schema,path),
43
48
  errors: props.document.getErrors(),
44
- readonly: isreadonly.value
49
+ readonly: isreadonly.value,
50
+ defaultValue: defaultvalue
45
51
  } //as SimpleAppFieldSetting
46
52
  }
47
53
 
48
54
  // "schemaPath": "#/properties/email/format",
49
55
 
50
- const getModelValue=(data:any,path:string)=>{
51
-
52
- }
53
56
  const getIsRequired=(schema:any,path:string)=>{
54
57
  if(!path){
55
58
  console.error('unknown path')
@@ -10,12 +10,15 @@ import axios from 'axios'
10
10
 
11
11
 
12
12
  const getAxiosConfig = () => {
13
+ const suffix = getCurrentXorg() ? '/'+getCurrentXorg() : ''
13
14
  const config: o.Configuration = {
14
- basePath: `${useRuntimeConfig().public.APP_URL}/api/${getCurrentXorg()}`,
15
+ basePath: `${useRuntimeConfig().public.APP_URL}/api${suffix}`,
15
16
  isJsonMime: () => true,
16
17
  };
17
18
  return config
18
19
  }
20
+
21
+
19
22
  export const getApiSession = async ()=> {
20
23
  const res = await (new o.PROFILEApi(getAxiosConfig(),undefined,useNuxtApp().$axios)).getSession()
21
24
  return res
@@ -1,4 +1,6 @@
1
1
  import plugin from 'primevue/config';
2
+ import _ from 'lodash'
3
+
2
4
  import {Md5} from 'ts-md5'
3
5
  import moment from "moment";
4
6
  export const camelCaseToWords = (s: string) =>{
@@ -19,4 +21,5 @@ export const t = (txt:string,options?:any):string => useNuxtApp().$i18n.t(txt,op
19
21
  export const today = () => moment().format('YYYY-MM-DD')
20
22
  export const dateToString = (date:Date) => moment(date).format('YYYY-MM-DD')
21
23
  export const getMoment = (startTime:string)=> moment(startTime)
22
- export const lastDateOfMonth = (datestr:string) => moment(datestr).endOf('month').format('YYYY-MM-DD');
24
+ export const lastDateOfMonth = (datestr:string) => moment(datestr).endOf('month').format('YYYY-MM-DD');
25
+ export const upperFirst = (str:string) => _.upperFirst(str)
@@ -93,15 +93,15 @@ export default defineNuxtPlugin( async(nuxtApp) => {
93
93
  })
94
94
  },
95
95
  getCurrentXorg(){
96
- return (useRoute().params.xorg) ? String(useRoute().params.xorg) : undefined
96
+ return (useRoute().params.xorg) ? String(useRoute().params.xorg) : undefined
97
97
  },
98
98
  async pingSession(){
99
- let xorg = this.getCurrentXorg()
99
+ let xorg = this.getCurrentXorg()
100
100
  let apiurl=''
101
- if(xorg===undefined){
101
+ if(!xorg){
102
102
  apiurl = `${useRuntimeConfig().public.APP_URL}/api`
103
103
  }else{
104
- apiurl = `${useRuntimeConfig().public.APP_URL}/api/${xorg}`
104
+ apiurl = `${useRuntimeConfig().public.APP_URL}/api/${xorg}`
105
105
  }
106
106
  const {$axios} = useNuxtApp()
107
107
  return await new PROFILEApi(undefined,apiurl,$axios).getSession()
@@ -45,7 +45,7 @@ export class SimpleAppClient<
45
45
  }
46
46
 
47
47
  getDocType = () => this.doctype;
48
- getDocName = () => this.docname;
48
+ getDocName = (capFirst:boolean=false) => capFirst ? upperFirst(this.docname) :this.docname;
49
49
  setNew = ()=>{}
50
50
  isNew = () => this.data.value?.created==''
51
51
  setSchema = (schema: SchemaType) => (this.schema = schema);
@@ -0,0 +1,4 @@
1
+ <%for(let i=0; i<it.modules.length;i++){ %>
2
+ <% const d = it.modules[i] %>
3
+ export {Default<%= d['docname']%>} from './<%= d['docname']%>.default'
4
+ <%}%>
@@ -1,22 +0,0 @@
1
- /**
2
- * This file was automatically generated by simpleapp generator. Every
3
- * MODIFICATION OVERRIDE BY GENERATEOR
4
- * last change 2023-10-28
5
- * Author: Ks Tan
6
- */
7
- export type ApiEvent = {
8
- _id: string
9
- created: string
10
- updated?:string
11
- duration: number
12
- createdBy: string
13
- path: string
14
- ip: string
15
- method: string
16
- headers: any
17
- data?: any
18
- statusCode:number
19
- status:string
20
- errMsg?:string
21
- errData?: any
22
- }