@simitgroup/simpleapp-generator 1.6.6-i-alpha → 1.6.6-k-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 (239) hide show
  1. package/ReleaseNote.md +7 -0
  2. package/dist/buildinschemas/docnoformat.js +6 -6
  3. package/dist/buildinschemas/docnoformat.js.map +1 -1
  4. package/dist/buildinschemas/documentevent.js +1 -1
  5. package/dist/buildinschemas/documentevent.js.map +1 -1
  6. package/dist/buildinschemas/organization.js +1 -1
  7. package/dist/buildinschemas/organization.js.map +1 -1
  8. package/dist/buildinschemas/tenant.js +1 -1
  9. package/dist/buildinschemas/tenant.js.map +1 -1
  10. package/dist/buildinschemas/user.js +2 -2
  11. package/dist/buildinschemas/user.js.map +1 -1
  12. package/dist/buildinschemas/webhook.d.ts.map +1 -1
  13. package/dist/buildinschemas/webhook.js +1 -0
  14. package/dist/buildinschemas/webhook.js.map +1 -1
  15. package/dist/framework.d.ts.map +1 -1
  16. package/dist/framework.js +30 -3
  17. package/dist/framework.js.map +1 -1
  18. package/dist/generate.d.ts.map +1 -1
  19. package/dist/generate.js +21 -20
  20. package/dist/generate.js.map +1 -1
  21. package/dist/index.js +0 -0
  22. package/dist/processors/jrxmlbuilder.js +3 -3
  23. package/dist/processors/jrxmlbuilder.js.map +1 -1
  24. package/dist/processors/jsonschemabuilder.d.ts.map +1 -1
  25. package/dist/processors/jsonschemabuilder.js +17 -10
  26. package/dist/processors/jsonschemabuilder.js.map +1 -1
  27. package/dist/type.d.ts +1 -1
  28. package/dist/type.d.ts.map +1 -1
  29. package/package.json +2 -3
  30. package/reset-install.sh +3 -0
  31. package/src/buildinschemas/docnoformat.ts +6 -6
  32. package/src/buildinschemas/documentevent.ts +1 -1
  33. package/src/buildinschemas/organization.ts +1 -1
  34. package/src/buildinschemas/tenant.ts +1 -1
  35. package/src/buildinschemas/user.ts +2 -2
  36. package/src/buildinschemas/webhook.ts +1 -0
  37. package/src/framework.ts +33 -5
  38. package/src/generate.ts +22 -20
  39. package/src/processors/jrxmlbuilder.ts +3 -3
  40. package/src/processors/jsonschemabuilder.ts +27 -14
  41. package/src/type.ts +1 -1
  42. package/templates/basic/nest/controller.ts.eta +6 -5
  43. package/templates/basic/nest/resolver.ts.eta +4 -2
  44. package/templates/basic/nest/service.ts.eta +5 -2
  45. package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +3 -3
  46. package/templates/nest/.gitignore.eta +4 -5
  47. package/templates/nest/src/{app.module.ts.eta → app.module.ts._eta} +2 -2
  48. package/templates/nest/src/{main.ts.eta → main.ts._eta} +2 -2
  49. package/templates/nest/src/printapi/printapi.service.ts.eta +7 -8
  50. package/templates/nest/src/simpleapp/.gitignore.eta +1 -1
  51. package/templates/nest/src/simpleapp/generate/commons/audittrail.service.ts.eta +2 -2
  52. package/templates/nest/src/simpleapp/generate/commons/customkeycloa.guard.ts.eta +14 -12
  53. package/templates/nest/src/simpleapp/generate/commons/customkeycloak.guard.ts.eta +36 -42
  54. package/templates/nest/src/simpleapp/generate/commons/docnogenerator.service.ts.eta +6 -3
  55. package/templates/nest/src/simpleapp/generate/commons/encryption.static.ts.eta +56 -61
  56. package/templates/nest/src/simpleapp/generate/commons/middlewares/tenant.middleware.ts.eta +65 -88
  57. package/templates/nest/src/simpleapp/generate/commons/robotuser.service.ts.eta +10 -9
  58. package/templates/nest/src/simpleapp/generate/commons/roles/roles.guard.ts.eta +10 -3
  59. package/templates/nest/src/simpleapp/generate/commons/runwebhook.service.ts.eta +71 -77
  60. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +439 -293
  61. package/templates/nest/src/simpleapp/generate/processors/autoinc.processor.ts.eta +20 -5
  62. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +423 -38
  63. package/templates/nest/src/simpleapp/profile/{profile.controller.ts.eta → profile.controller.ts._eta} +2 -2
  64. package/templates/nest/src/simpleapp/profile/{profile.service.ts.eta → profile.service.ts._eta} +2 -2
  65. package/templates/nest/src/simpleapp/simpleapp.module.ts.eta +15 -4
  66. package/templates/nuxt/assets/css/style.css._eta +74 -28
  67. package/templates/nuxt/components/button/ButtonMultiple.vue._eta +1 -1
  68. package/templates/nuxt/components/calendar/{CalendarByResource.vue.eta → CalendarByResource.vue._eta} +2 -2
  69. package/templates/nuxt/components/calendar/{CalendarInput.vue.eta → CalendarInput.vue._eta} +3 -3
  70. package/templates/nuxt/components/calendar/{CalendarSmall.vue.eta → CalendarSmall.vue._eta} +13 -7
  71. package/templates/nuxt/components/debug/{DebugDocumentData.vue.eta → DebugDocumentData.vue._eta} +4 -5
  72. package/templates/nuxt/components/form/{FormDocnoformat.vue.eta → FormDocnoformat.vue._eta} +2 -1
  73. package/templates/nuxt/components/form/user/{FormUserPermission.vue.eta → FormUserPermission.vue._eta} +6 -0
  74. package/templates/nuxt/components/header/{HeaderBreadcrumb.vue.eta → HeaderBreadcrumb.vue._eta} +5 -5
  75. package/templates/nuxt/components/header/button/{HeaderButtonProfile.vue.eta → HeaderButtonProfile.vue._eta} +2 -2
  76. package/templates/nuxt/components/header/button/task/{HeaderButtonTaskList.vue.eta → HeaderButtonTaskList.vue._eta} +4 -4
  77. package/templates/nuxt/components/image/ImageAvatar.vue.eta +56 -0
  78. package/templates/nuxt/components/image/{ImageOrganization.vue.eta.vue → ImageOrganization.vue.eta} +15 -9
  79. package/templates/nuxt/components/image/{ImageToBase64Uploader.vue.eta.vue → ImageToBase64Uploader.vue.eta} +28 -18
  80. package/templates/nuxt/components/list/{ListDocumentTable.vue.eta → ListDocumentTable.vue._eta} +3 -3
  81. package/templates/nuxt/components/list/{ListItem.vue.eta → ListItem.vue._eta} +2 -2
  82. package/templates/nuxt/components/list/{ListMessages.vue.eta → ListMessages.vue._eta} +8 -2
  83. package/templates/nuxt/components/list/{ListView.vue.eta → ListView.vue._eta} +2 -2
  84. package/templates/nuxt/components/overlay/{OverlayPanelWithToolBar.vue.eta → OverlayPanelWithToolBar.vue._eta} +5 -5
  85. package/templates/nuxt/components/overlay/{OverlaySideBarCrud.vue.eta → OverlaySideBarCrud.vue._eta} +4 -4
  86. package/templates/nuxt/components/overlay/{OverlayViewer.vue.eta → OverlayViewer.vue._eta} +2 -2
  87. package/templates/nuxt/components/page/{PageDocList.vue.eta → PageDocList.vue._eta} +5 -5
  88. package/templates/nuxt/components/renderer/RendererDateAge.vue.eta +19 -0
  89. package/templates/nuxt/components/renderer/{RendererDateTime.vue.eta → RendererDateTime.vue._eta} +2 -2
  90. package/templates/nuxt/components/renderer/{RendererDocHistories.vue.eta → RendererDocHistories.vue._eta} +6 -0
  91. package/templates/nuxt/components/renderer/{RendererForeignKey.vue.eta → RendererForeignKey.vue._eta} +2 -2
  92. package/templates/nuxt/components/renderer/{RendererLink.vue.eta → RendererLink.vue._eta} +2 -2
  93. package/templates/nuxt/components/renderer/{RendererTime.vue.eta → RendererTime.vue._eta} +2 -2
  94. package/templates/nuxt/components/renderer/{RendererViewer.vue.eta → RendererViewer.vue._eta} +2 -2
  95. package/templates/nuxt/components/select/{SelectTemplate.vue.eta → SelectTemplate.vue._eta} +2 -2
  96. package/templates/nuxt/components/session/{SessionBlock.vue.eta → SessionBlock.vue._eta} +2 -2
  97. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +55 -55
  98. package/templates/nuxt/components/simpleApp/SimpleAppCalendarInput.vue.eta +13 -11
  99. package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +6 -3
  100. package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +33 -28
  101. package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +19 -28
  102. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +113 -105
  103. package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +3 -3
  104. package/templates/nuxt/components/simpleApp/SimpleAppJsonSchemaForm.vue.eta +3 -16
  105. package/templates/nuxt/components/simpleApp/SimpleAppUserPicker.vue.eta +10 -12
  106. package/templates/nuxt/components/table/{TableDocuments.vue.eta → TableDocuments.vue._eta} +2 -2
  107. package/templates/nuxt/components/user/{UserButtonPermissionInfo.vue.eta → UserButtonPermissionInfo.vue._eta} +4 -4
  108. package/templates/nuxt/components/user/{UserInvitation.vue.eta → UserInvitation.vue._eta} +2 -2
  109. package/templates/nuxt/components/user/{UserProfileListItem.vue.eta → UserProfileListItem.vue._eta} +2 -2
  110. package/templates/nuxt/components/user/{UserTenantPicker.vue.eta → UserTenantPicker.vue._eta} +2 -2
  111. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +11 -3
  112. package/templates/nuxt/composables/getUserStore.generate.ts.eta +1 -1
  113. package/templates/nuxt/composables/graphquery.generate.ts.eta +1 -1
  114. package/templates/nuxt/composables/recently.generate.ts.eta +0 -1
  115. package/templates/nuxt/composables/stringHelper.generate.ts.eta +5 -2
  116. package/templates/nuxt/nuxt.config.ts._eta +6 -5
  117. package/templates/nuxt/pages/[xorg]/docnoformat/[id].vue.eta +0 -1
  118. package/templates/nuxt/pages/[xorg]/{docnoformat.vue.eta → docnoformat.vue._eta} +1 -0
  119. package/templates/nuxt/pages/[xorg]/organization/[id].vue.eta +13 -9
  120. package/templates/nuxt/pages/[xorg]/organization/new.vue.eta +10 -12
  121. package/templates/nuxt/pages/[xorg]/{user.vue.eta → user.vue._eta} +2 -2
  122. package/templates/nuxt/pages/index.vue._eta +1 -1
  123. package/templates/nuxt/pages/{profile.vue.eta → profile.vue._eta} +2 -2
  124. package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +6 -0
  125. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +89 -12
  126. package/templates/nuxt/plugins/40.pusher.ts.eta +8 -5
  127. package/templates/nuxt/presets/lara/accordion/index.js +79 -0
  128. package/templates/nuxt/presets/lara/accordioncontent/index.js +3 -0
  129. package/templates/nuxt/presets/lara/accordionheader/index.js +11 -0
  130. package/templates/nuxt/presets/lara/accordionpanel/index.js +18 -0
  131. package/templates/nuxt/presets/lara/autocomplete/index.js +208 -0
  132. package/templates/nuxt/presets/lara/avatar/index.js +43 -0
  133. package/templates/nuxt/presets/lara/avatargroup/index.js +5 -0
  134. package/templates/nuxt/presets/lara/badge/index.js +47 -0
  135. package/templates/nuxt/presets/lara/badgedirective/index.js +43 -0
  136. package/templates/nuxt/presets/lara/blockui/index.js +4 -0
  137. package/templates/nuxt/presets/lara/breadcrumb/index.js +64 -0
  138. package/templates/nuxt/presets/lara/button/index.js +238 -0
  139. package/templates/nuxt/presets/lara/buttongroup/index.js +12 -0
  140. package/templates/nuxt/presets/lara/card/index.js +37 -0
  141. package/templates/nuxt/presets/lara/carousel/index.js +103 -0
  142. package/templates/nuxt/presets/lara/cascadeselect/index.js +199 -0
  143. package/templates/nuxt/presets/lara/checkbox/index.js +104 -0
  144. package/templates/nuxt/presets/lara/chip/index.js +42 -0
  145. package/templates/nuxt/presets/lara/colorpicker/index.js +123 -0
  146. package/templates/nuxt/presets/lara/confirmdialog/index.js +3 -0
  147. package/templates/nuxt/presets/lara/confirmpopup/index.js +56 -0
  148. package/templates/nuxt/presets/lara/contextmenu/index.js +126 -0
  149. package/templates/nuxt/presets/lara/datatable/index.js +403 -0
  150. package/templates/nuxt/presets/lara/dataview/index.js +28 -0
  151. package/templates/nuxt/presets/lara/datepicker/index.js +435 -0
  152. package/templates/nuxt/presets/lara/deferred/index.js +3 -0
  153. package/templates/nuxt/presets/lara/dialog/index.js +148 -0
  154. package/templates/nuxt/presets/lara/divider/index.js +67 -0
  155. package/templates/nuxt/presets/lara/dock/index.js +86 -0
  156. package/templates/nuxt/presets/lara/drawer/index.js +149 -0
  157. package/templates/nuxt/presets/lara/fieldset/index.js +84 -0
  158. package/templates/nuxt/presets/lara/fileupload/index.js +95 -0
  159. package/templates/nuxt/presets/lara/floatlabel/index.js +26 -0
  160. package/templates/nuxt/presets/lara/galleria/index.js +308 -0
  161. package/templates/nuxt/presets/lara/global.js +90 -0
  162. package/templates/nuxt/presets/lara/iconfield/index.js +27 -0
  163. package/templates/nuxt/presets/lara/image/index.js +206 -0
  164. package/templates/nuxt/presets/lara/index.js +234 -0
  165. package/templates/nuxt/presets/lara/inplace/index.js +27 -0
  166. package/templates/nuxt/presets/lara/inputgroup/index.js +5 -0
  167. package/templates/nuxt/presets/lara/inputgroupaddon/index.js +28 -0
  168. package/templates/nuxt/presets/lara/inputmask/index.js +39 -0
  169. package/templates/nuxt/presets/lara/inputnumber/index.js +167 -0
  170. package/templates/nuxt/presets/lara/inputotp/index.js +10 -0
  171. package/templates/nuxt/presets/lara/inputswitch/index.js +80 -0
  172. package/templates/nuxt/presets/lara/inputtext/index.js +54 -0
  173. package/templates/nuxt/presets/lara/knob/index.js +44 -0
  174. package/templates/nuxt/presets/lara/listbox/index.js +117 -0
  175. package/templates/nuxt/presets/lara/megamenu/index.js +198 -0
  176. package/templates/nuxt/presets/lara/menu/index.js +96 -0
  177. package/templates/nuxt/presets/lara/menubar/index.js +176 -0
  178. package/templates/nuxt/presets/lara/message/index.js +92 -0
  179. package/templates/nuxt/presets/lara/metergroup/index.js +96 -0
  180. package/templates/nuxt/presets/lara/multiselect/index.js +201 -0
  181. package/templates/nuxt/presets/lara/orderlist/index.js +13 -0
  182. package/templates/nuxt/presets/lara/organizationchart/index.js +137 -0
  183. package/templates/nuxt/presets/lara/overlaybadge/index.js +18 -0
  184. package/templates/nuxt/presets/lara/paginator/index.js +178 -0
  185. package/templates/nuxt/presets/lara/panel/index.js +91 -0
  186. package/templates/nuxt/presets/lara/panelmenu/index.js +127 -0
  187. package/templates/nuxt/presets/lara/password/index.js +72 -0
  188. package/templates/nuxt/presets/lara/picklist/index.js +52 -0
  189. package/templates/nuxt/presets/lara/popover/index.js +31 -0
  190. package/templates/nuxt/presets/lara/progressbar/index.js +55 -0
  191. package/templates/nuxt/presets/lara/progressspinner/index.js +51 -0
  192. package/templates/nuxt/presets/lara/radiobutton/index.js +104 -0
  193. package/templates/nuxt/presets/lara/rating/index.js +63 -0
  194. package/templates/nuxt/presets/lara/ripple/index.js +6 -0
  195. package/templates/nuxt/presets/lara/scrollpanel/index.js +77 -0
  196. package/templates/nuxt/presets/lara/scrolltop/index.js +26 -0
  197. package/templates/nuxt/presets/lara/select/index.js +240 -0
  198. package/templates/nuxt/presets/lara/selectbutton/index.js +16 -0
  199. package/templates/nuxt/presets/lara/skeleton/index.js +16 -0
  200. package/templates/nuxt/presets/lara/slider/index.js +137 -0
  201. package/templates/nuxt/presets/lara/speeddial/index.js +57 -0
  202. package/templates/nuxt/presets/lara/splitbutton/index.js +19 -0
  203. package/templates/nuxt/presets/lara/splitter/index.js +61 -0
  204. package/templates/nuxt/presets/lara/splitterpanel/index.js +5 -0
  205. package/templates/nuxt/presets/lara/step/index.js +62 -0
  206. package/templates/nuxt/presets/lara/stepitem/index.js +11 -0
  207. package/templates/nuxt/presets/lara/steplist/index.js +3 -0
  208. package/templates/nuxt/presets/lara/steppanels/index.js +3 -0
  209. package/templates/nuxt/presets/lara/stepper/index.js +13 -0
  210. package/templates/nuxt/presets/lara/steps/index.js +111 -0
  211. package/templates/nuxt/presets/lara/tab/index.js +42 -0
  212. package/templates/nuxt/presets/lara/tablist/index.js +8 -0
  213. package/templates/nuxt/presets/lara/tabmenu/index.js +73 -0
  214. package/templates/nuxt/presets/lara/tabpanel/index.js +3 -0
  215. package/templates/nuxt/presets/lara/tabpanels/index.js +3 -0
  216. package/templates/nuxt/presets/lara/tabs/index.js +5 -0
  217. package/templates/nuxt/presets/lara/tabview/index.js +156 -0
  218. package/templates/nuxt/presets/lara/tag/index.js +38 -0
  219. package/templates/nuxt/presets/lara/terminal/index.js +60 -0
  220. package/templates/nuxt/presets/lara/textarea/index.js +39 -0
  221. package/templates/nuxt/presets/lara/tieredmenu/index.js +121 -0
  222. package/templates/nuxt/presets/lara/timeline/index.js +81 -0
  223. package/templates/nuxt/presets/lara/toast/index.js +102 -0
  224. package/templates/nuxt/presets/lara/togglebutton/index.js +45 -0
  225. package/templates/nuxt/presets/lara/toggleswitch/index.js +80 -0
  226. package/templates/nuxt/presets/lara/toolbar/index.js +28 -0
  227. package/templates/nuxt/presets/lara/tooltip/index.js +46 -0
  228. package/templates/nuxt/presets/lara/tree/index.js +101 -0
  229. package/templates/nuxt/presets/lara/treeselect/index.js +102 -0
  230. package/templates/nuxt/presets/lara/treetable/index.js +305 -0
  231. package/templates/nuxt/providers/my-provider.ts.eta +1 -1
  232. package/templates/nuxt/server/api/profile/[...].ts.eta +4 -3
  233. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +10 -20
  234. package/templates/nuxt/tailwind.config.ts._eta +4 -15
  235. package/templates/nuxt/types/schema.ts.eta +1 -1
  236. package/templates/nuxt/types/user.ts.eta +6 -1
  237. package/templates/project/jsonschemas/appintegration.json_eta +227 -0
  238. package/templates/project/sharelibs/validate.ts.eta +23 -0
  239. package/templates/nuxt/components/image/ImageAvatar.vue.eta._vue +0 -57
