@simitgroup/simpleapp-generator 2.0.1-b-alpha → 2.0.1-d-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.
Files changed (46) hide show
  1. package/ReleaseNote.md +9 -0
  2. package/dist/buildinschemas/autoincreament.js +1 -1
  3. package/dist/buildinschemas/docnoformat.js +1 -1
  4. package/dist/buildinschemas/docnoformat.js.map +1 -1
  5. package/dist/buildinschemas/documentevent.js +1 -1
  6. package/dist/buildinschemas/message.d.ts +3 -0
  7. package/dist/buildinschemas/message.d.ts.map +1 -0
  8. package/dist/buildinschemas/message.js +34 -0
  9. package/dist/buildinschemas/message.js.map +1 -0
  10. package/dist/buildinschemas/webhookhistory.d.ts +3 -0
  11. package/dist/buildinschemas/webhookhistory.d.ts.map +1 -0
  12. package/dist/buildinschemas/webhookhistory.js +44 -0
  13. package/dist/buildinschemas/webhookhistory.js.map +1 -0
  14. package/dist/createproject.js +138 -0
  15. package/dist/createproject.js.map +1 -0
  16. package/dist/generate-allow-changebackend.js +305 -0
  17. package/dist/generate-allow-changebackend.js.map +1 -0
  18. package/dist/index2.js +118 -0
  19. package/dist/index2.js.map +1 -0
  20. package/dist/installdependency.js +20 -0
  21. package/dist/installdependency.js.map +1 -0
  22. package/dist/installnest.js +2 -0
  23. package/dist/installnest.js.map +1 -0
  24. package/dist/installnuxt.js +2 -0
  25. package/dist/installnuxt.js.map +1 -0
  26. package/dist/processors/groupsbuilder.js +2 -0
  27. package/dist/processors/groupsbuilder.js.map +1 -0
  28. package/dist/schematype/baseschema.js +25 -0
  29. package/dist/schematype/baseschema.js.map +1 -0
  30. package/dist/schematype/default.js +2 -0
  31. package/dist/schematype/default.js.map +1 -0
  32. package/dist/schematype/index.js +12 -0
  33. package/dist/schematype/index.js.map +1 -0
  34. package/dist/schematype/primarymasterdata.js +38 -0
  35. package/dist/schematype/primarymasterdata.js.map +1 -0
  36. package/dist/schematype/simple.js +24 -0
  37. package/dist/schematype/simple.js.map +1 -0
  38. package/dist/schematype/simplemasterdata.js +31 -0
  39. package/dist/schematype/simplemasterdata.js.map +1 -0
  40. package/dist/schematype/transaction.js +74 -0
  41. package/dist/schematype/transaction.js.map +1 -0
  42. package/package.json +1 -1
  43. package/templates/basic/nest/model.ts.eta +1 -1
  44. package/templates/nest/src/simple-app/_core/features/profile/profile.service.ts.eta +1 -1
  45. package/templates/nest/src/simple-app/_core/framework/base/simple-app.service.ts.eta +64 -228
  46. package/templates/nuxt/middleware/30.acl.global.ts._eta +26 -11
@@ -357,106 +357,7 @@ export class SimpleAppService<T extends SchemaFields> {
357
357
  }
358
358
  }
359
359
 
