mushroom-cli 1.2.0-alpha.18 → 1.2.0-alpha.19
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.
- package/README.md +8 -0
- package/dist/gen/gen-ts-driver.js +147 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,14 @@ npx mushroom-cli parameters --no-check-update
|
|
|
132
132
|
|
|
133
133
|
## Version
|
|
134
134
|
|
|
135
|
+
### 1.2.0-alpha.19
|
|
136
|
+
|
|
137
|
+
Improvement:
|
|
138
|
+
|
|
139
|
+
- gen-ts:
|
|
140
|
+
- generate type for custom methods of action
|
|
141
|
+
- generate description for fields, entities
|
|
142
|
+
|
|
135
143
|
### 1.2.0-alpha.17
|
|
136
144
|
|
|
137
145
|
Improvement:
|
|
@@ -38,9 +38,6 @@ function getCSharpTypeFromMushroomType(type) {
|
|
|
38
38
|
switch (type) {
|
|
39
39
|
case 'string':
|
|
40
40
|
return 'string';
|
|
41
|
-
case 'object':
|
|
42
|
-
case 'array':
|
|
43
|
-
return '';
|
|
44
41
|
case 'boolean':
|
|
45
42
|
return 'boolean';
|
|
46
43
|
case 'integer':
|
|
@@ -52,32 +49,73 @@ function getCSharpTypeFromMushroomType(type) {
|
|
|
52
49
|
case 'IdRef':
|
|
53
50
|
case 'AutoId':
|
|
54
51
|
return 'IdValue';
|
|
52
|
+
default:
|
|
53
|
+
return 'any';
|
|
55
54
|
}
|
|
56
|
-
return 'UNKNOWN_TYPE_' + type;
|
|
57
55
|
}
|
|
58
56
|
function generateTypescriptClass(objectDefination, className, options) {
|
|
59
57
|
let childrenCode = '';
|
|
60
58
|
let code = `export interface ${className} {\n`;
|
|
61
59
|
for (const fieldName in objectDefination) {
|
|
62
|
-
const
|
|
60
|
+
const field = objectDefination[fieldName];
|
|
61
|
+
if (!field)
|
|
62
|
+
continue;
|
|
63
|
+
if (field.description) {
|
|
64
|
+
code += ` /**\n * ${field.description.replace(/\r/, '').split('\n').map(line => line.includes('*/') ? line.replace(/\*\//g, "* /") : line).join('\n * ')}\n */\n`;
|
|
65
|
+
}
|
|
66
|
+
const optionalMark = options?.checkRequired && (field.required || field.validation?.required) ? '' : '?';
|
|
63
67
|
const nullType = optionalMark ? ' | null' : '';
|
|
64
|
-
if (
|
|
68
|
+
if (field.type == 'object') {
|
|
65
69
|
const fieldClassName = className + '_' + toTypeScriptClassName(fieldName);
|
|
66
70
|
code += ` ${fieldName}${optionalMark}: ${fieldClassName}${nullType};\n`;
|
|
67
|
-
childrenCode += generateTypescriptClass(
|
|
71
|
+
childrenCode += generateTypescriptClass(field.fields ?? {}, fieldClassName, options);
|
|
68
72
|
}
|
|
69
|
-
else if (
|
|
70
|
-
|
|
73
|
+
else if (field.type == 'keyValue') {
|
|
74
|
+
const valueNullType = options?.checkRequired && (field.values.required || field.values.validation?.required) ? '' : ' | null | undefined';
|
|
75
|
+
if (field.values?.type == 'object') {
|
|
71
76
|
const fieldClassName = className + '_' + toTypeScriptClassName(fieldName);
|
|
72
|
-
code += ` ${fieldName}${optionalMark}: ${fieldClassName}
|
|
73
|
-
childrenCode += generateTypescriptClass(
|
|
77
|
+
code += ` ${fieldName}${optionalMark}: Record<string, ${fieldClassName}${valueNullType}>${nullType};\n`;
|
|
78
|
+
childrenCode += generateTypescriptClass(field.values.fields ?? {}, fieldClassName, options);
|
|
79
|
+
}
|
|
80
|
+
else if (field.values?.type == 'array') {
|
|
81
|
+
const itemNullType = options?.checkRequired && (field.values.items?.required || field.values.items?.validation?.required) ? '' : ' | null | undefined';
|
|
82
|
+
if (field.values.items?.type == 'object') {
|
|
83
|
+
const fieldClassName = className + '_' + toTypeScriptClassName(fieldName);
|
|
84
|
+
code += ` ${fieldName}${optionalMark}: Record<string, Array<${fieldClassName}${itemNullType}>${valueNullType}>${nullType};\n`;
|
|
85
|
+
childrenCode += generateTypescriptClass(field.values.items.fields ?? {}, fieldClassName, options);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
code += ` ${fieldName}${optionalMark}: Record<string, Array<${getCSharpTypeFromMushroomType(field.values.items?.type ?? 'string')}${itemNullType}>${valueNullType}>${nullType};\n`;
|
|
89
|
+
}
|
|
74
90
|
}
|
|
75
91
|
else {
|
|
76
|
-
code += ` ${fieldName}${optionalMark}: ${getCSharpTypeFromMushroomType(
|
|
92
|
+
code += ` ${fieldName}${optionalMark}: Record<string, ${getCSharpTypeFromMushroomType(field.values?.type ?? 'string')}${valueNullType}>${nullType};\n`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (field.type == 'array') {
|
|
96
|
+
const itemNullType = options?.checkRequired && (field.items.required || field.items.validation?.required) ? '' : ' | null | undefined';
|
|
97
|
+
if (field.items?.type == 'object') {
|
|
98
|
+
const fieldClassName = className + '_' + toTypeScriptClassName(fieldName);
|
|
99
|
+
code += ` ${fieldName}${optionalMark}: Array<${fieldClassName}${itemNullType}>${nullType};\n`;
|
|
100
|
+
childrenCode += generateTypescriptClass(field.items.fields ?? {}, fieldClassName, options);
|
|
101
|
+
}
|
|
102
|
+
else if (field.items?.type == 'keyValue') {
|
|
103
|
+
const valueNullType = options?.checkRequired && (field.items.values?.required || field.items.values?.validation?.required) ? '' : ' | null | undefined';
|
|
104
|
+
if (field.items.values?.type == 'object') {
|
|
105
|
+
const fieldClassName = className + '_' + toTypeScriptClassName(fieldName);
|
|
106
|
+
code += ` ${fieldName}${optionalMark}: Array<Record<string, ${fieldClassName}${valueNullType}>${itemNullType}>${nullType};\n`;
|
|
107
|
+
childrenCode += generateTypescriptClass(field.items.values.fields ?? {}, fieldClassName, options);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
code += ` ${fieldName}${optionalMark}: Array<Record<string, ${getCSharpTypeFromMushroomType(field.items.type ?? 'string')}${valueNullType}>${itemNullType}>${nullType};\n`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
code += ` ${fieldName}${optionalMark}: Array<${getCSharpTypeFromMushroomType(field.items?.type ?? 'string')}${itemNullType}>${nullType};\n`;
|
|
77
115
|
}
|
|
78
116
|
}
|
|
79
117
|
else {
|
|
80
|
-
code += ` ${fieldName}${optionalMark}: ${getCSharpTypeFromMushroomType(
|
|
118
|
+
code += ` ${fieldName}${optionalMark}: ${getCSharpTypeFromMushroomType(field.type ?? 'string')}${nullType};\n`;
|
|
81
119
|
}
|
|
82
120
|
}
|
|
83
121
|
code += '}\n\n';
|
|
@@ -93,6 +131,69 @@ function generateTypescriptClassFromViewParameters(parameters) {
|
|
|
93
131
|
}
|
|
94
132
|
return '{}';
|
|
95
133
|
}
|
|
134
|
+
function generateTopCustomClass(config, entityName, methodName, grantRole, postfix, code) {
|
|
135
|
+
const isKeyValue = config.type == 'keyValue';
|
|
136
|
+
const isArray = isKeyValue ? config.values?.type == 'array' : config.type == 'array';
|
|
137
|
+
const fields = isKeyValue ? (isArray ? config.values?.items?.fields : config.values?.fields) : (isArray ? config.items?.fields : config.fields);
|
|
138
|
+
const type = (isKeyValue ? (isArray ? config.values?.items?.type : config.values?.type) : (isArray ? config.items?.type : config.type)) ?? 'string';
|
|
139
|
+
let inputClassName;
|
|
140
|
+
if (type == 'object') {
|
|
141
|
+
if (fields) {
|
|
142
|
+
const roleIndicator = grantRole ? '_' + toTypeScriptClassName(grantRole) + '_' : '';
|
|
143
|
+
inputClassName = `${toTypeScriptClassName(entityName)}_${toTypeScriptClassName(methodName)}${roleIndicator}${postfix}`;
|
|
144
|
+
code.classesCode += generateTypescriptClass(fields, inputClassName, {
|
|
145
|
+
checkRequired: true
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
inputClassName = 'any';
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else
|
|
153
|
+
inputClassName = getCSharpTypeFromMushroomType(type);
|
|
154
|
+
return isKeyValue ? (isArray ? 'Record<string, ' + inputClassName + '[]>' : 'Record<string, ' + inputClassName + '>') : (isArray ? inputClassName + '[]' : inputClassName);
|
|
155
|
+
}
|
|
156
|
+
function generateCustomMethodCode(entityName, actionName, actions) {
|
|
157
|
+
const result = { classesCode: '', methodCode: '' };
|
|
158
|
+
if (!actionName || !actionName.startsWith('_raw_http_method_') || !actions || !actions.length)
|
|
159
|
+
return result;
|
|
160
|
+
actions = actions.filter(action => action.enabled);
|
|
161
|
+
if (!actions.length)
|
|
162
|
+
return result;
|
|
163
|
+
const methodName = actionName.substring('_raw_http_method_'.length);
|
|
164
|
+
let inputTypes = new Set();
|
|
165
|
+
let outputTypes = new Set();
|
|
166
|
+
actions.forEach(action => {
|
|
167
|
+
const codeHintDelegator = action?.codeHint?.delegator;
|
|
168
|
+
if (!codeHintDelegator)
|
|
169
|
+
return;
|
|
170
|
+
if (codeHintDelegator.result && !codeHintDelegator.isBinaryResponse) {
|
|
171
|
+
const className = generateTopCustomClass(codeHintDelegator.result, entityName, methodName, actions.length > 1 ? action.grant : '', 'Result', result);
|
|
172
|
+
outputTypes.add(className);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
outputTypes.add('any');
|
|
176
|
+
}
|
|
177
|
+
if (codeHintDelegator.param && codeHintDelegator.requestBody) {
|
|
178
|
+
let paramClassName = generateTopCustomClass(codeHintDelegator.param, entityName, methodName, actions.length > 1 ? action.grant : '', 'ParamRequest', result);
|
|
179
|
+
const bodyClassName = generateTopCustomClass(codeHintDelegator.requestBody, entityName, methodName, actions.length > 1 ? action.grant : '', 'Request', result);
|
|
180
|
+
inputTypes.add(`CustomMethodRequest<${paramClassName}, ${bodyClassName}>`);
|
|
181
|
+
}
|
|
182
|
+
else if (codeHintDelegator.param) {
|
|
183
|
+
const className = generateTopCustomClass(codeHintDelegator.param, entityName, methodName, actions.length > 1 ? action.grant : '', 'ParamRequest', result);
|
|
184
|
+
inputTypes.add(`CustomMethodParamsRequest<${className}>`);
|
|
185
|
+
}
|
|
186
|
+
else if (codeHintDelegator.requestBody) {
|
|
187
|
+
const className = generateTopCustomClass(codeHintDelegator.requestBody, entityName, methodName, actions.length > 1 ? action.grant : '', 'Request', result);
|
|
188
|
+
inputTypes.add(`CustomMethodBodyRequest<${className}>`);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
inputTypes.add('MushroomRequest');
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
result.methodCode = ` ${methodName}Async: (request: ${inputTypes.size ? [...inputTypes].join(' | ') : 'MushroomRequest'}) => Promise<MushroomResponse<${outputTypes.size ? [...outputTypes].join(' | ') : 'any'}>>;\n`;
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
96
197
|
export function genTypescriptDriverString(aliasProject, source) {
|
|
97
198
|
if (!aliasProject) {
|
|
98
199
|
return '';
|
|
@@ -126,6 +227,19 @@ export const extensions = {
|
|
|
126
227
|
export type ISODateValue = string | Date;
|
|
127
228
|
export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoIncLong' ? 'number' : 'string'};
|
|
128
229
|
|
|
230
|
+
export interface CustomMethodRequest<TParam extends {}, TBody> extends MushroomRequest {
|
|
231
|
+
params?: TParam;
|
|
232
|
+
body?: TBody;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export interface CustomMethodParamsRequest<TParam extends {}> extends MushroomRequest {
|
|
236
|
+
params?: TParam;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export interface CustomMethodBodyRequest<TBody> extends MushroomRequest {
|
|
240
|
+
body?: TBody;
|
|
241
|
+
}
|
|
242
|
+
|
|
129
243
|
`;
|
|
130
244
|
let iApiClassBody = '';
|
|
131
245
|
for (const entityName in entities) {
|
|
@@ -133,6 +247,9 @@ export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoI
|
|
|
133
247
|
const typescriptClassName = toTypeScriptClassName(entityName);
|
|
134
248
|
code += generateTypescriptClass(entity.fields, typescriptClassName);
|
|
135
249
|
const actions = {};
|
|
250
|
+
if (entity.description) {
|
|
251
|
+
iApiClassBody += ` /**\n * ${entity.description.replace(/\r/, '').split('\n').map(line => line.includes('*/') ? line.replace(/\*\//g, "* /") : line).join('\n * ')}\n */\n`;
|
|
252
|
+
}
|
|
136
253
|
iApiClassBody += ` ${entityName}: MushroomResourceBase`;
|
|
137
254
|
let customMethodCode = '';
|
|
138
255
|
for (const actionName in entity.actions) {
|
|
@@ -194,7 +311,9 @@ export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoI
|
|
|
194
311
|
}
|
|
195
312
|
default: {
|
|
196
313
|
if (actionName.indexOf('_raw_http_method_') === 0) {
|
|
197
|
-
|
|
314
|
+
const customCode = generateCustomMethodCode(entityName, actionName, entity.actions[actionName]);
|
|
315
|
+
customMethodCode += customCode.methodCode;
|
|
316
|
+
code += customCode.classesCode;
|
|
198
317
|
break;
|
|
199
318
|
}
|
|
200
319
|
else {
|
|
@@ -205,9 +324,7 @@ export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoI
|
|
|
205
324
|
}
|
|
206
325
|
}
|
|
207
326
|
if (customMethodCode) {
|
|
208
|
-
code += `export interface ${typescriptClassName}$CustomMethodResource {
|
|
209
|
-
${customMethodCode}}
|
|
210
|
-
`;
|
|
327
|
+
code += `export interface ${typescriptClassName}$CustomMethodResource {\n${customMethodCode}}\n`;
|
|
211
328
|
iApiClassBody += ` & ${typescriptClassName}$CustomMethodResource`;
|
|
212
329
|
}
|
|
213
330
|
const views = {};
|
|
@@ -290,6 +407,19 @@ export declare const extensions = {
|
|
|
290
407
|
export declare type ISODateValue = string | Date;
|
|
291
408
|
export declare type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoIncLong' ? 'number' : 'string'};
|
|
292
409
|
|
|
410
|
+
export interface CustomMethodRequest<TParam extends {}, TBody> extends MushroomRequest {
|
|
411
|
+
params?: TParam;
|
|
412
|
+
body?: TBody;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export interface CustomMethodParamsRequest<TParam extends {}> extends MushroomRequest {
|
|
416
|
+
params?: TParam;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
export interface CustomMethodBodyRequest<TBody> extends MushroomRequest {
|
|
420
|
+
body?: TBody;
|
|
421
|
+
}
|
|
422
|
+
|
|
293
423
|
`;
|
|
294
424
|
let iApiClassBody = '';
|
|
295
425
|
for (const entityName in entities) {
|