worsoft-frontend-codegen-local-mcp 0.1.23 → 0.1.24
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/mcp_server.js +73 -52
- package/package.json +1 -1
package/mcp_server.js
CHANGED
|
@@ -5,7 +5,7 @@ const fs = require('fs');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
|
|
7
7
|
const SERVER_NAME = 'worsoft-codegen-local';
|
|
8
|
-
const SERVER_VERSION = '0.1.
|
|
8
|
+
const SERVER_VERSION = '0.1.24';
|
|
9
9
|
const PROTOCOL_VERSION = '2024-11-05';
|
|
10
10
|
const TOOL_NAME = 'worsoft_codegen_local_generate_frontend';
|
|
11
11
|
const TEMPLATE_LIBRARY_ROOT = path.resolve(__dirname, '..', 'template');
|
|
@@ -16,25 +16,27 @@ const DEFAULT_DICT_REGISTRY_KEYS = {
|
|
|
16
16
|
trade_standard_type: 'TRADE_STANDARD_TYPE',
|
|
17
17
|
trade_score_standard: 'TRADE_SCORE_STANDARD',
|
|
18
18
|
};
|
|
19
|
-
const DEFAULT_CRUD_SCHEMA_TEMPLATE = `export interface FieldMeta {
|
|
20
|
-
show: boolean;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
const DEFAULT_CRUD_SCHEMA_TEMPLATE = `export interface FieldMeta {
|
|
20
|
+
show: boolean;
|
|
21
|
+
listShow: boolean;
|
|
22
|
+
alwaysHide: boolean;
|
|
23
|
+
smart: boolean;
|
|
24
|
+
labelKey: string;
|
|
24
25
|
label?: string;
|
|
25
26
|
width: string;
|
|
26
27
|
dictType?: string;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
export interface FieldConfig {
|
|
30
|
-
key: string;
|
|
31
|
-
labelKey?: string;
|
|
32
|
-
label?: string;
|
|
33
|
-
width?: string;
|
|
34
|
-
show?: boolean;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
export interface FieldConfig {
|
|
31
|
+
key: string;
|
|
32
|
+
labelKey?: string;
|
|
33
|
+
label?: string;
|
|
34
|
+
width?: string;
|
|
35
|
+
show?: boolean;
|
|
36
|
+
listShow?: boolean;
|
|
37
|
+
alwaysHide?: boolean;
|
|
38
|
+
smart?: boolean;
|
|
39
|
+
dictType?: string;
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
export interface CrudSchemaDefinition {
|
|
@@ -52,11 +54,12 @@ export interface CrudSchema {
|
|
|
52
54
|
|
|
53
55
|
const DEFAULT_WIDTH = '120';
|
|
54
56
|
|
|
55
|
-
export const field = (labelKey: string, width = DEFAULT_WIDTH): FieldMeta => ({
|
|
56
|
-
show: true,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
export const field = (labelKey: string, width = DEFAULT_WIDTH): FieldMeta => ({
|
|
58
|
+
show: true,
|
|
59
|
+
listShow: true,
|
|
60
|
+
alwaysHide: false,
|
|
61
|
+
smart: false,
|
|
62
|
+
labelKey,
|
|
60
63
|
width,
|
|
61
64
|
});
|
|
62
65
|
|
|
@@ -79,10 +82,11 @@ export const collectDictTypes = (...groups: Array<Record<string, FieldMeta>>) =>
|
|
|
79
82
|
)
|
|
80
83
|
);
|
|
81
84
|
|
|
82
|
-
const normalizeField = (item: FieldConfig): FieldMeta => ({
|
|
83
|
-
show: item.show ?? true,
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
const normalizeField = (item: FieldConfig): FieldMeta => ({
|
|
86
|
+
show: item.show ?? true,
|
|
87
|
+
listShow: item.listShow ?? item.show ?? true,
|
|
88
|
+
alwaysHide: item.alwaysHide ?? false,
|
|
89
|
+
smart: item.smart ?? false,
|
|
86
90
|
labelKey: item.labelKey ?? item.label ?? item.key,
|
|
87
91
|
...(item.label ? { label: item.label } : {}),
|
|
88
92
|
width: item.width ?? DEFAULT_WIDTH,
|
|
@@ -145,6 +149,7 @@ const TOOL_SCHEMA = {
|
|
|
145
149
|
required: { type: ['boolean', 'string'], description: 'Whether the field is required.' },
|
|
146
150
|
readonly: { type: ['boolean', 'string'], description: 'Whether the field is readonly on the page.' },
|
|
147
151
|
show: { type: ['boolean', 'string'], description: 'Whether the field is shown on the page.' },
|
|
152
|
+
listShow: { type: ['boolean', 'string'], description: 'Whether the field is shown on the list page.' },
|
|
148
153
|
dictType: { type: 'string', description: 'Dictionary type code from the API document.' },
|
|
149
154
|
defaultValue: { type: ['string', 'number', 'boolean'], description: 'Optional default value.' },
|
|
150
155
|
description: { type: 'string', description: 'Field description or notes.' },
|
|
@@ -181,6 +186,7 @@ const TOOL_SCHEMA = {
|
|
|
181
186
|
required: { type: ['boolean', 'string'], description: 'Whether the field is required.' },
|
|
182
187
|
readonly: { type: ['boolean', 'string'], description: 'Whether the field is readonly on the page.' },
|
|
183
188
|
show: { type: ['boolean', 'string'], description: 'Whether the field is shown on the page.' },
|
|
189
|
+
listShow: { type: ['boolean', 'string'], description: 'Whether the field is shown on the list page.' },
|
|
184
190
|
dictType: { type: 'string', description: 'Dictionary type code from the API document.' },
|
|
185
191
|
defaultValue: { type: ['string', 'number', 'boolean'], description: 'Optional default value.' },
|
|
186
192
|
description: { type: 'string', description: 'Field description or notes.' },
|
|
@@ -428,20 +434,20 @@ function buildChildSectionTitleKey(model, childModel) {
|
|
|
428
434
|
return `${buildI18nNamespace(model)}.children.${childModel.listName}.title`;
|
|
429
435
|
}
|
|
430
436
|
|
|
431
|
-
function buildLocaleLeaf(model) {
|
|
432
|
-
const leaf = {
|
|
433
|
-
title: model.tableComment,
|
|
434
|
-
fields: Object.fromEntries(model.
|
|
435
|
-
};
|
|
437
|
+
function buildLocaleLeaf(model) {
|
|
438
|
+
const leaf = {
|
|
439
|
+
title: model.tableComment,
|
|
440
|
+
fields: Object.fromEntries(model.optionFields.map((field) => [field.attrName, stripDictAnnotation(field.comment)])),
|
|
441
|
+
};
|
|
436
442
|
|
|
437
443
|
if (model.children.length) {
|
|
438
444
|
leaf.children = Object.fromEntries(
|
|
439
445
|
model.children.map((childModel) => [
|
|
440
446
|
childModel.listName,
|
|
441
|
-
{
|
|
442
|
-
title: childModel.tableComment,
|
|
443
|
-
fields: Object.fromEntries(childModel.
|
|
444
|
-
},
|
|
447
|
+
{
|
|
448
|
+
title: childModel.tableComment,
|
|
449
|
+
fields: Object.fromEntries(childModel.optionFields.map((field) => [field.attrName, stripDictAnnotation(field.comment)])),
|
|
450
|
+
},
|
|
445
451
|
])
|
|
446
452
|
);
|
|
447
453
|
}
|
|
@@ -778,6 +784,7 @@ function normalizeStructuredField(inputField, index, contextLabel) {
|
|
|
778
784
|
defaultValue: normalizeDefaultValue(inputField.defaultValue),
|
|
779
785
|
readonly: parseBooleanLike(inputField.readonly, false),
|
|
780
786
|
show: parseBooleanLike(inputField.show, true),
|
|
787
|
+
listShow: parseBooleanLike(inputField.listShow, parseBooleanLike(inputField.show, true)),
|
|
781
788
|
sourceKind: normalizeStructuredSourceKind(inputField.sourceKind),
|
|
782
789
|
primary: parseBooleanLike(inputField.primary, fieldName === 'id'),
|
|
783
790
|
};
|
|
@@ -903,9 +910,10 @@ function buildChildModels(safeArgs, mainFields, mainPk) {
|
|
|
903
910
|
});
|
|
904
911
|
const mainRelationField = ensureFieldExists(mainFields, relation.mainField, safeArgs.tableName, 'Main relation');
|
|
905
912
|
const childRelationField = ensureFieldExists(childFields, relation.childField, relation.childTableName, 'Child relation');
|
|
906
|
-
const
|
|
907
|
-
(field) => field.fieldName !== childPk.fieldName && !field.isAudit && field.fieldName !== relation.childField
|
|
913
|
+
const childOptionFields = childFields.filter(
|
|
914
|
+
(field) => field.fieldName !== childPk.fieldName && !field.isAudit && field.fieldName !== relation.childField
|
|
908
915
|
);
|
|
916
|
+
const childVisibleFields = childOptionFields.filter((field) => field.show !== false);
|
|
909
917
|
const payloadField = relation.payloadField;
|
|
910
918
|
const listName = payloadField;
|
|
911
919
|
|
|
@@ -919,6 +927,7 @@ function buildChildModels(safeArgs, mainFields, mainPk) {
|
|
|
919
927
|
payloadFieldSource: 'arguments',
|
|
920
928
|
pk: childPk,
|
|
921
929
|
fields: childFields,
|
|
930
|
+
optionFields: childOptionFields,
|
|
922
931
|
visibleFields: childVisibleFields,
|
|
923
932
|
mainField: mainRelationField,
|
|
924
933
|
childField: childRelationField,
|
|
@@ -932,11 +941,13 @@ function buildModel(safeArgs) {
|
|
|
932
941
|
const fields = normalizeFields({
|
|
933
942
|
fields: safeArgs.fields,
|
|
934
943
|
});
|
|
935
|
-
const
|
|
936
|
-
const
|
|
944
|
+
const optionFields = fields.filter((field) => field.fieldName !== pkField.fieldName && !field.isAudit);
|
|
945
|
+
const visibleFields = optionFields.filter((field) => field.show !== false);
|
|
946
|
+
const listFields = optionFields.filter((field) => field.listShow !== false);
|
|
947
|
+
const gridFields = listFields.slice(0, 8);
|
|
937
948
|
const children = buildChildModels(safeArgs, fields, pkField);
|
|
938
|
-
const childDictTypes = children.flatMap((child) => child.
|
|
939
|
-
const dictTypes = [...new Set([...
|
|
949
|
+
const childDictTypes = children.flatMap((child) => child.optionFields.map((field) => field.dictType).filter(Boolean));
|
|
950
|
+
const dictTypes = [...new Set([...optionFields.map((field) => field.dictType).filter(Boolean), ...childDictTypes])];
|
|
940
951
|
|
|
941
952
|
const functionName = toCamelCase(safeArgs.tableName);
|
|
942
953
|
const apiPath = safeArgs.apiPath || functionName;
|
|
@@ -950,7 +961,9 @@ function buildModel(safeArgs) {
|
|
|
950
961
|
moduleName: normalizeModulePathForFeature(safeArgs.moduleName, functionName, apiPath),
|
|
951
962
|
pk: pkField,
|
|
952
963
|
fields,
|
|
964
|
+
optionFields,
|
|
953
965
|
visibleFields,
|
|
966
|
+
listFields,
|
|
954
967
|
gridFields,
|
|
955
968
|
dictTypes,
|
|
956
969
|
frontendPath: path.resolve(safeArgs.frontendPath),
|
|
@@ -1211,27 +1224,34 @@ function getDefaultOptionFieldWidthV2(field) {
|
|
|
1211
1224
|
return '100';
|
|
1212
1225
|
}
|
|
1213
1226
|
|
|
1214
|
-
function renderOptionFieldV2(field, labelKey, dictRegistryRefs, indent = ' ') {
|
|
1215
|
-
const
|
|
1227
|
+
function renderOptionFieldV2(field, labelKey, dictRegistryRefs, indent = ' ') {
|
|
1228
|
+
const fallbackLabel = stripDictAnnotation(field.comment).replace(/'/g, "\\'");
|
|
1229
|
+
const parts = [`key: '${field.attrName}'`, `labelKey: '${labelKey}'`, `label: '${fallbackLabel}'`];
|
|
1216
1230
|
const width = getDefaultOptionFieldWidthV2(field);
|
|
1217
1231
|
|
|
1218
1232
|
if (width !== '120') {
|
|
1219
1233
|
parts.push(`width: '${width}'`);
|
|
1220
1234
|
}
|
|
1221
1235
|
|
|
1222
|
-
if (field.dictType) {
|
|
1223
|
-
parts.push(`dictType: ${getDictRegistryReference(field.dictType, dictRegistryRefs)}`);
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
}
|
|
1236
|
+
if (field.dictType) {
|
|
1237
|
+
parts.push(`dictType: ${getDictRegistryReference(field.dictType, dictRegistryRefs)}`);
|
|
1238
|
+
}
|
|
1239
|
+
if (field.show === false) {
|
|
1240
|
+
parts.push('show: false');
|
|
1241
|
+
}
|
|
1242
|
+
if (field.listShow === false) {
|
|
1243
|
+
parts.push('listShow: false');
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
return `${indent}{ ${parts.join(', ')} },`;
|
|
1247
|
+
}
|
|
1228
1248
|
|
|
1229
1249
|
function renderChildOptionGroupV2(model, childModel, dictRegistryRefs) {
|
|
1230
1250
|
return [
|
|
1231
1251
|
` ${childModel.listName}: [`,
|
|
1232
|
-
childModel.
|
|
1233
|
-
.map((field) => renderOptionFieldV2(field, buildChildFieldLabelKey(model, childModel, field), dictRegistryRefs, ' '))
|
|
1234
|
-
.join('\n'),
|
|
1252
|
+
childModel.optionFields
|
|
1253
|
+
.map((field) => renderOptionFieldV2(field, buildChildFieldLabelKey(model, childModel, field), dictRegistryRefs, ' '))
|
|
1254
|
+
.join('\n'),
|
|
1235
1255
|
' ],',
|
|
1236
1256
|
].join('\n');
|
|
1237
1257
|
}
|
|
@@ -1443,7 +1463,7 @@ function buildReplacements(model, sharedSupport) {
|
|
|
1443
1463
|
TABLE_COLUMNS: model.gridFields.map((field) => renderTableColumnV2(field, dictRegistryRefs)).join('\n'),
|
|
1444
1464
|
FORM_DEFAULTS: renderFormDefaults(model),
|
|
1445
1465
|
DICT_REGISTRY_IMPORT_BLOCK: model.dictTypes.length ? "import { DictRegistry } from '/@/enums/dict-registry';" : '',
|
|
1446
|
-
MASTER_OPTION_FIELDS: model.
|
|
1466
|
+
MASTER_OPTION_FIELDS: model.optionFields.map((field) => renderOptionFieldV2(field, buildFieldLabelKey(model, field), dictRegistryRefs)).join('\n'),
|
|
1447
1467
|
CHILD_OPTION_GROUPS: model.children.map((childModel) => renderChildOptionGroupV2(model, childModel, dictRegistryRefs)).join('\n'),
|
|
1448
1468
|
FORM_RULES: renderFormRulesV2(model.visibleFields),
|
|
1449
1469
|
CHILD_FORM_LIST_DEFAULTS: renderChildFormListDefaults(model.children),
|
|
@@ -1582,7 +1602,8 @@ function buildManifest(model, safeArgs, stylePreset, sharedTemplates, files, not
|
|
|
1582
1602
|
summary: {
|
|
1583
1603
|
totalFields: model.fields.length,
|
|
1584
1604
|
visibleFields: model.visibleFields.length,
|
|
1585
|
-
|
|
1605
|
+
listVisibleFields: model.listFields.length,
|
|
1606
|
+
dictFields: model.optionFields.filter((field) => field.dictType).map((field) => field.attrName),
|
|
1586
1607
|
skippedAuditFields: model.fields.filter((field) => field.isAudit).map((field) => field.fieldName),
|
|
1587
1608
|
childCount: model.children.length,
|
|
1588
1609
|
childTables: model.children.map((childModel) => childModel.tableName),
|
package/package.json
CHANGED