mushroom-cli 1.2.0-alpha.17 → 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 +150 -21
- 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,33 +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
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (
|
|
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) ? '' : '?';
|
|
67
|
+
const nullType = optionalMark ? ' | null' : '';
|
|
68
|
+
if (field.type == 'object') {
|
|
66
69
|
const fieldClassName = className + '_' + toTypeScriptClassName(fieldName);
|
|
67
|
-
code += ` ${fieldName}: ${fieldClassName}${
|
|
68
|
-
childrenCode += generateTypescriptClass(
|
|
70
|
+
code += ` ${fieldName}${optionalMark}: ${fieldClassName}${nullType};\n`;
|
|
71
|
+
childrenCode += generateTypescriptClass(field.fields ?? {}, fieldClassName, options);
|
|
69
72
|
}
|
|
70
|
-
else if (
|
|
71
|
-
|
|
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') {
|
|
72
76
|
const fieldClassName = className + '_' + toTypeScriptClassName(fieldName);
|
|
73
|
-
code += ` ${fieldName}: ${fieldClassName}
|
|
74
|
-
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
|
+
}
|
|
75
90
|
}
|
|
76
91
|
else {
|
|
77
|
-
code += ` ${fieldName}: ${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`;
|
|
78
115
|
}
|
|
79
116
|
}
|
|
80
117
|
else {
|
|
81
|
-
code += ` ${fieldName}: ${getCSharpTypeFromMushroomType(
|
|
118
|
+
code += ` ${fieldName}${optionalMark}: ${getCSharpTypeFromMushroomType(field.type ?? 'string')}${nullType};\n`;
|
|
82
119
|
}
|
|
83
120
|
}
|
|
84
121
|
code += '}\n\n';
|
|
@@ -88,12 +125,75 @@ function generateTypescriptClassFromViewParameters(parameters) {
|
|
|
88
125
|
if (Array.isArray(parameters)) {
|
|
89
126
|
return ('{\n' +
|
|
90
127
|
parameters
|
|
91
|
-
.map((p) => ` ${p.field}: ${getCSharpTypeFromMushroomType(p.type || 'string')}${p.isArray ? '[]' : ''}${p.validation?.required && p.defaultValue === undefined ? '' : ' | null
|
|
128
|
+
.map((p) => ` ${p.field}${p.validation?.required && p.defaultValue === undefined ? '' : '?'}: ${getCSharpTypeFromMushroomType(p.type || 'string')}${p.isArray ? '[]' : ''}${p.validation?.required && p.defaultValue === undefined ? '' : ' | null'};`)
|
|
92
129
|
.join('\n') +
|
|
93
130
|
'\n}');
|
|
94
131
|
}
|
|
95
132
|
return '{}';
|
|
96
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
|
+
}
|
|
97
197
|
export function genTypescriptDriverString(aliasProject, source) {
|
|
98
198
|
if (!aliasProject) {
|
|
99
199
|
return '';
|
|
@@ -127,6 +227,19 @@ export const extensions = {
|
|
|
127
227
|
export type ISODateValue = string | Date;
|
|
128
228
|
export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoIncLong' ? 'number' : 'string'};
|
|
129
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
|
+
|
|
130
243
|
`;
|
|
131
244
|
let iApiClassBody = '';
|
|
132
245
|
for (const entityName in entities) {
|
|
@@ -134,6 +247,9 @@ export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoI
|
|
|
134
247
|
const typescriptClassName = toTypeScriptClassName(entityName);
|
|
135
248
|
code += generateTypescriptClass(entity.fields, typescriptClassName);
|
|
136
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
|
+
}
|
|
137
253
|
iApiClassBody += ` ${entityName}: MushroomResourceBase`;
|
|
138
254
|
let customMethodCode = '';
|
|
139
255
|
for (const actionName in entity.actions) {
|
|
@@ -195,7 +311,9 @@ export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoI
|
|
|
195
311
|
}
|
|
196
312
|
default: {
|
|
197
313
|
if (actionName.indexOf('_raw_http_method_') === 0) {
|
|
198
|
-
|
|
314
|
+
const customCode = generateCustomMethodCode(entityName, actionName, entity.actions[actionName]);
|
|
315
|
+
customMethodCode += customCode.methodCode;
|
|
316
|
+
code += customCode.classesCode;
|
|
199
317
|
break;
|
|
200
318
|
}
|
|
201
319
|
else {
|
|
@@ -206,9 +324,7 @@ export type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoI
|
|
|
206
324
|
}
|
|
207
325
|
}
|
|
208
326
|
if (customMethodCode) {
|
|
209
|
-
code += `export interface ${typescriptClassName}$CustomMethodResource {
|
|
210
|
-
${customMethodCode}}
|
|
211
|
-
`;
|
|
327
|
+
code += `export interface ${typescriptClassName}$CustomMethodResource {\n${customMethodCode}}\n`;
|
|
212
328
|
iApiClassBody += ` & ${typescriptClassName}$CustomMethodResource`;
|
|
213
329
|
}
|
|
214
330
|
const views = {};
|
|
@@ -291,6 +407,19 @@ export declare const extensions = {
|
|
|
291
407
|
export declare type ISODateValue = string | Date;
|
|
292
408
|
export declare type IdValue = ${source.idType == 'AutoIncInt' || source.idType == 'AutoIncLong' ? 'number' : 'string'};
|
|
293
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
|
+
|
|
294
423
|
`;
|
|
295
424
|
let iApiClassBody = '';
|
|
296
425
|
for (const entityName in entities) {
|