@simitgroup/simpleapp-generator 1.0.23 → 1.0.25

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 (66) hide show
  1. package/README.md +48 -0
  2. package/dist/createproject.js +1 -1
  3. package/dist/createproject.js.map +1 -1
  4. package/dist/framework.js +37 -25
  5. package/dist/framework.js.map +1 -1
  6. package/dist/generate.js +38 -16
  7. package/dist/generate.js.map +1 -1
  8. package/dist/index.js +2 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/processors/jsonschemabuilder.js +9 -9
  11. package/dist/processors/jsonschemabuilder.js.map +1 -1
  12. package/package.json +1 -1
  13. package/src/framework.ts +50 -36
  14. package/src/generate.ts +37 -21
  15. package/src/index.ts +2 -1
  16. package/src/processors/jsonschemabuilder.ts +9 -9
  17. package/src/type.ts +1 -0
  18. package/templates/basic/apischema.eta +8 -4
  19. package/templates/basic/controller.eta +21 -5
  20. package/templates/basic/jsonschema.eta +2 -0
  21. package/templates/basic/model.eta +4 -7
  22. package/templates/basic/module.eta +2 -0
  23. package/templates/basic/pageindex.vue.eta +28 -15
  24. package/templates/basic/pageindexwithid.vue.eta +13 -1
  25. package/templates/basic/service.eta +11 -9
  26. package/templates/basic/simpleappclient.eta +9 -8
  27. package/templates/basic/type.eta +2 -1
  28. package/templates/nest/SimpleAppController.eta +5 -5
  29. package/templates/nest/SimpleAppService.eta +87 -31
  30. package/templates/nest/TenantMiddleware.eta +39 -0
  31. package/templates/nest/User.eta +115 -0
  32. package/templates/nest/app.module.eta +24 -4
  33. package/templates/nest/inputvalidation-exception.eta +6 -0
  34. package/templates/nest/nest.env.eta +12 -1
  35. package/templates/nest/nest.main.eta +14 -3
  36. package/templates/nest/oauth2-redirect.eta +79 -0
  37. package/templates/nuxt/components.crudsimple.vue.eta +60 -48
  38. package/templates/nuxt/components.debugdocdata.vue.eta +12 -4
  39. package/templates/nuxt/components.eventmonitor.vue.eta +17 -11
  40. package/templates/nuxt/components.menus.vue.eta +14 -12
  41. package/templates/nuxt/composables.getautocomplete.ts.eta +19 -8
  42. package/templates/nuxt/composables.getmenus.ts.eta +27 -9
  43. package/templates/nuxt/env.eta +12 -0
  44. package/templates/nuxt/layouts.default.vue.eta +10 -3
  45. package/templates/nuxt/nuxt.config.ts.eta +10 -6
  46. package/templates/nuxt/pages.[xorg].index.vue.eta +19 -0
  47. package/templates/nuxt/pages.index.vue.eta +17 -1
  48. package/templates/nuxt/pages.login.vue.eta +20 -0
  49. package/templates/nuxt/plugins.simpleapp.ts.eta +12 -4
  50. package/templates/nuxt/server.api.auth.logout.ts.eta +12 -0
  51. package/templates/nuxt/server.api.auth[...].ts.eta +144 -0
  52. package/templates/nuxt/server.api.ts.eta +33 -19
  53. package/src/createproject.ts +0 -121
  54. package/src/index2.ts-old +0 -132
  55. package/src/installdependency.sh +0 -5
  56. package/src/installnest.ts +0 -0
  57. package/src/installnuxt.ts +0 -0
  58. package/templates/basic/backend.config.eta +0 -1
  59. package/templates/basic/beforesave.eta +0 -7
  60. package/templates/basic/controller2.eta +0 -86
  61. package/templates/basic/frontend.config.eta +0 -1
  62. package/templates/basic/model-converter.etabackup +0 -21
  63. package/templates/basic/readme.eta +0 -3
  64. package/templates/basic/service.etabackupe +0 -106
  65. package/templates/basic/type.etabackup +0 -23
  66. package/templates/basic/uischema.eta +0 -13
package/src/framework.ts CHANGED
@@ -13,6 +13,12 @@ let config = {
13
13
  "frontendFolder":"./myfrontend",
14
14
  "frontendPort":"8080",
15
15
  "openapi3Yaml":"../openapi.yaml",
16
+ "keycloaksetting":{
17
+ "OAUTH2_CONFIGURL":"https://keycloak-server-url/realms/realm-name",
18
+ "OAUTH2_CLIENTID":"client-id",
19
+ "OAUTH2_CLIENTSECRET":"client-secret-value",
20
+ "AUTH_SECRET_KEY":"my-secret",
21
+ }
16
22
  }
