@simitgroup/simpleapp-generator 1.0.31 → 1.0.32

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.
@@ -13,32 +13,64 @@ import {
13
13
  ChildModels,
14
14
  SchemaModel,
15
15
  TypeForeignKey,
16
- TypeForeignKeyCatalogue
16
+ TypeForeignKeyCatalogue,
17
+ DocSetting,ApiSetting,DocStatusSetting,
18
+
17
19
  } from '../type';
18
20
  import { json } from 'stream/consumers';
19
21
  const log: Logger<ILogObj> = new Logger();
22
+
20
23
  const X_DOCUMENT_NO='x-document-no'
21
- const X_DOCUMENT_NAME='x-document-name'
24
+ const X_DOCUMENT_LABEL='x-document-label'
22
25
  const X_AUTOCOMPLETE_FIELD='x-autocomplete-field'
26
+ const X_DOCUMENT_NAME='x-document-name'
27
+ const X_DOCUMENT_TYPE='x-document-type'
28
+ const X_COLLECTION_NAME='x-document-collection'
29
+ const X_DOCUMENT_STATUS='x-document-status'
30
+ const X_DOCUMENT_API='x-document-api'
31
+ const X_IGNORE_AUTOCOMPLETE='x-ignore-autocomplete'
23
32
  const FOREIGNKEY_PROPERTY='x-foreignkey'
24
-
25
33
  const X_TEL_NO='x-tel'
34
+ const X_ISOLATION_TYPE='x-isolation-type'
35
+
36
+ let docSetting:DocSetting={} as DocSetting
37
+
38
+
39
+
26
40
  let allmodels: ChildModels = {};
27
41
  let fullschema={}
28
- let fieldAutoCompleteCode=''
29
- let fieldAutoCompleteName=''
42
+ // let fieldAutoCompleteCode=''
43
+ // let fieldAutoCompleteName=''
30
44
  let moreAutoComplete:string[]=[]