@@ -42,7 +42,10 @@ import {
42
42
  DeleteResultType,
43
43
  WorkflowName,
44
44
  TextSearchBody,
45
+ CheckMutipleUnionExistResponse,
45
46
  } from '../types';
47
+ import { CustomException } from 'src/customexception';
48
+
46
49
  @Injectable()
47
50
  export class SimpleAppService<T extends { _id?: string; __v?: number }> {
48
51
  @Inject(EventEmitter2)
@@ -114,6 +117,8 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
114
117
  this.data = { ...newdata };
115
118
  return this;
116
119
  };
120
+ getDocumentIdentityCode = () => this.documentIdentityCode;
121
+ getDocumentIdentityLabel = () => this.documentIdentityLabel;
117
122
  public isReadOnly(): boolean {
118
123
  return false;
119
124
  }
@@ -164,7 +169,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
164
169
  try {
165
170
  const filter1 = {};
166
171
  const filter2 = {};
167
- let filters: any[] = [];
172
+ const filters: any[] = [];
168
173
  if (
169
174
  this.jsonschema.properties[this.documentIdentityCode]['type'] ==
170
175
  'string'
@@ -178,7 +183,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
178
183
  const filterobj = { $or: filters };
179
184
  Object.assign(filterobj, data);
180
185
  Object.assign(filterobj, this.getIsolationFilter(appuser));
181
- let projections = {
186
+ const projections = {
182
187
  label: `\$${this.documentIdentityLabel}`,
183
188
  code: `\$${this.documentIdentityCode}`,
184
189
  };
@@ -186,7 +191,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
186
191
  Object.assign(projections, this.moreAutoCompleteField);
187
192
  }
188
193
  const products = await this.doc.find(filterobj, projections, {
189
- limit: this.LIMITPERPAGE,
194
+ // limit: this.LIMITPERPAGE,
190
195
  });
191
196
  const productlist = products.map((p: T) => {
192
197
  return p;
@@ -203,10 +208,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
203
208
  * @param filters
204
209
  * @returns
205
210
  */
206
- private async searchNoIsolation(
207
- appuser: UserContext,
208
- filters: FilterQuery<T>,
209
- ) {
211
+ async searchNoIsolation(appuser: UserContext, filters: FilterQuery<T>) {
210
212
  try {
211
213
  if (this.hooks.beforeSearch)
212
214
  await this.hooks.beforeSearch(appuser, filters);
@@ -224,6 +226,23 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
224
226
  }
225
227
  // return this;
226
228
  }
229
+ async aggregateNoIsolation(appuser: UserContext, pipeline: PipelineStage[]) {
230
+ if (pipeline[0] && pipeline[0]['$match']) {
231
+ try {
232
+ this.logger.verbose(pipeline, `${this.documentName} aggregate:`);
233
+
234
+ return await this.doc.aggregate(pipeline, {
235
+ session: appuser.getDBSession(),
236
+ });
237
+ } catch (err) {
238
+ throw new InternalServerErrorException(err);
239
+ }
240
+ } else {
241
+ throw new InternalServerErrorException(
242
+ 'first aggregate pipelinestage shall use $match',
243
+ );
244
+ }
245
+ }
227
246
  async aggregate(appuser: UserContext, pipeline: PipelineStage[]) {
228
247
  if (pipeline[0] && pipeline[0]['$match']) {
229
248
  try {
@@ -271,13 +290,12 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
271
290
  } else {
272
291
  const pipelines = this.searchToAggregate(
273
292
  appuser,
274
- filters,
293
+ newfilters,
275
294
  projection,
276
295
  sort,
277
296
  lookup,
278
297
  );
279
298
  this.logger.debug('after aggregate', pipelines);
280
-
281
299
  searchResults = await this.aggregate(appuser, pipelines);
282
300
  }
283
301
 
@@ -296,16 +314,60 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
296
314
  }
297
315
 
298
316
  async fullTextSearch(appuser: UserContext, body: TextSearchBody) {
299
- const isolationFilter = { ...this.getIsolationFilter(appuser) };
300
- this.polishIsolationFilter(isolationFilter);
317
+ try {
318
+ const isolationFilter = { ...this.getIsolationFilter(appuser) };
319
+ this.polishIsolationFilter(isolationFilter);
320
+ const keyword = body.keyword;
301
321
 
302
- const filters = { $text: { $search: body.keyword } };
303
- const newfilters: FilterQuery<T> = { ...filters, ...isolationFilter };
304
- const fields = body.fields;
305
- const sorts = body.sorts;
306
- //not yet support lookup mapper
307
- const lookup = body.lookup;
308
- return await this.doc.find(newfilters, fields, sorts);
322
+ // Prepare regex filter
323
+ const orConditions: any[] = [];
324
+ if (body.fields && body.fields.length > 0) {
325
+ body.fields.forEach((field: string) => {
326
+ if (
327
+ field != 'defaultPrice' &&
328
+ field != 'amount' &&
329
+ field != 'active' &&
330
+ field != 'updated'
331
+ ) {
332
+ orConditions.push({
333
+ [field]: { $regex: keyword, $options: 'i' },
334
+ });
335
+ } else {
336
+ if (
337
+ !isNaN(Number(keyword)) &&
338
+ (field == 'defaultPrice' || field == 'amount')
339
+ ) {
340
+ orConditions.push({
341
+ [field]: { $gte: keyword },
342
+ });
343
+ }
344
+ }
345
+ });
346
+ }
347
+ const filter = {
348
+ $or: orConditions,
349
+ };
350
+
351
+ const tmpfilters: FilterQuery<T> = { ...filter, ...isolationFilter };
352
+ const newfilters: FilterQuery<T> = {
353
+ $and: [tmpfilters],
354
+ };
355
+
356
+ const fields = body.fields || {};
357
+ const sorts = body.sorts || {};
358
+
359
+ // Ensure `this.doc` is a Mongoose model or similar
360
+ const results = await this.doc
361
+ .find(newfilters, fields)
362
+ .sort(sorts)
363
+ .exec();
364
+
365
+ return results;
366
+ } catch (error) {
367
+ console.error('Error during full-text search:', error);
368
+ // Ensure error handling returns a valid status code
369
+ throw new Error('Failed to perform search');
370
+ }
309
371
  }
310
372
  async findById(appuser: UserContext, id: string) {
311
373
  if (this.hooks.beforeFetchRecord)
@@ -323,6 +385,129 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
323
385
  }
324
386
  }
325
387
 
388
+ async findByIdNoIsolation(appuser: UserContext, id: string) {
389
+ if (this.hooks.beforeFetchRecord)
390
+ await this.hooks.beforeFetchRecord(appuser, id);
391
+
392
+ const data = await this.searchNoIsolation(appuser, { _id: id as any });
393
+ if (this.hooks.afterFetchRecord)
394
+ await this.hooks.afterFetchRecord(appuser, data[0]);
395
+
396
+ if (data.length == 1) {
397
+ // console.log('data0', data[0]);
398
+ return data[0];
399
+ } else {
400
+ return null;
401
+ }
402
+ }
403
+
404
+ async createManyWithId(appuser: UserContext, datas: T[]) {
405
+ if (Array.isArray(datas)) {
406
+ for (let i = 0; i < datas.length; i++) {
407
+ const data = datas[i];
408
+ let isolationFilter: any = { ...appuser.getCreateFilterWithId() };
409
+ isolationFilter = this.polishIsolationFilter(isolationFilter, data);
410
+
411
+ Object.assign(data, isolationFilter);
412
+ this.reCalculateValue(data);
413
+ await this.validateData(appuser, data);
414
+ this.applyNestedDateTime(appuser, data, 'create');
415
+ }
416
+
417
+ const result = await this.doc.insertMany(datas);
418
+ await this.audittrail.addManyEvents(
419
+ appuser,
420
+ this.documentName,
421
+ 'createMany',
422
+ datas,
423
+ );
424
+ return result;
425
+ } else {
426
+ throw new BadRequestException(
427
+ this.getDocumentType() + ': create many only support array',
428
+ );
429
+ }
430
+ }
431
+
432
+ /**
433
+ * create many from array with hooks (temporary used for generate sample data only)
434
+ * @param appuser
435
+ * @param datas
436
+ */
437
+ async createManyWithHook(appuser: UserContext, datas: T[]) {
438
+ if (Array.isArray(datas)) {
439
+ for (let i = 0; i < datas.length; i++) {
440
+ const data = datas[i];
441
+
442
+ let result;
443
+ const dbsession = appuser.getDBSession();
444
+ if (dbsession && !dbsession.inTransaction()) {
445
+ dbsession.startTransaction();
446
+ }
447
+
448
+ if (this.withDocNumberFormat && !data[this.documentIdentityCode]) {
449
+ await this.genNewDocNo(appuser, data);
450
+ }
451
+
452
+ let isolationFilter: any = { ...appuser.getCreateFilterWithId() };
453
+ isolationFilter = this.polishIsolationFilter(isolationFilter, data);
454
+
455
+ Object.assign(data, isolationFilter);
456
+ this.reCalculateValue(data);
457
+ await this.validateData(appuser, data);
458
+ this.applyNestedDateTime(appuser, data, 'create');
459
+ if (this.hooks.beforeCreate)
460
+ await this.hooks.beforeCreate(appuser, data);
461
+ const newdoc = new this.doc(data);
462
+
463
+ try {
464
+ result = await newdoc.save({ session: dbsession });
465
+ await this.audittrail.addEvent(
466
+ appuser,
467
+ this.documentName,
468
+ result._id,
469
+ 'create',
470
+ data,
471
+ );
472
+ appuser.addInsertedRecordId(this.documentName, result._id);
473
+ } catch (err) {
474
+ this.logger.error(err);
475
+ const processdata = await this.runWorker(
476
+ appuser,
477
+ 'processdata.processError',
478
+ {
479
+ err: err,
480
+ },
481
+ );
482
+
483
+ if (!processdata) {
484
+ throw new InternalServerErrorException(err);
485
+ } else {
486
+ throw new CustomException(processdata.code, processdata.msg);
487
+ }
488
+ }
489
+
490
+ try {
491
+ if (this.hooks.afterCreate)
492
+ await this.hooks.afterCreate(appuser, result);
493
+ this.callWebhook(appuser, 'create', result);
494
+
495
+ // return result as T;
496
+ } catch (err) {
497
+ throw new InternalServerErrorException(
498
+ `createHook ${this.documentType} error: ${JSON.stringify(err)}`,
499
+ `${this.documentType} createHook error`,
500
+ );
501
+ }
502
+ }
503
+ } else {
504
+ throw new BadRequestException(
505
+ this.getDocumentType() + ': create many only support array',
506
+ );
507
+ }
508
+ return 'ok';
509
+ }
510
+
326
511
  /**
327
512
  * create many from array, for performance reason it submit all item in 1 go, so it won't implement hooks
328
513
  * @param appuser
@@ -355,8 +540,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
355
540
  );
356
541
  }
357
542
  }
358
-
359
- async create(appuser: UserContext, data: T) {
543
+ async createWithId(appuser: UserContext, data: T) {
360
544
  let result;
361
545
 
362
546
  if (!data._id) {
@@ -378,7 +562,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
378
562
  await this.genNewDocNo(appuser, data);
379
563
  }
380
564
 
381
- let isolationFilter: any = { ...appuser.getCreateFilter() };
565
+ let isolationFilter: any = { ...appuser.getCreateFilterWithId() };
382
566
  isolationFilter = this.polishIsolationFilter(isolationFilter, data);
383
567
 
384
568
  this.logger.debug('isolationFilter', 'SimpleAppService');
@@ -407,13 +591,103 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
407
591
  appuser.addInsertedRecordId(this.documentName, result._id);
408
592
  } catch (err) {
409
593
  this.logger.error(err);
410
- throw new InternalServerErrorException(err);
594
+ const processdata = await this.runWorker(
595
+ appuser,
596
+ 'processdata.processError',
597
+ {
598
+ err: err,
599
+ },
600
+ );
601
+
602
+ if (!processdata) {
603
+ throw new InternalServerErrorException(err);
604
+ } else {
605
+ throw new CustomException(processdata.code, processdata.msg);
606
+ }
607
+ }
608
+
609
+ try {
610
+ if (this.hooks.afterCreate) await this.hooks.afterCreate(appuser, result);
611
+ this.callWebhook(appuser, 'create', result);
612
+ return result as T;
613
+ } catch (err) {
614
+ throw new InternalServerErrorException(
615
+ `createHook ${this.documentType} error: ${JSON.stringify(err)}`,
616
+ `${this.documentType} createHook error`,
617
+ );
411
618
  }
619
+ }
412
620
 
413
- // this.doc.create(data)
414
- // this.doc
621
+ async create(
622
+ appuser: UserContext,
623
+ data: T,
624
+ noStartTransaction: boolean = false,
625
+ ) {
626
+ let result;
627
+
628
+ if (!data._id) {
629
+ data._id = crypto.randomUUID();
630
+ }
631
+ const dbsession = appuser.getDBSession();
632
+ if (dbsession && !dbsession.inTransaction() && !noStartTransaction) {
633
+ dbsession.startTransaction();
634
+ }
635
+
636
+ this.logger.debug(
637
+ 'this.withDocNumberFormat :' +
638
+ this.withDocNumberFormat +
639
+ ' && ' +
640
+ '!data[this.documentIdentityCode] ==' +
641
+ !data[this.documentIdentityCode],
642
+ );
643
+ if (this.withDocNumberFormat && !data[this.documentIdentityCode]) {
644
+ await this.genNewDocNo(appuser, data);
645
+ }
646
+
647
+ let isolationFilter: any = { ...appuser.getCreateFilter() };
648
+ isolationFilter = this.polishIsolationFilter(isolationFilter, data);
649
+
650
+ this.logger.debug('isolationFilter', 'SimpleAppService');
651
+ this.logger.debug(isolationFilter, 'SimpleAppService');
652
+ this.logger.debug('Create data before isolation', 'SimpleAppService');
653
+ this.logger.debug(data, 'SimpleAppService');
654
+ Object.assign(data, isolationFilter);
655
+ this.reCalculateValue(data);
656
+ await this.validateData(appuser, data);
657
+ this.logger.debug(data, `after create validation`);
658
+ this.applyNestedDateTime(appuser, data, 'create');
659
+
660
+ if (this.hooks.beforeCreate) await this.hooks.beforeCreate(appuser, data);
661
+ this.logger.debug(data, `Create Record ${this.documentName}`);
662
+ const newdoc = new this.doc(data);
663
+ await this.identifyForeignKeys(appuser, data);
664
+ try {
665
+ result = await newdoc.save({ session: dbsession });
666
+ await this.audittrail.addEvent(
667
+ appuser,
668
+ this.documentName,
669
+ result._id,
670
+ 'create',
671
+ data,
672
+ );
673
+ appuser.addInsertedRecordId(this.documentName, result._id);
674
+ } catch (err) {
675
+ this.logger.error(err);
676
+ const processdata = await this.runWorker(
677
+ appuser,
678
+ 'processdata.processError',
679
+ {
680
+ err: err,
681
+ },
682
+ );
683
+
684
+ if (!processdata) {
685
+ throw new InternalServerErrorException(err);
686
+ } else {
687
+ throw new CustomException(processdata.code, processdata.msg);
688
+ }
689
+ }
415
690
 
416
- // result = await newdoc.save()
417
691
  try {
418
692
  if (this.hooks.afterCreate) await this.hooks.afterCreate(appuser, result);
419
693
  this.callWebhook(appuser, 'create', result);
@@ -461,11 +735,13 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
461
735
  }
462
736
  };
463
737
  async validateData(appuser: UserContext, data: T, _id?: string) {
738
+ // console.log('validatedata');
464
739
  const ajv = new Ajv({ allErrors: true, useDefaults: true });
465
740
  addFormats(ajv);
466
741
  addErrors(ajv);
467
742
 
468
- ajv.addFormat('tel', /^$|^\d{7,15}$/gm);
743
+ // ajv.addFormat('tel', /^$|^\d{7,15}$/gm);
744
+ ajv.addFormat('tel', /.*$/);
469
745
  ajv.addFormat('text', /.*$/);
470
746
  ajv.addFormat('html', /.*$/);
471
747
  ajv.addFormat('documentno', /.*$/);
@@ -500,12 +776,14 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
500
776
  }
501
777
  const valid = validate(data);
502
778
  if (!valid) {
779
+ this.logger.error(JSON.stringify(data));
503
780
  this.logger.error(JSON.stringify(validate.errors), 'validate errors:');
504
781
  throw new BadRequestException(
505
782
  'Data validation failed',
506
783
  validate.errors as HttpExceptionOptions,
507
784
  );
508
785
  }
786
+ //no check for duplicate those
509
787
  if (this.hooks.afterValidation)
510
788
  await this.hooks.afterValidation(appuser, data, _id);
511
789
  }
@@ -555,7 +833,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
555
833
  dependency = await this.getRelatedRecords(appuser, id);
556
834
  //console.log('dependency', dependency);
557
835
  if (!dependency) {
558
- let filterIsolation = this.getIsolationFilter(appuser);
836
+ const filterIsolation = this.getIsolationFilter(appuser);
559
837
  this.polishIsolationFilter(filterIsolation);
560
838
 
561
839
  filterIsolation['_id'] = id;
@@ -590,11 +868,17 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
590
868
  } else {
591
869
  this.logger.debug('reject query', dependency);
592
870
 
593
- throw new ForbiddenException(dependency, 'Foreignkey constraint');
871
+ throw new ForbiddenException(
872
+ `This system detected that the [${this.documentName}] data has been used in other record`,
873
+ 'Foreignkey constraint',
874
+ );
594
875
  }
595
876
  } catch (err) {
596
- throw new InternalServerErrorException(err);
597
- //JSON.stringify(dependency),JSON.stringify(dependency)
877
+ if (err instanceof ForbiddenException) {
878
+ throw new ForbiddenException(err);
879
+ } else {
880
+ throw new InternalServerErrorException(err);
881
+ } //JSON.stringify(dependency),JSON.stringify(dependency)
598
882
  }
599
883
  }
600
884
 
@@ -602,7 +886,12 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
602
886
  // this.doc.updateOne(data);
603
887
  // };
604
888
 
605
- findIdThenUpdate = async (appuser: UserContext, id: string, data: T) => {
889
+ findIdThenUpdate = async (
890
+ appuser: UserContext,
891
+ id: string,
892
+ data: T,
893
+ noStartTransaction: boolean = false,
894
+ ) => {
606
895
  try {
607
896
  //version exists, need ensure different only 1
608
897
  const existingdata = await this.findById(appuser, id);
@@ -631,7 +920,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
631
920
  await this.hooks.beforeUpdate(appuser, id, existingdata, data);
632
921
 
633
922
  const dbsession = appuser.getDBSession();
634
- if (dbsession && !dbsession.inTransaction()) {
923
+ if (dbsession && !dbsession.inTransaction() && !noStartTransaction) {
635
924
  dbsession.startTransaction();
636
925
  }
637
926
  // try {
@@ -672,6 +961,80 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
672
961
  }
673
962
  };
674
963
 
964
+ findIdThenUpdateNoIsolation = async (
965
+ appuser: UserContext,
966
+ id: string,
967
+ data: T,
968
+ ) => {
969
+ try {
970
+ //version exists, need ensure different only 1
971
+ const existingdata = await this.findByIdNoIsolation(appuser, id);
972
+ if (!existingdata)
973
+ throw new NotFoundException(
974
+ `${this.documentName} findIdThenUpdate: _id:${id} not found`,
975
+ 'not found',
976
+ );
977
+
978
+ this.logger.debug(
979
+ 'update id:' + id,
980
+ this.documentName + ' findIdThenUpdate',
981
+ );
982
+ if (typeof data.__v == 'number' && data.__v != existingdata.__v) {
983
+ throw new BadRequestException(
984
+ `You submit older version data "v${data.__v}"" but latest version = "v${existingdata.__v}"`,
985
+ );
986
+ }
987
+ // this.logger.debug('warn1', existingdata);
988
+ data.__v = existingdata.__v + 1;
989
+ // if (!existingdata) {
990
+ // throw new NotFoundException(`${id} not found`, 'not found');
991
+ // }
992
+ // this.logger.debug('warn2');
993
+ if (this.hooks.beforeUpdate)
994
+ await this.hooks.beforeUpdate(appuser, id, existingdata, data);
995
+
996
+ const dbsession = appuser.getDBSession();
997
+ if (dbsession && !dbsession.inTransaction()) {
998
+ dbsession.startTransaction();
999
+ }
1000
+ // try {
1001
+ // Object.assign(data, appuser.getUpdateFilter());
1002
+ // Object.assign(existingdata, data);
1003
+
1004
+ delete data['_id'];
1005
+ this.reCalculateValue(data);
1006
+
1007
+ // existingdata['_id']=''
1008
+ await this.validateData(appuser, data, id);
1009
+
1010
+ const isolationFilter = {};
1011
+ // this.polishIsolationFilter(isolationFilter);
1012
+ isolationFilter['_id'] = id;
1013
+ this.applyNestedDateTime(appuser, data, 'update');
1014
+
1015
+ const result = await this.doc.findOneAndReplace(isolationFilter, data, {
1016
+ session: dbsession,
1017
+ new: true,
1018
+ });
1019
+ await this.audittrail.addEvent(
1020
+ appuser,
1021
+ this.documentName,
1022
+ id,
1023
+ 'update',
1024
+ data,
1025
+ );
1026
+
1027
+ appuser.addUpdatedRecordId(this.documentName, data._id);
1028
+ if (this.hooks.afterUpdate)
1029
+ await this.hooks.afterUpdate(appuser, id, existingdata, result);
1030
+ this.callWebhook(appuser, 'update', result);
1031
+ return result; // await this.findById(appuser, id);
1032
+ } catch (err) {
1033
+ this.logger.error(err);
1034
+ throw new InternalServerErrorException(err.message);
1035
+ }
1036
+ };
1037
+
675
1038
  findIdThenPatch = async (
676
1039
  appuser: UserContext,
677
1040
  id: string,
@@ -764,13 +1127,16 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
764
1127
  for (let j = 0; j < fobjs.length; j++) {
765
1128
  const fkey = fobjs[j];
766
1129
  //not deleted in current session, check from database
767
- let filter = {};
1130
+ const filter = {};
768
1131
  filter[fkey] = id;
769
1132
  const result = await collection.findOne(filter, {
770
1133
  session: appuser.getDBSession(),
771
1134
  });
772
1135
  if (result) {
773
- this.logger.error(result, 'related result found');
1136
+ this.logger.error(
1137
+ result,
1138
+ `related result found in ${collectionname} ${fkey} = ${id}`,
1139
+ );
774
1140
  return result;
775
1141
  }
776
1142
  }
@@ -960,7 +1326,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
960
1326
 
961
1327
  keystore[collectionname] = results;
962
1328
  //console.log("keystorekeystore",keystore)
963
- let addfield = { $addFields: { collection: collectionname } };
1329
+ const addfield = { $addFields: { collection: collectionname } };
964
1330
 
965
1331
  const stagefilter: PipelineStage = {
966
1332
  $unionWith: {
@@ -986,7 +1352,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
986
1352
  pipelines as HttpExceptionOptions,
987
1353
  );
988
1354
  } else {
989
- let searchresult: any = {};
1355
+ const searchresult: any = {};
990
1356
  unionresult.forEach((item) => {
991
1357
  if (searchresult[item.collection]) {
992
1358
  searchresult[item.collection].push(item._id);
@@ -1036,6 +1402,23 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
1036
1402
  return pdfresult;
1037
1403
  }
1038
1404
 
1405
+ async checkMultipleUnionExist(
1406
+ appuser: UserContext,
1407
+ data: string[],
1408
+ ): Promise<CheckMutipleUnionExistResponse> {
1409
+ const response: CheckMutipleUnionExistResponse = [];
1410
+ const unionKey = this.getDocumentIdentityCode();
1411
+ const searchQuery: any = { [unionKey]: { $in: data } };
1412
+ // search for multiple union exist
1413
+ const result = await this.search(appuser, searchQuery);
1414
+ for (const item of data) {
1415
+ const found = result.find((x) => x[unionKey] === item);
1416
+ response.push({ [item]: found ? 1 : 0 });
1417
+ }
1418
+
1419
+ return response;
1420
+ }
1421
+
1039
1422
  searchToAggregate(
1040
1423
  appuser: UserContext,
1041
1424
  filter: FilterQuery<T>,
@@ -1058,7 +1441,7 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
1058
1441
  collections.forEach((tokey: string) => {
1059
1442
  const toarr = tokey.split('.');
1060
1443
  const to = toarr[0];
1061
- toarr.splice(0,1)
1444
+ toarr.splice(0, 1);
1062
1445
  const foreignField = toarr.join('.') ?? '_id';
1063
1446
  pipelines.push({
1064
1447
  $lookup: {
@@ -1069,7 +1452,9 @@ export class SimpleAppService<T extends { _id?: string; __v?: number }> {
1069
1452
  pipeline: [{ $match: { tenantId: appuser.getTenantId() } }],
1070
1453
  },
1071
1454
  });
1072
- pipelines.push({ $unwind: '$_' + to });
1455
+
1456
+ // for support multiple data on lookup
1457
+ // pipelines.push({ $unwind: '$_' + to });
1073
1458
 
1074
1459
  if (Object.keys(projection).length > 0) projection['_' + to] = 1;
1075
1460
  });
@@ -1,6 +1,6 @@
1
1
  /**
2
- * This file was automatically generated by simpleapp generator. Every
3
- * MODIFICATION OVERRIDE BY GENERATEOR
2
+ * This file was automatically generated by simpleapp generator. It is changable.
3
+ * --remove-this-line-to-prevent-override--
4
4
  * last change 2024-02-23
5
5
  * Author: Ks Tan
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
- * This file was automatically generated by simpleapp generator. Every
3
- * MODIFICATION OVERRIDE BY GENERATEOR
2
+ * This file was automatically generated by simpleapp generator. It is changable.
3
+ * --remove-this-line-to-prevent-override--
4
4
  * last change 2024-02-23
5
5
  * Author: Ks Tan
6
6
  */