17
23
 
18
24
  export const setConfiguration=(paraconfig)=>{
@@ -50,57 +56,61 @@ export const runCreateNuxt = (callback:Function) =>{
50
56
  export const prepareNest = (callback:Function)=>{
51
57
  const targetfolder =config.backendFolder
52
58
  log.info(`creating backend project ${targetfolder}`)
53
- exec(`cd ${targetfolder};pnpm install --save @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config`,async (error, stdout, stderr)=>{
54
- // log.info(`dependency installed`)
55
- if(!error){
56
- exec(`pnpm install ajv ajv-formats axios json-schema`, (error, stdout, stderr)=>{
57
- const eta = new Eta({views: constants.templatedir});
58
- const variables={
59
- backendPort:config.backendPort,
60
- mongoConnectStr:config.mongoConnectStr
61
- }
62
- const txtEnv = eta.render('./nest/nest.env.eta', variables);
63
- const txtMain = eta.render('./nest/nest.main.eta', variables);
59
+ if(!fs.existsSync(`${targetfolder}/.env`)){
64
60
 
65
- fs.writeFileSync(`${targetfolder}/.env`, txtEnv);
66
- fs.writeFileSync(`${targetfolder}/src/main.ts`, txtMain);
67
- const tsconfigpath = process.cwd()+'/'+`${targetfolder}/tsconfig.json`
68
- const tsconfig = require(tsconfigpath)
69
- tsconfig.compilerOptions.esModuleInterop=true
70
- tsconfig.compilerOptions.resolveJsonModule=true
71
- fs.writeFileSync(tsconfigpath, JSON.stringify(tsconfig));
61
+
62
+ exec(`cd ${targetfolder};pnpm install --save @nestjs/serve-static axios @darkwolf/base64url json-schema @wearenova/mongoose-tenant @nestjs/swagger @nestjs/mongoose mongoose ajv ajv-formats @nestjs/config`,async (error, stdout, stderr)=>{
63
+ // log.info(`dependency installed`)
64
+ if(!error){
65
+ fs.mkdirSync(`${targetfolder}/public_html`,{recursive:true})
66
+ const eta = new Eta({views: constants.templatedir});
67
+ const variables=config
68
+ const txtEnv = eta.render('./nest/nest.env.eta', variables);
69
+ const txtMain = eta.render('./nest/nest.main.eta', variables);
70
+ const txtRedirectHtml = eta.render('./nest/oauth2-redirect.eta', variables);
72
71
 
73
- log.info("nest project completed")
74
- callback()
72
+ fs.writeFileSync(`${targetfolder}/.env`, txtEnv);
73
+ fs.writeFileSync(`${targetfolder}/src/main.ts`, txtMain);
74
+ fs.writeFileSync(`${targetfolder}/public_html/oauth2-redirect.html`, txtRedirectHtml);
75
+ const tsconfigpath = process.cwd()+'/'+`${targetfolder}/tsconfig.json`
76
+ const tsconfig = require(tsconfigpath)
77
+ tsconfig.compilerOptions.esModuleInterop=true
78
+ tsconfig.compilerOptions.resolveJsonModule=true
79
+ fs.writeFileSync(tsconfigpath, JSON.stringify(tsconfig));
80
+
81
+ log.info("nest project completed")
82
+ callback()
83
+
84
+ } else{
85
+ log.error(stderr)
86
+ throw error
87
+ }
75
88
  })
76
- } else{
77
- log.error(stderr)
78
- throw error
79
- }
80
- })
89
+ }else{
90
+ log.info(`${targetfolder}/.env exists, skip regenerate environment`)
91
+ callback()
92
+ }
81
93
  }
82
94
  //prepare nuxt project for simpleapp generator
83
95
  export const prepareNuxt = (callback:Function)=>{
84
96
  const targetfolder = config.frontendFolder
85
97
  if(!fs.existsSync(`${targetfolder}/.env`)){
86
98
  //asume no environment. prepare now
87
- exec(`cd ${targetfolder};pnpm install;pnpm install -D @types/node @vueuse/nuxt @sidebase/nuxt-auth @vueuse/core nuxt-security prettier @nuxtjs/tailwindcss`, (error, stdout, stderr)=>{
99
+ exec(`cd ${targetfolder};pnpm install;pnpm install -D @sidebase/nuxt-auth @nuxt/ui @types/node @vueuse/nuxt @sidebase/nuxt-auth @vueuse/core nuxt-security prettier `, (error, stdout, stderr)=>{
88
100
  //;pnpm install
89
101
  console.log(error, stdout, stderr)
90
- exec(`cd ${targetfolder};pnpm install --save ajv dotenv @fullcalendar/core @fullcalendar/vue3 quill uuid ajv-formats primeflex primeicons prettier primevue axios json-schema mitt @simitgroup/simpleapp-vue-component@latest`, (error, stdout, stderr)=>{
102
+ exec(`cd ${targetfolder};pnpm install --save next-auth@4.21.1 @darkwolf/base64url @nuxt/ui ajv dotenv @fullcalendar/core @fullcalendar/vue3 quill uuid ajv-formats primeflex primeicons prettier primevue axios json-schema mitt @simitgroup/simpleapp-vue-component@latest`, (error, stdout, stderr)=>{
91
103
  console.log(error, stdout, stderr)
92
104
 
93
105
  fs.mkdirSync(`${targetfolder}/assets/css/`,{recursive:true})
94
106
  fs.mkdirSync(`${targetfolder}/layouts`,{recursive:true})
95
107
  fs.mkdirSync(`${targetfolder}/components`,{recursive:true})
96
- fs.mkdirSync(`${targetfolder}/server/api`,{recursive:true})
97
- fs.mkdirSync(`${targetfolder}/pages`,{recursive:true})
108
+ fs.mkdirSync(`${targetfolder}/server/api/[xorg]`,{recursive:true})
109
+ fs.mkdirSync(`${targetfolder}/server/api/auth`,{recursive:true})
110
+ fs.mkdirSync(`${targetfolder}/pages/[xorg]`,{recursive:true})
98
111
  fs.mkdirSync(`${targetfolder}/plugins`,{recursive:true})
99
112
  const eta = new Eta({views: `${constants.templatedir}/nuxt`});
100
- const variables={
101
- backendPort:config.backendPort,
102
- frontendPort:config.frontendPort
103
- }
113
+ const variables=config
104
114
  const writes = {
105
115
  './app.vue.eta':'app.vue',
106
116
  './components.eventmonitor.vue.eta':'components/EventMonitor.vue',
@@ -108,12 +118,16 @@ export const prepareNuxt = (callback:Function)=>{
108
118
  './components.crudsimple.vue.eta':'components/CrudSimple.vue',
109
119
  './components.debugdocdata.vue.eta':'components/DebugDocumentData.vue',
110
120
  './layouts.default.vue.eta':'layouts/default.vue',
111
- './server.api.ts.eta':'server/api/[...].ts',
121
+ './server.api.ts.eta':'server/api/[xorg]/[...].ts',
122
+ './server.api.auth.logout.ts.eta':'server/api/auth/logout.ts',
123
+ './server.api.auth[...].ts.eta':'server/api/auth/[...].ts',
112
124
  './nuxt.config.ts.eta':'nuxt.config.ts',
113
125
  './pages.index.vue.eta':'pages/index.vue',
126
+ './pages.[xorg].index.vue.eta':'pages/[xorg]/index.vue',
127
+ './pages.login.vue.eta':'pages/login.vue',
114
128
  './plugins.simpleapp.ts.eta':'plugins/simpleapp.ts',
115
129
  './tailwind.config.ts.eta':'tailwind.config.ts',
116
- './tailwind.css.eta':'assets/css/tailwind.css',
130
+ './tailwind.css.eta':'assets/css/tailwind.css',
117
131
  './env.eta':'.env',
118
132
  }
119
133
 
@@ -143,7 +157,7 @@ export const prettyNuxt = ()=>{
143
157
 
144
158
  }
145
159
  export const prettyNest = ()=>{
146
- exec(`cd ${config.backendFolder};npx run format `)
160
+ exec(`cd ${config.backendFolder};npm run format`)
147
161
  }
148
162
 
149
163
  export const prepareOpenApiClient = () => {
package/src/generate.ts CHANGED
@@ -72,7 +72,7 @@ const generate = (
72
72
  frontendfolder:string
73
73
  ) => {
74
74
  const targetfolder = `${backendfolder}/src/docs/${doctype}`;
75
- const frontendpagefolder=`${frontendfolder}/pages`
75
+ const frontendpagefolder=`${frontendfolder}/pages/[xorg]`
76
76
  try {
77
77
 
78
78
  mkdirSync(targetfolder,{ recursive: true });
@@ -106,7 +106,8 @@ const generate = (
106
106
  bothEndCode: '',
107
107
  frontEndCode: '',
108
108
  backEndCode: '',
109
- controllerCode:''
109
+ controllerCode:'',
110
+ apiSchemaCode:'',
110
111
  };
111
112
 
112
113
  // console.log('generate 2', JSON.stringify(variables));
@@ -126,21 +127,33 @@ const generate = (
126
127
  writeFileSync(`${targetfolder}/${doctype}.jsonschema.ts`, txtJsonSchema);
127
128
 
128
129
  // generate before save source code, wont override after regenerate
129
- const customizefilename = `${targetfolder}/${doctype}.beforesave.ts`;
130
- if (!existsSync(customizefilename)) {
131
- const txtBeforeSave = eta.render('./beforesave', variables);
132
- writeFileSync(
133
- `${targetfolder}/${doctype}.beforesave.ts`,
134
- txtBeforeSave,
135
- );
136
- }
130
+ // const customizefilename = `${targetfolder}/${doctype}.beforesave.ts`;
131
+ // if (!existsSync(customizefilename)) {
132
+ // const txtBeforeSave = eta.render('./beforesave', variables);
133
+ // writeFileSync(
134
+ // `${targetfolder}/${doctype}.beforesave.ts`,
135
+ // txtBeforeSave,
136
+ // );
137
+ // }
137
138
  // write mongoose model file
138
139
  const txtModel = eta.render('./model', variables);
139
140
  writeFileSync(`${targetfolder}/${doctype}.model.ts`, txtModel);
140
141
 
141
142
  // prepare openapi schema
143
+ const apischemafile=`${targetfolder}/${doctype}.apischema.ts`
144
+ if (existsSync(apischemafile)) {
145
+ const apischemaCode = readFileSync(apischemafile).toString();
146
+ const regexapischema =
147
+ /\/\/<begin-apischema-code>([\s\S]*?)\/\/<end-apischema-code>/g;
148
+ const apischemaresult = apischemaCode.match(regexapischema);
149
+ if (apischemaresult) {
150
+ variables.apiSchemaCode = apischemaresult[0];
151
+ }else{
152
+ variables.apiSchemaCode="//<begin-apischema-code>\n//<end-apischema-code>";
153
+ }
154
+ }
142
155
  const txtApiSchema = eta.render('./apischema', variables);
143
- writeFileSync(`${targetfolder}/${doctype}.apischema.ts`, txtApiSchema);
156
+ writeFileSync(apischemafile, txtApiSchema);
144
157
 
145
158
  // prepare backend classes
146
159
  // prepare frontend api client
@@ -158,17 +171,22 @@ const generate = (
158
171
  /\/\/<begin-backend-code>([\s\S]*?)\/\/<end-backend-code>/g;
159
172
  const bothendresult = servicecodes.match(regex1);
160
173
  const backendresult = servicecodes.match(regex2);
174
+ console.log("bothendresult",bothendresult)
175
+ console.log("backendresult",backendresult)
161
176
  if (bothendresult) {
162
- bothEndCode = bothendresult[0];
177
+ variables.bothEndCode = bothendresult[0];
178
+ }else{
179
+ variables.bothEndCode="//<begin-bothend-code>\n//<end-bothend-code>";
163
180
  }
164
181
 
165
182
  if (backendresult) {
166
- backEndCode = backendresult[0];
183
+ variables.backEndCode = backendresult[0];
184
+ }else{
185
+ variables.backEndCode="//<begin-backend-code>\n//<end-backend-code>";
167
186
  }
168
187
  }
169
188
 
170
- variables.bothEndCode = bothEndCode ?? "//<begin-bothend-code>\n//<end-bothend-code>";
171
- variables.backEndCode = backEndCode ?? "//<begin-backend-code>\n//<end-backend-code>";
189
+
172
190
  const txtService = eta.render('./service', variables);
173
191
  writeFileSync(`${targetfolder}/${doctype}.service.ts`, txtService);
174
192
 
@@ -193,8 +211,8 @@ const generate = (
193
211
  writeFileSync(`${targetfolder}/${doctype}.module.ts`, txtModule);
194
212
 
195
213
  // prepare readme
196
- const txtReadme = eta.render('./readme', variables);
197
- writeFileSync(`${targetfolder}/README.md`, txtReadme);
214
+ // const txtReadme = eta.render('./readme', variables);
215
+ // writeFileSync(`${targetfolder}/README.md`, txtReadme);
198
216
 
199
217
  const frontendfile = `${frontendfolder}/simpleapp/simpleappdocs/${variables.typename}Doc.ts`;
200
218
  let frontEndCode = '';
@@ -249,12 +267,10 @@ const prepareEnvironments = (backendfolder:string,frontendfolder:string)=>{
249
267
  //do nothing
250
268
  }
251
269
 
252
- //copy over backend service class
253
-
254
270
  copyFileSync(`${constants.templatedir}/nest/SimpleAppService.eta`,`${targetfolder}/SimpleAppService.ts`)
255
-
256
- //copy over backend controller
257
271
  copyFileSync(`${constants.templatedir}/nest/SimpleAppController.eta`,`${targetfolder}/SimpleAppController.ts`)
272
+ copyFileSync(`${constants.templatedir}/nest/TenantMiddleware.eta`,`${targetfolder}/TenantMiddleware.ts`)
273
+ copyFileSync(`${constants.templatedir}/nest/User.eta`,`${targetfolder}/User.ts`)
258
274
 
259
275
  //copy over frontend apiabstract class
260
276
  // copyFileSync(`${constants.templatedir}/nuxt.apigateway.eta`,`${targetfrontendfolder}/[...].ts`)
package/src/index.ts CHANGED
@@ -27,7 +27,8 @@ program
27
27
 
28
28
  let path=''
29
29
  const options = program.opts();
30
- console.log(figlet.textSync(`SimpleApp Generator ${version}`));
30
+ console.log(figlet.textSync(`SimpleApp Generator`));
31
+ console.log(figlet.textSync(`${version}`));
31
32
  if(!options.configFile){
32
33
  log.error("Config file parameter is required. Example: simpleapp-generator -c ./config.json")
33
34
  throw "Undefine configuration file"
@@ -17,8 +17,8 @@ import {
17
17
  } from '../type';
18
18
  import { json } from 'stream/consumers';
19
19
  const log: Logger<ILogObj> = new Logger();
20
- const FIELD_AUTOCOMPLETE_CODE='field-autocomplete-code'
21
- const FIELD_AUTOCOMPLETE_NAME='field-autocomplete-name'
20
+ const X_DOCUMENT_NO='x-document-no'
21
+ const X_DOCUMENT_NAME='x-document-name'
22
22
  const FOREIGNKEY_PROPERTY='x-foreignkey'
23
23
  let allmodels: ChildModels = {};
24
24
  let fullschema={}
@@ -53,11 +53,11 @@ export const readJsonSchemaBuilder = async (
53
53
  throw(`unsupport array type for ${docname}.${doctype}`)
54
54
  }
55
55
  if(fieldAutoCompleteCode=='') {
56
- log.error(`you shall define 1 field with format:'${FIELD_AUTOCOMPLETE_CODE}'`)
56
+ log.error(`you shall define 1 field with format:'${X_DOCUMENT_NO}'`)
57
57
  throw "missing field format"
58
58
  }
59
59
  if(fieldAutoCompleteName=='') {
60
- log.error(`you shall define 1 field with format: '${FIELD_AUTOCOMPLETE_NAME}'}`)
60
+ log.error(`you shall define 1 field with format: '${X_DOCUMENT_NAME}'}`)
61
61
  throw "missing field format"
62
62
  }
63
63
 
@@ -75,9 +75,9 @@ const processObject = (doctype: string,
75
75
  //ensure some field exists, also override it
76
76
  jsondata.properties['_id'] = {type: 'string',description: 'Control value, dont edit it',};
77
77
  jsondata.properties['doctype'] = {type: 'string', default:doctype, examples: [doctype],description: 'Control value, dont edit it',};
78
- jsondata.properties['tenant_id'] = {type: 'number',description: 'Control value, dont edit it',};
79
- jsondata.properties['organization_id'] = {type: 'number',description: 'Control value, dont edit it',};
80
- jsondata.properties['branch_id'] = {type: 'number',description: 'Control value, dont edit it',};
78
+ jsondata.properties['tenantId'] = {type: 'number',description: 'Control value, dont edit it',};
79
+ jsondata.properties['orgId'] = {type: 'number',description: 'Control value, dont edit it',};
80
+ jsondata.properties['branchId'] = {type: 'number',description: 'Control value, dont edit it',};
81
81
  jsondata.properties['created'] = {type: 'string',description: 'Control value, dont edit it',};
82
82
  jsondata.properties['updated'] = {type: 'string',description: 'Control value, dont edit it',};
83
83
  jsondata.properties['createdby'] = {type: 'string',description: 'Control value, dont edit it',};
@@ -111,10 +111,10 @@ const genSchema = (
111
111
 
112
112
  const isrequired = requiredlist && requiredlist.includes(key);
113
113
  const newName: string = docname + capitalizeFirstLetter(key);
114
- if(obj.format && obj.format==FIELD_AUTOCOMPLETE_CODE){
114
+ if(obj.format && obj.format==X_DOCUMENT_NO){
115
115
  fieldAutoCompleteCode=key
116
116
  }
117
- if(obj.format && obj.format==FIELD_AUTOCOMPLETE_NAME){
117
+ if(obj.format && obj.format==X_DOCUMENT_NAME){
118
118
  fieldAutoCompleteName=key
119
119
  }
120
120
  // if (obj.type == 'object' && obj.items ){
package/src/type.ts CHANGED
@@ -61,4 +61,5 @@ bothEndCode: string
61
61
  frontEndCode: string
62
62
  backEndCode: string
63
63
  controllerCode:string
64
+ apiSchemaCode:string
64
65
  }
@@ -1,7 +1,9 @@
1
1
  /**
2
- * This file was automatically generated by simpleapp generator.
3
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4
- * and regenerate this file.
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR Except content between:
4
+ * <begin-apischema-code><end-apischema-code>
5
+ * last change 2023-09-09
6
+ * Author: Ks Tan
5
7
  */
6
8
  import { ApiProperty } from '@nestjs/swagger';
7
9
 
@@ -26,4 +28,6 @@ import { ApiProperty } from '@nestjs/swagger';
26
28
  }
27
29
  <%}) %>
28
30
 
29
-
31
+ /*****************************customized code begin here *****************************************/
32
+ <%~ it.apiSchemaCode %>
33
+
@@ -1,7 +1,9 @@
1
1
  /**
2
- * This file was automatically generated by simpleapp generator.
3
- * You can add your additional custom api in this file.
4
- * CODE GENERATOR WONT OVERRIDE THIS FILE
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR Except content between:
4
+ * <begin-controller-code><end-controller-code>
5
+ * last change 2023-09-09
6
+ * Author: Ks Tan
5
7
  */
6
8
  import {
7
9
  Controller,
@@ -39,7 +41,7 @@ export class <%= it.typename %>Controller extends SimpleAppController<
39
41
  type: [<%= it.fullApiSchemaName%>]
40
42
  })
41
43
  @ApiResponse({ status: 500, description: 'Internal error' })
42
- @ApiOperation({ operationId: 'runList' })
44
+ @ApiOperation({ operationId: 'runList', description:"List all data" })
43
45
  async list() {
44
46
  return this._list();
45
47
  }
@@ -51,7 +53,7 @@ export class <%= it.typename %>Controller extends SimpleAppController<
51
53
  type: ()=>[{id:'100',label:'label1'}],
52
54
  })
53
55
  @ApiResponse({ status: 500, description: 'Internal error' })
54
- @ApiOperation({ operationId: 'autoComplete' })
56
+ @ApiOperation({ operationId: 'autoComplete',description:"retrieve array of {_id, code, name}" })
55
57
  async autoComplete(@Query('keyword') keyword: string) {
56
58
  return this._autocomplete(keyword);
57
59
  }
@@ -86,6 +88,20 @@ export class <%= it.typename %>Controller extends SimpleAppController<
86
88
  return await this._create(data)
87
89
  }
88
90
 
91
+ @Post('/search')
92
+ @ApiResponse({
93
+ status: 201,
94
+ description: 'success',
95
+ type: [<%= it.fullApiSchemaName%>]
96
+ })
97
+ @ApiResponse({ status: 400, description: 'bad request' })
98
+ @ApiResponse({ status: 500, description: 'internal error' })
99
+ @ApiBody({ description: 'Data', type: Object })
100
+ @ApiOperation({ operationId: 'runSearch' })
101
+ async search(@Body() data: Object) {
102
+ return await this._search(data)
103
+ }
104
+
89
105
  @Put(':id')
90
106
  @ApiResponse({
91
107
  status: 200,
@@ -2,5 +2,7 @@
2
2
  * This file was automatically generated by simpleapp generator.
3
3
  * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4
4
  * and regenerate this file.
5
+ * last change 2023-09-09
6
+ * Author: Ks Tan
5
7
  */
6
8
  export const <%= it.typename%>JsonSchema = <%~ JSON.stringify(it.jsonschema) %>
@@ -2,16 +2,14 @@
2
2
  * This file was automatically generated by simpleapp generator.
3
3
  * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4
4
  * and regenerate this file.
5
- * ALL FIELDS not compulsory, it control at microservice level using AJV
5
+ * last change 2023-09-09
6
+ * Author: Ks Tan
6
7
  */
7
8
 
8
9
  <% const schema = it.schema %>
9
10
  <% const typeclass = it.doctype+'type' %>
10
11
  import { Schema } from 'mongoose';
11
12
  import { <%Object.keys(it.models).forEach(function(key) { %> <%=key %>, <%})%> } from './<%= it.doctype %>.type';
12
- import { beforeSave } from './<%= it.doctype %>.beforesave';
13
-
14
-
15
13
  const schemasetting = {
16
14
 
17
15
  <%Object.keys(it.schema).forEach(function(key) { %>
@@ -25,11 +23,10 @@ const schemasetting = {
25
23
  <% }else if( schema[key].type == 'array'){%>
26
24
  <%= key %>: [{type: <%= schema[key].item.type %>, required:false}] //basic array
27
25
  <% }else{%>
28
- <%= key %>: {type: <%= capitalizeFirstLetter(schema[key].type) %>, required:false}, //field
26
+ <%= key %>: {type: <%= capitalizeFirstLetter(schema[key].type) %>, required: <% if(key==it.autocompletecode || key==it.autocompletename){%>true<%}else{%>false<%}%>}, //field
29
27
  <% } %>
30
28
  <%}) %>
31
29
  };
32
30
 
33
31
  export const <%= it.doctype %>MongoSchema = new Schema(schemasetting,{collection: '<%= it.name %>'})
34
- .post('validate', (doc: <%= it.typename %>) => beforeSave(doc))
35
- .pre('save', () => {});
32
+ .index({<%=it.autocompletecode%>:1,orgId:1},{unique:true});
@@ -2,6 +2,8 @@
2
2
  * This file was automatically generated by simpleapp generator.
3
3
  * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4
4
  * and regenerate this file.
5
+ * last change 2023-09-09
6
+ * Author: Ks Tan
5
7
  */
6
8
  import { Module } from '@nestjs/common';
7
9
  import { <%= it.typename %>Controller } from './<%= it.doctype %>.controller';
@@ -1,7 +1,32 @@
1
+ <script setup lang="ts">
2
+ /**
3
+ * This file was automatically generated by simpleapp everytime regenerate code.
4
+ * delete file "delete-me-for-avoid-override" if you want to modify this file and
5
+ * prevent regenerate code override it.
6
+ * last change 2023-09-09
7
+ * author: Ks Tan
8
+ */
9
+ <% let skipcolumns = ['_id','createdby','created','updatedby','updated','orgId','branchId','tenantId','doctype'] %>
10
+
11
+ import { <%= it.typename %>Doc } from "../../../simpleapp/simpleappdocs/<%= it.typename %>Doc";
12
+ const { $event, $listen } = useNuxtApp();
13
+ const route = useRoute()
14
+ const doc = new <%= it.typename %>Doc(route.params.xorg,$event, $listen);
15
+ const documentpath = `/${route.params.xorg}/<%= it.name %>`;
16
+ const data = doc.getReactiveData();
17
+ const columns = [
18
+ <%Object.keys(it.jsonschema.properties).forEach(function(key) { %>
19
+ <%let obj=it.jsonschema.properties[key] %>
20
+ <%if(skipcolumns.indexOf(key)>=0){%>/* skip system columns <%=key%>*/
21
+ <%} else if(['string','number','integer'].indexOf(obj.type)>=0){%>'<%=key%>',<%}%>
22
+ <%})%>
23
+ ]
24
+ </script>
1
25
  <template>
2
- <% let skipcolumns = ['_id','createdby','created','updatedby','updated','organization_id','branch_id','tenant_id','doctype'] %>
3
26
  <div>
4
- <CrudSimple :document="doc" title="<%= it.typename %>" #default="o"
27
+ <CrudSimple :document="doc" title="<%= it.typename %>"
28
+ #default="o"
29
+ :path="documentpath"
5
30
  :listColumns="columns">
6
31
 
7
32
  <%Object.keys(it.jsonschema.properties).forEach(function(key) { %>
@@ -38,17 +63,5 @@
38
63
  </CrudSimple>
39
64
  </div>
40
65
  </template>
41
- <script setup lang="ts">
42
- import { <%= it.typename %>Doc } from "../../simpleapp/simpleappdocs/<%= it.typename %>Doc";
43
- const { $event, $listen } = useNuxtApp();
44
- const doc = new <%= it.typename %>Doc($event, $listen);
45
- const data = doc.getReactiveData();
46
- const columns = [
47
- <%Object.keys(it.jsonschema.properties).forEach(function(key) { %>
48
- <%let obj=it.jsonschema.properties[key] %>
49
- <%if(skipcolumns.indexOf(key)>=0){%>/* skip system columns <%=key%>*/
50
- <%} else if(['string','number','integer'].indexOf(obj.type)>=0){%>'<%=key%>',<%}%>
51
- <%})%>
52
- ]
53
- </script>
66
+
54
67
 
@@ -1 +1,13 @@
1
- <template></template>
1
+ <script setup lang="ts">
2
+ /**
3
+ * This file was automatically generated by simpleapp everytime regenerate code.
4
+ * delete file "delete-me-for-avoid-override" if you want to modify this file and
5
+ * prevent regenerate code override it.
6
+ * last change 2023-09-09
7
+ * author: Ks Tan
8
+ */
9
+ import Index from './index.vue'
10
+ </script>
11
+ <template>
12
+ <Index/>
13
+ </template>
@@ -1,13 +1,16 @@
1
1
  /**
2
- * This file was automatically generated by simpleapp generator.
3
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4
- * and regenerate this file.
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR Except content between:
4
+ * <begin-bothend-code><end-bothend-code>
5
+ * <begin-backend-code><end-backend-code>
6
+ * last change 2023-09-09
7
+ * Author: Ks Tan
5
8
  */
6
9
  import { Injectable } from '@nestjs/common';
7
10
  import { InjectModel } from '@nestjs/mongoose';
8
11
  import { Model } from 'mongoose';
9
12
  import {<%= it.typename%>JsonSchema } from './<%= it.doctype %>.jsonschema'
10
- import { SimpleAppService } from '../../class/SimpleAppService';
13
+ import { SimpleAppService,IsolationType } from '../../class/SimpleAppService';
11
14
  import { <%Object.keys(it.models).forEach(function(key) { %> <%=key %>, <%})%> } from './<%= it.doctype %>.type';
12
15
 
13
16
 
@@ -17,18 +20,17 @@ export class <%= it.typename %>Service extends SimpleAppService<<%= it.typename
17
20
  protected documentIdentityName='<%~ it.autocompletename %>'
18
21
  constructor(@InjectModel('<%= it.name %>') mydoc: Model<<%= it.typename %>>,
19
22
  ) {
20
- super(mydoc);
23
+ super(mydoc,IsolationType.org);
21
24
  this.setSchema(<%= it.typename%>JsonSchema)
22
25
  }
23
26
 
24
27
 
25
28
  /*****************************customized frontend + backend code*****************************************/
26
-
27
-
29
+
28
30
  <%~ it.bothEndCode %>
29
31
 
30
32
  /*****************************customized backend only code*****************************************/
31
-
32
- <%~ it.backEndCode %>
33
+
34
+ <%~ it.backEndCode %>
33
35
 
34
36
  }
@@ -1,7 +1,9 @@
1
1
  /**
2
- * This file was automatically generated by simpleapp generator.
3
- * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4
- * and regenerate this file.
2
+ * This file was automatically generated by simpleapp generator. Every
3
+ * MODIFICATION OVERRIDE BY GENERATEOR Except content between:
4
+ * <begin-frontend-code><end-frontend-code>
5
+ * last change 2023-09-09
6
+ * Author: Ks Tan
5
7
  */
6
8
  import { SimpleAppClient } from "@simitgroup/simpleapp-vue-component/src/SimpleAppClient";
7
9
 
@@ -21,8 +23,8 @@ export class <%= it.typename%>Doc extends SimpleAppClient<<%= it.typename%>,<%=
21
23
  public readonly schema= <%~ JSON.stringify(it.jsonschema) %>;
22
24
  protected documentIdentityCode='<%~ it.autocompletecode %>'
23
25
  protected documentIdentityName='<%~ it.autocompletename %>'
24
- constructor(event:any,listen?:any) {
25
- const apiconfig = new Configuration({ basePath: useRuntimeConfig().public.APP_URL+'/api' });
26
+ constructor(xorg:string,event:any,listen?:any) {
27
+ const apiconfig = new Configuration({ basePath: `${useRuntimeConfig().public.APP_URL}/api/${xorg}` });
26
28
  const apiobj = new <%= it.doctype.toUpperCase()%>Api(apiconfig)
27
29
  super(apiobj,'<%= it.doctype %>','<%=it.name %>')
28
30
  this.event=event
@@ -56,11 +58,10 @@ export class <%= it.typename%>Doc extends SimpleAppClient<<%= it.typename%>,<%=
56
58
  }
57
59
 
58
60
  /*****************************customized frontend + backend code*****************************************/
59
-
60
-
61
+
61
62
  <%~ it.bothEndCode %>
62
63
 
63
64
  /*****************************customized frontend only code*****************************************/
64
-
65
65
  <%~ it.frontEndCode %>
66
+
66
67
  }
@@ -2,9 +2,10 @@
2
2
  * This file was automatically generated by simpleapp generator.
3
3
  * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
4
4
  * and regenerate this file.
5
+ * last change 2023-09-09
6
+ * Author: Ks Tan
5
7
  */
6
8
 
7
-
8
9
  <%Object.keys(it.models).forEach(function(prop){ %>
9
10
  <% let schema = it.models[prop] %>
10
11
  export type <%= prop %> = {