45
+
46
+
47
+ const newDocSetting=(doctype:string,docname:string):DocSetting=>{
48
+ return {
49
+ docName:docname, //done
50
+ docType:doctype, //done
51
+ colDocNo:'', //done
52
+ colDocLabel:'', //done
53
+ collectionName:docname, //done
54
+ autocompleteFields:[],
55
+ docStatusSettings:[],
56
+ apiSettings:[],
57
+ requireautocomplete:true,
58
+ isolationtype:"org"
59
+
60
+ }
61
+ }
31
62
  export const readJsonSchemaBuilder = async (
32
63
  doctype: string,
33
64
  docname: string,
34
65
  orijsondata:JSONSchema7,
35
66
  allforeignkeys:TypeForeignKeyCatalogue
36
67
  ) => {
37
-
38
- fieldAutoCompleteCode=''
39
- fieldAutoCompleteName=''
68
+ docSetting=newDocSetting(doctype,docname)
69
+ // fieldAutoCompleteCode=''
70
+ // fieldAutoCompleteName=''
40
71
  moreAutoComplete=[]
41
72
  allmodels = {};
73
+
42
74
  const validateddata: JSONSchema7 = { ...orijsondata };
43
75
  let schema: SchemaModel | SchemaModel[];
44
76
  const tmpjsondata = await $RefParser.dereference(orijsondata).then((schema)=>{
@@ -56,12 +88,12 @@ export const readJsonSchemaBuilder = async (
56
88
  } else if (jsondata.type == 'array') {
57
89
  throw(`unsupport array type for ${docname}.${doctype}`)
58
90
  }
59
- if(fieldAutoCompleteCode=='') {
91
+ if(docSetting.colDocNo=='' && docSetting.requireautocomplete) {
60
92
  log.error(`you shall define 1 field with format:'${X_DOCUMENT_NO}'`)
61
93
  throw "missing field format"
62
94
  }
63
- if(fieldAutoCompleteName=='') {
64
- log.error(`you shall define 1 field with format: '${X_DOCUMENT_NAME}'}`)
95
+ if(docSetting.colDocLabel=='' && docSetting.requireautocomplete) {
96
+ log.error(`you shall define 1 field with format: '${X_DOCUMENT_LABEL}'}`)
65
97
  throw "missing field format"
66
98
  }
67
99
 
@@ -86,6 +118,50 @@ const processObject = (doctype: string,
86
118
  jsondata.properties['updated'] = {type: 'string',description: 'Control value, dont edit it',};
87
119
  jsondata.properties['createdby'] = {type: 'string',description: 'Control value, dont edit it',};
88
120
  jsondata.properties['updatedby'] = {type: 'string',description: 'Control value, dont edit it',};
121
+
122
+ if(jsondata[X_ISOLATION_TYPE] && ['none','tenant','org','branch'].includes(jsondata[X_ISOLATION_TYPE]) ){
123
+ docSetting.isolationtype=jsondata[X_ISOLATION_TYPE]
124
+ }
125
+ if(jsondata[X_IGNORE_AUTOCOMPLETE] && jsondata[X_IGNORE_AUTOCOMPLETE]==true){
126
+ docSetting.requireautocomplete=false
127
+ }
128
+ if(jsondata[X_DOCUMENT_API] && Array.isArray(jsondata[X_DOCUMENT_API])){
129
+ log.warn("x-document-api exists:")
130
+ log.warn(jsondata[X_DOCUMENT_API])
131
+ for(let i=0; i<jsondata[X_DOCUMENT_API].length;i++){
132
+ const tmp:ApiSetting =jsondata[X_DOCUMENT_API][i]
133
+ if(!tmp.action){
134
+ const errmsg = "x-document-api defined but undefine property 'action'"
135
+ log.error(errmsg)
136
+
137
+ throw errmsg
138
+ }
139
+ if(!tmp.method){
140
+ const errmsg = "x-document-api defined but undefine property 'method'"
141
+ log.error(errmsg)
142
+ throw errmsg
143
+ }
144
+ docSetting.apiSettings.push(tmp)
145
+ }
146
+ }
147
+ if(jsondata[X_DOCUMENT_STATUS] && Array.isArray(jsondata[X_DOCUMENT_STATUS])){
148
+ for(let i=0; i<jsondata[X_DOCUMENT_STATUS].length;i++){
149
+ const tmp:DocStatusSetting =jsondata[X_DOCUMENT_STATUS][i]
150
+ if(tmp.statusCode ===undefined){
151
+ const errmsg = "x-document-status defined but undefine property 'statusCode'"
152
+ log.error(errmsg)
153
+ throw errmsg
154
+ }
155
+ if(!tmp.statusName ===undefined){
156
+ const errmsg = "x-document-status defined but undefine property 'statusName'"
157
+ log.error(errmsg)
158
+ throw errmsg
159
+ }
160
+ docSetting.docStatusSettings.push(tmp)
161
+ }
162
+ }
163
+
164
+
89
165
  return genSchema(
90
166
  capitalizeFirstLetter(docname),
91
167
  'object',
@@ -94,12 +170,8 @@ const processObject = (doctype: string,
94
170
  );
95
171
  }
96
172
 
97
- const genSchema = (
98
- docname: string,
99
- schematype: string,
100
- jsondata: JsonSchemaProperties,//JSONSchema7,//|JsonSchemaProperties|JSONSchema7Definition,
101
- requiredlist: string[] | undefined,
102
- ): SchemaModel => {
173
+ const genSchema = (docname: string,schematype: string,jsondata: JsonSchemaProperties,
174
+ requiredlist: string[] | undefined): SchemaModel => {
103
175
  const newmodel: SchemaModel = {};
104
176
  const props = Object.getOwnPropertyNames(jsondata ??{});
105
177
  // console.log('==== jsondata', jsondata);
@@ -116,18 +188,25 @@ const genSchema = (
116
188
  const isrequired = requiredlist && requiredlist.includes(key);
117
189
  const newName: string = docname + capitalizeFirstLetter(key);
118
190
  if(obj.format && obj.format==X_DOCUMENT_NO){
119
- fieldAutoCompleteCode=key
191
+ docSetting.colDocNo=key
120
192
  obj.minLength=obj.minLength??1
121
193
  jsondata[key]['minLength']=obj.minLength
122
194
  }
123
- if(obj.format && obj.format==X_DOCUMENT_NAME){
124
- fieldAutoCompleteName=key
195
+ if(obj.format && obj.format==X_DOCUMENT_LABEL){
196
+ docSetting.colDocLabel=key
125
197
  obj.minLength=obj.minLength??1
126
198
  jsondata[key]['minLength']=obj.minLength
127
199
  }
200
+
201
+ if(obj[X_COLLECTION_NAME]){
202
+ docSetting.collectionName=key
203
+ }
204
+
205
+
128
206
  if(obj[X_AUTOCOMPLETE_FIELD]){
129
- moreAutoComplete.push(key)
207
+ docSetting.autocompleteFields.push(key)
130
208
  }
209
+
131
210
 
132
211
  // if(obj.format && obj.format==X_TEL_NO){
133
212
  // obj.pattern=obj.pattern ?? '/^\d{7,15}$/gm'
@@ -177,7 +256,18 @@ const genSchema = (
177
256
  // console.log(key,'--------newmodel',obj, newmodel[key]);
178
257
  }
179
258
  }
180
- allmodels[docname] = { type: schematype, model: newmodel,codeField: fieldAutoCompleteCode ,nameField: fieldAutoCompleteName,moreAutoComplete:moreAutoComplete };
259
+ allmodels[docname] = {
260
+ type: schematype,
261
+ model: newmodel,
262
+ codeField: docSetting.colDocNo ,
263
+ nameField: docSetting.colDocLabel,
264
+ moreAutoComplete:docSetting.autocompleteFields,
265
+ docStatusSettings:docSetting.docStatusSettings,
266
+ apiSettings:docSetting.apiSettings,
267
+ requireautocomplete:docSetting.requireautocomplete,
268
+ isolationtype:docSetting.isolationtype
269
+ };
270
+ // console.warn(docname,docSetting.isolationtype)
181
271
  return newmodel;
182
272
  };
183
273
 
@@ -216,3 +306,4 @@ const getField = (
216
306
  }
217
307
  return f;
218
308
  };
309
+
package/src/type.ts CHANGED
@@ -1,6 +1,16 @@
1
1
  import { JSONSchema7, JSONSchema7Definition } from 'json-schema';
2
2
  export type ChildModels = {
3
- [key: string]: { type: string; model: SchemaModel,codeField:string,nameField:string,moreAutoComplete:string[] };
3
+ [key: string]: {
4
+ type: string;
5
+ model: SchemaModel,
6
+ codeField:string,
7
+ nameField:string,
8
+ moreAutoComplete:string[],
9
+ docStatusSettings:DocStatusSetting[],
10
+ apiSettings:ApiSetting[],
11
+ requireautocomplete: boolean
12
+ isolationtype:string
13
+ };
4
14
  };
5
15
  export enum Fieldtypes {
6
16
  'string' = 'string',
@@ -63,4 +73,37 @@ frontEndCode: string
63
73
  backEndCode: string
64
74
  controllerCode:string
65
75
  apiSchemaCode:string
76
+ docStatusSettings:DocStatusSetting[],
77
+ apiSettings:ApiSetting[],
78
+ requireautocomplete:boolean,
79
+ isolationtype:string
80
+ }
81
+
82
+ export type DocStatusSetting = {
83
+ statusCode:string,
84
+ statusName:string,
85
+ allowApi:string[],
86
+ readonly?:boolean,
87
+ description?:''
88
+ }
89
+
90
+ export type ApiSetting = {
91
+ method:string,
92
+ action:string,
93
+ setDocStatus?:'',
94
+ description?:'',
95
+ bpmnApi?:'',
96
+ data?:any
97
+ }
98
+ export type DocSetting = {
99
+ docName:string,
100
+ docType:string,
101
+ colDocNo:string,
102
+ colDocLabel:string,
103
+ collectionName:string,
104
+ autocompleteFields:string[],
105
+ docStatusSettings:DocStatusSetting[],
106
+ apiSettings:ApiSetting[],
107
+ requireautocomplete:boolean
108
+ isolationtype:string
66
109
  }
@@ -2,7 +2,7 @@
2
2
  * This file was automatically generated by simpleapp generator. Every
3
3
  * MODIFICATION OVERRIDE BY GENERATEOR Except content between:
4
4
  * <begin-controller-code><end-controller-code>
5
- * last change 2023-09-09
5
+ * last change 2023-09-18
6
6
  * Author: Ks Tan
7
7
  */
8
8
  import {
@@ -59,20 +59,6 @@ export class <%= it.typename %>Controller extends SimpleAppController<
59
59
  }
60
60
 
61
61
 
62
- @Get(':id')
63
- @ApiResponse({
64
- status: 200,
65
- description: 'Founds',
66
- type: <%= it.fullApiSchemaName%>
67
- })
68
- @ApiResponse({ status: 404, description: 'Document not found' })
69
- @ApiResponse({ status: 500, description: 'Internal error' })
70
- @ApiOperation({ operationId: 'runFindOne' })
71
- async findOne(@Param('id') id: string) {
72
- return await this._findOne(id);
73
- }
74
-
75
-
76
62
 
77
63
  @Post()
78
64
  @ApiResponse({
@@ -102,6 +88,38 @@ export class <%= it.typename %>Controller extends SimpleAppController<
102
88
  return await this._search(data)
103
89
  }
104
90
 
91
+
92
+ /***************************** x-document-api definations *****************************************/
93
+
94
+ <% for(let i=0;i<it.apiSettings.length;i++){%>
95
+ <% let api = it.apiSettings[i] %>
96
+ <%~ `@${capitalizeFirstLetter(api.method)}(':id/${api.action}')`%>
97
+ @ApiResponse({status: 200,description: '<%=api.description%>'})
98
+ @ApiOperation({ operationId: 'exec<%=capitalizeFirstLetter(api.action)%>' })
99
+ async exec<%=capitalizeFirstLetter(api.action)%>(@Param('id') id: string){
100
+ return await this.service.exec<%=capitalizeFirstLetter(api.action)%>(id)
101
+ }
102
+ <%}%>
103
+
104
+ /*****************************customized code begin here *****************************************/
105
+ <%~ it.controllerCode %>
106
+
107
+ /*****************************customized code end here *****************************************/
108
+
109
+ @Get(':id')
110
+ @ApiResponse({
111
+ status: 200,
112
+ description: 'Founds',
113
+ type: <%= it.fullApiSchemaName%>
114
+ })
115
+ @ApiResponse({ status: 404, description: 'Document not found' })
116
+ @ApiResponse({ status: 500, description: 'Internal error' })
117
+ @ApiOperation({ operationId: 'runFindOne' })
118
+ async findOne(@Param('id') id: string) {
119
+ return await this._findOne(id);
120
+ }
121
+
122
+
105
123
  @Put(':id')
106
124
  @ApiResponse({
107
125
  status: 200,
@@ -129,7 +147,6 @@ export class <%= it.typename %>Controller extends SimpleAppController<
129
147
  }
130
148
 
131
149
 
132
- /*****************************customized code begin here *****************************************/
133
- <%~ it.controllerCode %>
150
+
134
151
 
135
152
  }
@@ -29,6 +29,7 @@ const schemasetting = {
29
29
  };
30
30
 
31
31
  export const <%= it.doctype %>MongoSchema = new Schema(schemasetting,{collection: '<%= it.name %>'})
32
+ <%if(it.requireautocomplete){%>
32
33
  .index({<%=it.autocompletecode%>:1,orgId:1},{unique:true})
33
34
  .index({<%=it.autocompletename%>:1,orgId:1});
34
-
35
+ <%}%>
@@ -55,7 +55,7 @@
55
55
  <% } else if(obj.type=='array' && obj.items && obj.items.type =='string' ){ %>
56
56
  <SimpleAppChip autofocus :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
57
57
  <% } else if(obj.type=='object' && typeof obj['x-foreignkey']!='undefined'){ %>
58
- <SimpleAppAutocomplete :getAutocomplete="getAutocomplete" :setting="o.getField('#/properties/<%= key %>')"
58
+ <SimpleAppAutocomplete :setting="o.getField('#/properties/<%= key %>')"
59
59
  v-model="data.<%= key %>" optionLabel="label" :remote-src="getAutocomplete('<%=obj['x-foreignkey']%>')"/>
60
60
  <% } else if(obj.type=='string'){ %>
61
61
  <% if(obj.format=='date'){ %>
@@ -6,6 +6,7 @@
6
6
  * last change 2023-09-09
7
7
  * Author: Ks Tan
8
8
  */
9
+ import { UserProvider } from '../../class/UserProvider'
9
10
  import { Injectable } from '@nestjs/common';
10
11
  import { InjectModel } from '@nestjs/mongoose';
11
12
  import { Model } from 'mongoose';
@@ -20,7 +21,7 @@ export class <%= it.typename %>Service extends SimpleAppService<<%= it.typename
20
21
  protected documentIdentityName='<%~ it.autocompletename %>'
21
22
  constructor(@InjectModel('<%= it.name %>') mydoc: Model<<%= it.typename %>>,
22
23
  ) {
23
- super('<%= it.doctype %>','<%= it.name %>',mydoc,IsolationType.org);
24
+ super('<%= it.doctype %>','<%= it.name %>',mydoc,IsolationType.<%=it.isolationtype%>);
24
25
  this.setSchema(<%= it.typename%>JsonSchema)
25
26
 
26
27
  <%if(it.moreAutoComplete.length>0){%>
@@ -34,7 +35,22 @@ export class <%= it.typename %>Service extends SimpleAppService<<%= it.typename
34
35
 
35
36
  }
36
37
 
37
-
38
+ /***************************** x-document-api definations *****************************************/
39
+
40
+ <%for(let i=0;i<it.apiSettings.length;i++){%>
41
+ <% let api = it.apiSettings[i] %>
42
+ async exec<%=capitalizeFirstLetter(api.action)%>(id:string){
43
+ <%if(api.bpmn!==undefined){%>
44
+ return await this.executeWorkFlow(id,"<%=api.bpmn%>","<%=api.setDocumentStatus%>")
45
+ <%}else if (api.setDocumentStatus !== undefined){%>
46
+ return await this.setDocumentStatus(id,'<%=api.setDocumentStatus%>')
47
+ <%}else {%>
48
+ return Promise.resolve("unknown action")
49
+ <%}%>
50
+
51
+ }
52
+ <%}%>
53
+
38
54
  /*****************************customized frontend + backend code*****************************************/
39
55
 
40
56
  <%~ it.bothEndCode %>
@@ -6,6 +6,7 @@
6
6
  * Author: Ks Tan
7
7
  */
8
8
  import { SimpleAppClient } from "@simitgroup/simpleapp-vue-component/src/SimpleAppClient";
9
+ import {AxiosResponse} from 'axios'
9
10
 
10
11
  // import { JSONSchema7 } from 'json-schema';
11
12
  import { Configuration,
@@ -26,6 +27,9 @@ export class <%= it.typename%>Doc extends SimpleAppClient<<%= it.typename%>,<%=
26
27
  protected documentIdentityCode='<%~ it.autocompletecode %>'
27
28
  protected documentIdentityName='<%~ it.autocompletename %>'
28
29
  constructor(xorg:string,event:any,listen?:any) {
30
+ if(!xorg){
31
+ xorg='MC0wLTA' //0-0-0
32
+ }
29
33
  const apiconfig = new Configuration({ basePath: `${useRuntimeConfig().public.APP_URL}/api/${xorg}` });
30
34
  const apiobj = new <%= it.doctype.toUpperCase()%>Api(apiconfig)
31
35
  super(apiobj,'<%= it.doctype %>','<%=it.name %>')
@@ -91,6 +95,21 @@ export class <%= it.typename%>Doc extends SimpleAppClient<<%= it.typename%>,<%=
91
95
  <%})%>
92
96
 
93
97
 
98
+ <%for(let i=0;i<it.apiSettings.length;i++){%>
99
+ <% let api = it.apiSettings[i] %>
100
+ async exec<%=capitalizeFirstLetter(api.action)%>(){
101
+ const recordid: string = this.data.value._id ?? '';
102
+ return await this.docapi.exec<%=capitalizeFirstLetter(api.action)%>(recordid)
103
+ .then((res: AxiosResponse) => {
104
+ if(this.event){this.event('info:<%=capitalizeFirstLetter(api.action)%>',res.data)}
105
+ return res;
106
+ }).catch((res:any)=>{
107
+ if(this.event){this.event('error:<%=capitalizeFirstLetter(api.action)%>',res)}
108
+ return Promise.reject(res)
109
+ });
110
+ }
111
+ <%}%>
112
+
94
113
  /*****************************customized frontend + backend code*****************************************/
95
114
 
96
115
  <%~ it.bothEndCode %>