360
- // seems no use, and confusing
361
- // async createManyWithId(appuser: UserContext, datas: T[]) {
362
- // if (Array.isArray(datas)) {
363
- // for (let i = 0; i < datas.length; i++) {
364
- // const data = datas[i];
365
- // let isolationFilter: any = { ...appuser.getCreateFilterWithId() };
366
- // isolationFilter = this.polishIsolationFilter(isolationFilter, data);
367
-
368
- // Object.assign(data, isolationFilter);
369
- // this.reCalculateValue(data);
370
- // await this.validateData(appuser, data);
371
- // this.applyNestedDateTime(appuser, data, 'create');
372
- // }
373
-
374
- // const dbsession = appuser.getDBSession();
375
- // if (dbsession && !dbsession.inTransaction()) {
376
- // dbsession.startTransaction({ readPreference: 'primary' });
377
- // }
378
-
379
- // const result = await this.doc.insertMany(datas, { session: dbsession });
380
- // await this.addManyAuditEvents(appuser, this.documentName, 'createMany', datas);
381
- // for (let i = 0; i < datas.length; i++) {
382
- // appuser.addInsertedRecordId(this.documentName, datas[i]._id);
383
- // }
384
- // return result;
385
- // } else {
386
- // throw new BadRequestException(this.getDocumentType() + ': create many only support array');
387
- // }
388
- // }
389
-
390
- /**
391
- * create many from array with hooks (temporary used for generate sample data only)
392
- * @param appuser
393
- * @param datas
394
- */
395
- //seems nobody use. also confusing
396
- // async createManyWithHook(appuser: UserContext, datas: T[]) {
397
- // if (Array.isArray(datas)) {
398
- // for (let i = 0; i < datas.length; i++) {
399
- // const data = datas[i];
400
-
401
- // let result;
402
- // const dbsession = appuser.getDBSession();
403
- // if (dbsession && !dbsession.inTransaction()) {
404
- // dbsession.startTransaction({ readPreference: 'primary' });
405
- // }
406
-
407
- // if (this.withDocNumberFormat && !data[this.documentIdentityCode]) {
408
- // await this.genNewDocNo(appuser, data);
409
- // }
410
-
411
- // let isolationFilter: any = { ...appuser.getCreateFilterWithId() };
412
- // isolationFilter = this.polishIsolationFilter(isolationFilter, data);
413
-
414
- // Object.assign(data, isolationFilter);
415
- // this.reCalculateValue(data);
416
- // await this.validateData(appuser, data);
417
- // this.applyNestedDateTime(appuser, data, 'create');
418
-
419
- // //new way of hook
420
- // await this.runEvent(appuser, this.setHookName('beforeCreate'), { data: data }, false);
421
-
422
- // const newdoc = new this.doc(data);
423
-
424
- // try {
425
- // result = await newdoc.save({ session: dbsession });
426
- // await this.addAuditEvent(appuser, this.documentName, result._id, 'create', data);
427
- // appuser.addInsertedRecordId(this.documentName, result._id);
428
- // } catch (err) {
429
- // this.logger.error(err);
430
- // throw new ProcessErrorException('ERR_CREATE_MANY',err.message,{
431
- // err:err
432
- // })
433
- // // const processdata = await this.runEvent(appuser, 'processdata.processError', {
434
- // // err: err,
435
- // // });
436
-
437
- // // if (!processdata) {
438
- // // throw new InternalServerErrorException(err);
439
- // // } else {
440
- // // throw new CustomException(processdata.code, processdata.msg);
441
- // // }
442
- // }
443
-
444
- // try {
445
- // //new way of hook
446
- // await this.runEvent(appuser, this.setHookName('afterCreate'), { data: data }, false);
447
- // await this.callWebhook(appuser, 'create', result);
448
-
449
- // // return result as T;
450
- // } catch (err) {
451
- // throw new InternalServerErrorException(`createHook ${this.documentType} error: ${JSON.stringify(err)}`, `${this.documentType} createHook error`);
452
- // }
453
- // }
454
- // } else {
455
- // throw new BadRequestException(this.getDocumentType() + ': create many only support array');
456
- // }
457
- // return 'ok';
458
- // }
459
-
360
+
460
361
  /**
461
362
  * create many from array, for performance reason it submit all item in 1 go, so it won't implement hooks
462
363
  * @param appuser
@@ -476,7 +377,7 @@ export class SimpleAppService<T extends SchemaFields> {
476
377
  }
477
378
  const dbsession = appuser.getDBSession();
478
379
  if (dbsession && !dbsession.inTransaction()) {
479
- dbsession.startTransaction({ readPreference: 'primary' });
380
+ dbsession.startTransaction({readConcern:{level:"snapshot"},writeConcern:{w:"majority"}, readPreference: 'primary' });
480
381
  }
481
382
 
482
383
  try {
@@ -495,71 +396,6 @@ export class SimpleAppService<T extends SchemaFields> {
495
396
  }
496
397
  }
497
398
 
498
- //seems nobody use, also confusing
499
- // async createWithId(appuser: UserContext, data: T) {
500
- // let result;
501
-
502
- // if (!data._id) {
503
- // data._id = crypto.randomUUID();
504
- // }
505
- // const dbsession = appuser.getDBSession();
506
- // if (dbsession && !dbsession.inTransaction()) {
507
- // dbsession.startTransaction({ readPreference: 'primary' });
508
- // }
509
-
510
- // this.logger.debug('this.withDocNumberFormat :' + this.withDocNumberFormat + ' && ' + '!data[this.documentIdentityCode] ==' + !data[this.documentIdentityCode]);
511
- // if (this.withDocNumberFormat && !data[this.documentIdentityCode]) {
512
- // await this.genNewDocNo(appuser, data);
513
- // }
514
-
515
- // let isolationFilter: any = { ...appuser.getCreateFilterWithId() };
516
- // isolationFilter = this.polishIsolationFilter(isolationFilter, data);
517
-
518
- // this.logger.debug('isolationFilter', 'SimpleAppService');
519
- // this.logger.debug(isolationFilter, 'SimpleAppService');
520
- // this.logger.debug('Create data before isolation', 'SimpleAppService');
521
- // this.logger.debug(data, 'SimpleAppService');
522
- // Object.assign(data, isolationFilter);
523
- // this.reCalculateValue(data);
524
- // await this.validateData(appuser, data);
525
- // this.logger.debug(data, `after create validation`);
526
- // this.applyNestedDateTime(appuser, data, 'create');
527
-
528
- // //new way of hook
529
-
530
- // await this.runEvent(appuser, this.setHookName('beforeCreate'), { data: data }, false);
531
-
532
- // this.logger.debug(data, `Create Record ${this.documentName}`);
533
- // const newdoc = new this.doc(data);
534
- // await this.identifyForeignKeys(appuser, data);
535
- // try {
536
- // result = await newdoc.save({ session: dbsession });
537
- // await this.addAuditEvent(appuser, this.documentName, result._id, 'create', data);
538
- // appuser.addInsertedRecordId(this.documentName, result._id);
539
- // } catch (err) {
540
- // this.logger.error(err);
541
- // const processdata = await this.runEvent(appuser, 'processdata.processError', {
542
- // err: err,
543
- // });
544
-
545
- // if (!processdata) {
546
- // throw new InternalServerErrorException(err);
547
- // } else {
548
- // throw new CustomException(processdata.code, processdata.msg);
549
- // }
550
- // }
551
-
552
- // try {
553
- // //new way of hook
554
- // await this.runEvent(appuser, this.setHookName('afterCreate'), { data: result }, false);
555
-
556
- // await this.callWebhook(appuser, 'create', result);
557
- // return result as T;
558
- // } catch (err) {
559
- // throw new InternalServerErrorException(`createHook ${this.documentType} error: ${JSON.stringify(err)}`, `${this.documentType} createHook error`);
560
- // }
561
- // }
562
-
563
399
  async create(appuser: UserContext, data: T, noStartTransaction: boolean = false) {
564
400
  let result;
565
401
 
@@ -568,7 +404,7 @@ export class SimpleAppService<T extends SchemaFields> {
568
404
  }
569
405
  const dbsession = appuser.getDBSession();
570
406
  if (dbsession && !dbsession.inTransaction() && !noStartTransaction) {
571
- dbsession.startTransaction({ readPreference: 'primary' });
407
+ dbsession.startTransaction({readConcern:{level:"snapshot"},writeConcern:{w:"majority"}, readPreference: 'primary' });
572
408
  }
573
409
 
574
410
  this.logger.debug('this.withDocNumberFormat :' + this.withDocNumberFormat + ' && ' + '!data[this.documentIdentityCode] ==' + !data[this.documentIdentityCode]);
@@ -714,7 +550,7 @@ export class SimpleAppService<T extends SchemaFields> {
714
550
  }
715
551
  const dbsession = appuser.getDBSession();
716
552
  if (dbsession && !dbsession.inTransaction()) {
717
- dbsession.startTransaction({ readPreference: 'primary' });
553
+ dbsession.startTransaction({readConcern:{level:"snapshot"},writeConcern:{w:"majority"}, readPreference: 'primary' });
718
554
  }
719
555
 
720
556
  let dependency;
@@ -793,7 +629,7 @@ export class SimpleAppService<T extends SchemaFields> {
793
629
 
794
630
  const dbsession = appuser.getDBSession();
795
631
  if (dbsession && !dbsession.inTransaction() && !noStartTransaction) {
796
- dbsession.startTransaction({ readPreference: 'primary' });
632
+ dbsession.startTransaction({readConcern:{level:"snapshot"},writeConcern:{w:"majority"}, readPreference: 'primary' });
797
633
  }
798
634
  // try {
799
635
  Object.assign(data, appuser.getUpdateFilter());
@@ -852,7 +688,7 @@ export class SimpleAppService<T extends SchemaFields> {
852
688
 
853
689
  const dbsession = appuser.getDBSession();
854
690
  if (dbsession && !dbsession.inTransaction()) {
855
- dbsession.startTransaction({ readPreference: 'primary' });
691
+ dbsession.startTransaction({readConcern:{level:"snapshot"},writeConcern:{w:"majority"}, readPreference: 'primary' });
856
692
  }
857
693
  // try {
858
694
  // Object.assign(data, appuser.getUpdateFilter());
@@ -908,7 +744,7 @@ export class SimpleAppService<T extends SchemaFields> {
908
744
  await this.runEvent(appuser, this.setHookName('beforePatch'), { id: id, patchData: data, prevData: existingdata }, false);
909
745
  const dbsession = appuser.getDBSession();
910
746
  if (dbsession && !dbsession.inTransaction()) {
911
- dbsession.startTransaction({ readPreference: 'primary' });
747
+ dbsession.startTransaction({readConcern:{level:"snapshot"},writeConcern:{w:"majority"}, readPreference: 'primary' });
912
748
  }
913
749
  // try {
914
750
  Object.assign(data, appuser.getUpdateFilter());
@@ -963,7 +799,7 @@ export class SimpleAppService<T extends SchemaFields> {
963
799
  // Get DB Session
964
800
  const dbsession = appuser.getDBSession();
965
801
  if (dbsession && !dbsession.inTransaction()) {
966
- dbsession.startTransaction({ readPreference: 'primary' });
802
+ dbsession.startTransaction({readConcern:{level:"snapshot"},writeConcern:{w:"majority"}, readPreference: 'primary' });
967
803
  }
968
804
 
969
805
  const result = await this.doc.updateMany(isolationFilter, { $set: patch }, { session: dbsession });
@@ -1316,63 +1152,63 @@ export class SimpleAppService<T extends SchemaFields> {
1316
1152
  },
1317
1153
  ];
1318
1154
 
1319
- // // Relation lookups
1320
- // Object.entries(option.relations).forEach(([relationName, relationOption]) => {
1321
- // // Prevent mini api user lookup sensitive data
1322
- // if (!allowedRelations.includes(relationName)) {
1323
- // throw new BadRequestException(`Not allowed to lookup ${relationName}`);
1324
- // }
1325
-
1326
- // const subPipeline: PipelineStage.Lookup['$lookup']['pipeline'] = [];
1327
-
1328
- // subPipeline.push({
1329
- // $match: {
1330
- // $expr: { $eq: [`$${relationOption.foreignField}`, '$$localValue'] },
1331
- // },
1332
- // ...relationOption.filter,
1333
- // });
1334
-
1335
- // // Relation sort
1336
- // if (relationOption.sort) {
1337
- // subPipeline.push({
1338
- // $sort: relationOption.sort,
1339
- // });
1340
- // }
1341
-
1342
- // // Relation projection
1343
- // if (relationOption.projection) {
1344
- // subPipeline.push({
1345
- // $project: {
1346
- // ...(relationOption.projection ?? {}),
1347
- // },
1348
- // });
1349
- // }
1350
-
1351
- // pipeline.push({
1352
- // $lookup: {
1353
- // from: relationName.toLowerCase(),
1354
- // as: `_${relationName}`,
1355
- // let: { localValue: `$${relationOption.localField}` },
1356
- // pipeline: subPipeline,
1357
- // },
1358
- // });
1359
- // });
1360
-
1361
- // // Root sort
1362
- // if (option.root?.sort) {
1363
- // pipeline.push({
1364
- // $sort: option.root.sort,
1365
- // });
1366
- // }
1155
+ // Relation lookups
1156
+ Object.entries(option.relations).forEach(([relationName, relationOption]) => {
1157
+ // Prevent mini api user lookup sensitive data
1158
+ if (!allowedRelations.includes(relationName)) {
1159
+ throw new BadRequestException(`Not allowed to lookup ${relationName}`);
1160
+ }
1367
1161
 
1368
- // // Root Projection
1369
- // if (option.root.projection) {
1370
- // pipeline.push({
1371
- // $project: {
1372
- // ...(option.root?.projection ?? {}),
1373
- // },
1374
- // });
1375
- // }
1162
+ const subPipeline: PipelineStage.Lookup['$lookup']['pipeline'] = [];
1163
+
1164
+ subPipeline.push({
1165
+ $match: {
1166
+ $expr: { $eq: [`$${relationOption.foreignField}`, '$$localValue'] },
1167
+ },
1168
+ ...relationOption.filter,
1169
+ });
1170
+
1171
+ // Relation sort
1172
+ if (relationOption.sort) {
1173
+ subPipeline.push({
1174
+ $sort: relationOption.sort,
1175
+ });
1176
+ }
1177
+
1178
+ // Relation projection
1179
+ if (relationOption.projection) {
1180
+ subPipeline.push({
1181
+ $project: {
1182
+ ...(relationOption.projection ?? {}),
1183
+ },
1184
+ });
1185
+ }
1186
+
1187
+ pipeline.push({
1188
+ $lookup: {
1189
+ from: relationName.toLowerCase(),
1190
+ as: `_${relationName}`,
1191
+ let: { localValue: `$${relationOption.localField}` },
1192
+ pipeline: subPipeline,
1193
+ },
1194
+ });
1195
+ });
1196
+
1197
+ // Root sort
1198
+ if (option.root?.sort) {
1199
+ pipeline.push({
1200
+ $sort: option.root.sort,
1201
+ });
1202
+ }
1203
+
1204
+ // Root Projection
1205
+ if (option.root.projection) {
1206
+ pipeline.push({
1207
+ $project: {
1208
+ ...(option.root?.projection ?? {}),
1209
+ },
1210
+ });
1211
+ }
1376
1212
 
1377
1213
  return await this.aggregate(appUser, pipeline);
1378
1214
  }
@@ -2,17 +2,24 @@ import { RouteLocationNormalizedGeneric } from 'vue-router';
2
2
  import { getUserProfile } from './../composables/getUserStore.generate';
3
3
 
4
4
  export default defineNuxtRouteMiddleware(async (to, from) => {
5
- console.log(to.path)
6
- const userProfile = getUserProfile()
5
+ // console.log("to",to.path)
6
+ const uauth = useAuthState()
7
+
8
+ if(isPublicPath(to.path)) return true
9
+ if(!uauth.data.value) return navigateTo('/login')
10
+
11
+ let userProfile = getUserProfile()
7
12
  const xorg = <string>to.params['xorg'] ?? 'MC0wLTA'
8
13
  useNuxtApp().$userstore.xOrg=xorg
9
14
  if(!userProfile?._id){
10
15
  // console.error("middleware detect no user id, reload under xorg",xorg)
11
16
  await reloadUserStoreFromMiddleware(xorg)
17
+ userProfile = getUserProfile()
12
18
  // console.log("after reload",userProfile)
13
- }else if(userProfile.branchId===0 && xorg !='MC0wLTA'){
19
+ }else if(userProfile?.branchId===0 && xorg !='MC0wLTA'){
14
20
  // console.error("middleware detect wrong xorg reload profile for",xorg)
15
21
  await reloadUserStoreFromMiddleware(xorg)
22
+ userProfile = getUserProfile()
16
23
  // console.log("after reload",userProfile)
17
24
  }else{
18
25
  // console.log("use exists, use back the user store")
@@ -21,9 +28,9 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
21
28
 
22
29
 
23
30
  const currentgroup = useCookie('currentGroup').value
24
- if(currentgroup && userProfile.groups.includes(currentgroup)){
31
+ if(currentgroup && userProfile?.groups?.includes(currentgroup)){
25
32
  //use back ground
26
- }else if(userProfile.groups.length>0){
33
+ }else if(userProfile?.groups?.length>0){
27
34
  goTo('pickgroup')
28
35
  }
29
36
  // if (!currentgroup)goTo('pickgroup')
@@ -43,7 +50,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
43
50
  }
44
51
 
45
52
  const license = useLicense().getLicense()
46
- console.log("metas check",metas)
53
+ // console.log("metas check",metas)
47
54
  if(metas.length == 0){
48
55
  throw createError({
49
56
  statusCode: 404,
@@ -83,7 +90,8 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
83
90
  if(to.meta['requiredGroups']){
84
91
 
85
92
  const requiredGroups:string[] = to.meta['requiredGroups']
86
- const userGroups = userProfile.groups
93
+ const userGroups = userProfile?.groups || []
94
+ const userRoles = userProfile?.roles || []
87
95
  let allowAccess = false
88
96
  if(['','/'].includes(to.path)) allowAccess= true
89
97
 
@@ -92,7 +100,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
92
100
  if(userGroups.includes(g)){
93
101
  allowAccess = true
94
102
  }
95
- if(userProfile.roles.includes(g)){
103
+ if(userRoles.includes(g)){
96
104
  allowAccess = true
97
105
  }
98
106
 
@@ -106,7 +114,7 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
106
114
  });
107
115
  }
108
116
  }
109
- console.log("middleware check isexpired",useLicense().isExpired())
117
+ // console.log("middleware check isexpired",useLicense().isExpired())
110
118
  if(!useLicense().isExpired()) {
111
119
  return true
112
120
  }else if(allowAccessExpired(to)){
@@ -125,15 +133,22 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
125
133
  const allowAccessExpired = (to:RouteLocationNormalizedGeneric)=>{
126
134
  const userProfile = getUserProfile()
127
135
  let allowPass = false
128
- const isSuperAdmin = userProfile.groups.includes('superadmin')
136
+ const isSuperAdmin = userProfile?.groups?.includes('superadmin') ?? false
129
137
  if(isSuperAdmin){
130
138
  allowPass=true
131
139
  }
132
140
  const allowedPath = ['/billing','/pickgroup']
133
141
  for(const p of allowedPath){
134
- console.log("to.path.includes",to.path,p)
142
+ // console.log("to.path.includes",to.path,p)
135
143
  if(to.path.includes(p))allowPass = true
136
144
  }
137
145
 
138
146
  return allowPass
147
+ }
148
+
149
+ const isPublicPath=(path:string)=>{
150
+ if(path.includes('/login')) return true
151
+ if(path.includes('/relogin')) return true
152
+ if(path.includes('/logout')) return true
153
+ return false
139
154
  }