@bimatrix-aud-platform/aud_mcp_server 1.1.23 → 1.1.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.
- package/dist/generators/control-info.js +11 -2
- package/dist/generators/fixer.js +197 -5
- package/package.json +1 -1
- package/schemas/mtsd.interface.ts +489 -74
- package/schemas/mtsd.schema.json +339 -52
|
@@ -52,10 +52,19 @@ export function getControlInfo(filePath, filterName) {
|
|
|
52
52
|
typeSet.add(type);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
// ChildElements 재귀 순회
|
|
56
|
-
if (el.ChildElements && Array.isArray(el.ChildElements)) {
|
|
55
|
+
// ChildElements 재귀 순회 (Group)
|
|
56
|
+
if (type !== "Tab" && el.ChildElements && Array.isArray(el.ChildElements)) {
|
|
57
57
|
walkElements(el.ChildElements, type === "Group" ? name : parentGroup);
|
|
58
58
|
}
|
|
59
|
+
// Tab > TabItems > Controls 또는 ChildElements 재귀 순회
|
|
60
|
+
if (type === "Tab" && el.TabItems && Array.isArray(el.TabItems)) {
|
|
61
|
+
for (const tabPage of el.TabItems) {
|
|
62
|
+
const children = tabPage.Controls || tabPage.ChildElements;
|
|
63
|
+
if (children && Array.isArray(children)) {
|
|
64
|
+
walkElements(children, name);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
70
|
// Forms > Elements 순회
|
package/dist/generators/fixer.js
CHANGED
|
@@ -58,6 +58,8 @@ export function fixMtsd(filePath) {
|
|
|
58
58
|
fixOlapMeasuresField(doc, fixes);
|
|
59
59
|
// Rule 3: Enum/Range 값 범위 초과 보정
|
|
60
60
|
fixEnumAndRangeValues(doc, datas, fixes);
|
|
61
|
+
// Rule 4: Tab > TabItems 내 ChildElements → Controls 노드 이름 보정
|
|
62
|
+
fixTabItemChildElements(doc, fixes);
|
|
61
63
|
// Rule (disabled): DataSource Params에 Value 누락 보정
|
|
62
64
|
//fixParamsMissingValue(datas, fixes);
|
|
63
65
|
// Rule 4: DataSource Columns에 Type 누락 보정
|
|
@@ -384,6 +386,28 @@ function fixEnumAndRangeValues(doc, datas, fixes) {
|
|
|
384
386
|
for (const form of forms) {
|
|
385
387
|
const elements = form.Elements || [];
|
|
386
388
|
walkElements(elements, (el, path) => {
|
|
389
|
+
// ---- AutoRefresh / DoRefresh / DoExport 필수 속성 보정 ----
|
|
390
|
+
const type = el.Type;
|
|
391
|
+
// AutoRefresh 대상: DataGrid, ComboBox, MultiComboBox, OlapGrid, Chart, PieChart, ScatterChart, PolygonChart, TreeGrid, iGrid, WebContainer
|
|
392
|
+
const hasAutoRefresh = ["DataGrid", "ComboBox", "MultiComboBox", "OlapGrid", "Chart", "PieChart", "ScatterChart", "PolygonChart", "TreeGrid", "iGrid", "WebContainer"];
|
|
393
|
+
if (hasAutoRefresh.includes(type) && !("AutoRefresh" in el)) {
|
|
394
|
+
const autoDefault = type === "ComboBox" ? true : false;
|
|
395
|
+
el.AutoRefresh = autoDefault;
|
|
396
|
+
fixes.push(`[Rule3] ${path}.AutoRefresh: 누락 → ${autoDefault}`);
|
|
397
|
+
}
|
|
398
|
+
// DoRefresh 대상: DataGrid, ComboBox, OlapGrid, Chart, PieChart, ScatterChart, PolygonChart, TreeGrid, iGrid, UserComponent, WebContainer
|
|
399
|
+
const hasDoRefresh = ["DataGrid", "ComboBox", "OlapGrid", "Chart", "PieChart", "ScatterChart", "PolygonChart", "TreeGrid", "iGrid", "UserComponent", "WebContainer"];
|
|
400
|
+
if (hasDoRefresh.includes(type) && !("DoRefresh" in el)) {
|
|
401
|
+
const isCombo = type === "ComboBox";
|
|
402
|
+
el.DoRefresh = isCombo ? false : true;
|
|
403
|
+
fixes.push(`[Rule3] ${path}.DoRefresh: 누락 → ${el.DoRefresh}`);
|
|
404
|
+
}
|
|
405
|
+
// DoExport 대상: DataGrid, OlapGrid, Chart, PieChart, ScatterChart, PolygonChart, TreeGrid, iGrid, UserComponent, Tab
|
|
406
|
+
const hasDoExport = ["DataGrid", "OlapGrid", "Chart", "PieChart", "ScatterChart", "PolygonChart", "TreeGrid", "iGrid", "UserComponent", "Tab"];
|
|
407
|
+
if (hasDoExport.includes(type) && !("DoExport" in el)) {
|
|
408
|
+
el.DoExport = true;
|
|
409
|
+
fixes.push(`[Rule3] ${path}.DoExport: 누락 → true`);
|
|
410
|
+
}
|
|
387
411
|
// ---- Style.Border.LineType ----
|
|
388
412
|
const border = el.Style?.Border;
|
|
389
413
|
if (border) {
|
|
@@ -410,6 +434,34 @@ function fixEnumAndRangeValues(doc, datas, fixes) {
|
|
|
410
434
|
if (bg.Color)
|
|
411
435
|
clampColorRGBA(bg.Color, `${path}.Style.Background.Color`, fixes);
|
|
412
436
|
}
|
|
437
|
+
// ---- DataGrid: ColumnHeaderHeight / RowHeight / ShowHeader 필수 ----
|
|
438
|
+
if (el.Type === "DataGrid") {
|
|
439
|
+
if (!("ColumnHeaderHeight" in el)) {
|
|
440
|
+
el.ColumnHeaderHeight = 28;
|
|
441
|
+
fixes.push(`[Rule3] ${path}.ColumnHeaderHeight: 누락 → 28`);
|
|
442
|
+
}
|
|
443
|
+
if (!("RowHeight" in el)) {
|
|
444
|
+
el.RowHeight = 24;
|
|
445
|
+
fixes.push(`[Rule3] ${path}.RowHeight: 누락 → 24`);
|
|
446
|
+
}
|
|
447
|
+
if (!("ShowHeader" in el)) {
|
|
448
|
+
el.ShowHeader = 3;
|
|
449
|
+
fixes.push(`[Rule3] ${path}.ShowHeader: 누락 → 3 (Row&Column)`);
|
|
450
|
+
}
|
|
451
|
+
fixIntRange(el, "ShowHeader", 0, 3, 3, path, fixes); // 0:None, 1:Row, 2:Column, 3:Row&Column
|
|
452
|
+
if (!("SelectRule" in el)) {
|
|
453
|
+
el.SelectRule = 2;
|
|
454
|
+
fixes.push(`[Rule3] ${path}.SelectRule: 누락 → 2 (SingleRange)`);
|
|
455
|
+
}
|
|
456
|
+
fixIntRange(el, "SelectRule", 0, 3, 2, path, fixes); // 0:SingleRow, 1:MultiRow, 2:SingleRange, 3:SingleCell
|
|
457
|
+
}
|
|
458
|
+
// ---- TreeGrid: ToggleBtnSize 필수 ----
|
|
459
|
+
if (el.Type === "TreeGrid") {
|
|
460
|
+
if (!("ToggleBtnSize" in el)) {
|
|
461
|
+
el.ToggleBtnSize = 10;
|
|
462
|
+
fixes.push(`[Rule3] ${path}.ToggleBtnSize: 누락 → 10`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
413
465
|
// ---- DataGrid / TreeGrid Columns ----
|
|
414
466
|
if ((el.Type === "DataGrid" || el.Type === "TreeGrid") && Array.isArray(el.Columns)) {
|
|
415
467
|
for (let i = 0; i < el.Columns.length; i++) {
|
|
@@ -425,6 +477,61 @@ function fixEnumAndRangeValues(doc, datas, fixes) {
|
|
|
425
477
|
fixIntRange(col, "DataType", 0, 2, 0, colPath, fixes); // 기본값: 1(String)
|
|
426
478
|
}
|
|
427
479
|
}
|
|
480
|
+
// ---- FileUploadButton: Value / Cursor 필수 ----
|
|
481
|
+
if (el.Type === "FileUploadButton") {
|
|
482
|
+
if (!("Value" in el)) {
|
|
483
|
+
el.Value = "upload";
|
|
484
|
+
fixes.push(`[Rule3] ${path}.Value: 누락 → "upload"`);
|
|
485
|
+
}
|
|
486
|
+
if (!("Cursor" in el)) {
|
|
487
|
+
el.Cursor = "pointer";
|
|
488
|
+
fixes.push(`[Rule3] ${path}.Cursor: 누락 → "pointer"`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// ---- Chart: PlotOptions 필수 ----
|
|
492
|
+
const isChart = ["Chart", "PieChart", "ScatterChart", "PolygonChart"].includes(type);
|
|
493
|
+
if (isChart) {
|
|
494
|
+
if (!el.PlotOptions || typeof el.PlotOptions !== "object") {
|
|
495
|
+
el.PlotOptions = { Animation: 1000, EnableMouseTracking: true, DataLabels: {}, ConnectNulls: false, AllowOverlap: false };
|
|
496
|
+
fixes.push(`[Rule3] ${path}.PlotOptions: 누락 → 기본값 생성`);
|
|
497
|
+
}
|
|
498
|
+
else {
|
|
499
|
+
const po = el.PlotOptions;
|
|
500
|
+
if (!("Animation" in po)) {
|
|
501
|
+
po.Animation = 1000;
|
|
502
|
+
fixes.push(`[Rule3] ${path}.PlotOptions.Animation: 누락 → 1000`);
|
|
503
|
+
}
|
|
504
|
+
if (!("EnableMouseTracking" in po)) {
|
|
505
|
+
po.EnableMouseTracking = true;
|
|
506
|
+
fixes.push(`[Rule3] ${path}.PlotOptions.EnableMouseTracking: 누락 → true`);
|
|
507
|
+
}
|
|
508
|
+
if (!("DataLabels" in po) || typeof po.DataLabels !== "object") {
|
|
509
|
+
po.DataLabels = {};
|
|
510
|
+
fixes.push(`[Rule3] ${path}.PlotOptions.DataLabels: 누락 → {}`);
|
|
511
|
+
}
|
|
512
|
+
if (!("ConnectNulls" in po)) {
|
|
513
|
+
po.ConnectNulls = false;
|
|
514
|
+
fixes.push(`[Rule3] ${path}.PlotOptions.ConnectNulls: 누락 → false`);
|
|
515
|
+
}
|
|
516
|
+
if (!("AllowOverlap" in po)) {
|
|
517
|
+
po.AllowOverlap = false;
|
|
518
|
+
fixes.push(`[Rule3] ${path}.PlotOptions.AllowOverlap: 누락 → false`);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
// ---- MultiComboBox: InitType / RefreshType 필수 + enum 범위 ----
|
|
523
|
+
if (el.Type === "MultiComboBox") {
|
|
524
|
+
if (!("InitType" in el)) {
|
|
525
|
+
el.InitType = 0;
|
|
526
|
+
fixes.push(`[Rule3] ${path}.InitType: 누락 → 0 (CurrentValue)`);
|
|
527
|
+
}
|
|
528
|
+
fixIntRange(el, "InitType", 0, 2, 0, path, fixes); // 0:CurrentValue, 1:InitValue, 2:없음
|
|
529
|
+
if (!("RefreshType" in el)) {
|
|
530
|
+
el.RefreshType = 1;
|
|
531
|
+
fixes.push(`[Rule3] ${path}.RefreshType: 누락 → 1 (FirstTime)`);
|
|
532
|
+
}
|
|
533
|
+
fixIntRange(el, "RefreshType", 0, 2, 1, path, fixes); // 0:None, 1:FirstTime, 2:EveryTime
|
|
534
|
+
}
|
|
428
535
|
// ---- OlapGrid Fields ----
|
|
429
536
|
if (el.Type === "OlapGrid") {
|
|
430
537
|
const fields = el.iOLAPView?.Fields;
|
|
@@ -460,6 +567,86 @@ function fixEnumAndRangeValues(doc, datas, fixes) {
|
|
|
460
567
|
});
|
|
461
568
|
}
|
|
462
569
|
}
|
|
570
|
+
// ---- Rule 4: Tab > TabItems 내 ChildElements → Controls 보정 ----
|
|
571
|
+
function fixTabItemChildElements(doc, fixes) {
|
|
572
|
+
const forms = doc.Forms || [];
|
|
573
|
+
for (const form of forms) {
|
|
574
|
+
const elements = form?.Elements;
|
|
575
|
+
if (!elements || !Array.isArray(elements))
|
|
576
|
+
continue;
|
|
577
|
+
function walk(els, parentPath) {
|
|
578
|
+
for (const el of els) {
|
|
579
|
+
const path = parentPath
|
|
580
|
+
? `${parentPath} > ${el.Type || "?"}(${el.Name || el.Id || "?"})`
|
|
581
|
+
: `${el.Type || "?"}(${el.Name || el.Id || "?"})`;
|
|
582
|
+
if (el.Type === "Tab") {
|
|
583
|
+
// Property 누락 시 기본값 생성
|
|
584
|
+
if (!el.Property) {
|
|
585
|
+
el.Property = {};
|
|
586
|
+
fixes.push(`[Rule4] ${path}.Property: 누락 → 기본값 생성`);
|
|
587
|
+
}
|
|
588
|
+
const prop = el.Property;
|
|
589
|
+
// TabButtonPosition 필수 — 누락 시 기본값, 범위 검증 (0:Top, 1:Bottom)
|
|
590
|
+
if (!("TabButtonPosition" in prop)) {
|
|
591
|
+
prop.TabButtonPosition = 0;
|
|
592
|
+
fixes.push(`[Rule4] ${path}.Property.TabButtonPosition: 누락 → 0`);
|
|
593
|
+
}
|
|
594
|
+
fixIntRange(prop, "TabButtonPosition", 0, 1, 0, `${path}.Property`, fixes);
|
|
595
|
+
if (!el.TabItems || !Array.isArray(el.TabItems)) {
|
|
596
|
+
el.TabItems = [];
|
|
597
|
+
fixes.push(`[Rule4] ${path}.TabItems: 누락 → 빈 배열 생성`);
|
|
598
|
+
}
|
|
599
|
+
for (let i = 0; i < el.TabItems.length; i++) {
|
|
600
|
+
const tabPage = el.TabItems[i];
|
|
601
|
+
const tiPath = `${path} > TabItem[${i}](${tabPage.Name || "?"})`;
|
|
602
|
+
// BaseProperties.Width 누락 시 기본값 생성
|
|
603
|
+
if (tabPage.BaseProperties) {
|
|
604
|
+
if (!tabPage.BaseProperties.Width) {
|
|
605
|
+
tabPage.BaseProperties.Width = { WidthSettingType: 0, WidthValue: 100 };
|
|
606
|
+
fixes.push(`[Rule4] ${tiPath}.BaseProperties.Width: 누락 → 기본값 {WidthSettingType:0(FitToLength), WidthValue:100}`);
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
const w = tabPage.BaseProperties.Width;
|
|
610
|
+
if (!("WidthSettingType" in w)) {
|
|
611
|
+
w.WidthSettingType = 0;
|
|
612
|
+
fixes.push(`[Rule4] ${tiPath}.BaseProperties.Width.WidthSettingType: 누락 → 0(FitToLength)`);
|
|
613
|
+
}
|
|
614
|
+
if (!("WidthValue" in w)) {
|
|
615
|
+
w.WidthValue = 100;
|
|
616
|
+
fixes.push(`[Rule4] ${tiPath}.BaseProperties.Width.WidthValue: 누락 → 100`);
|
|
617
|
+
}
|
|
618
|
+
fixIntRange(w, "WidthSettingType", 0, 1, 0, `${tiPath}.BaseProperties.Width`, fixes);
|
|
619
|
+
}
|
|
620
|
+
// Visible 누락 시 기본값 true
|
|
621
|
+
if (!("Visible" in tabPage.BaseProperties)) {
|
|
622
|
+
tabPage.BaseProperties.Visible = true;
|
|
623
|
+
fixes.push(`[Rule4] ${tiPath}.BaseProperties.Visible: 누락 → true`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
if (tabPage.ChildElements && !tabPage.Controls) {
|
|
627
|
+
tabPage.Controls = tabPage.ChildElements;
|
|
628
|
+
delete tabPage.ChildElements;
|
|
629
|
+
fixes.push(`[Rule4] ${path} > TabItem[${i}](${tabPage.Name || "?"}): ChildElements → Controls 노드 이름 변경`);
|
|
630
|
+
}
|
|
631
|
+
// TabItem 내 자식 요소도 재귀 순회
|
|
632
|
+
if (tabPage.Controls && Array.isArray(tabPage.Controls)) {
|
|
633
|
+
walk(tabPage.Controls, `${path} > TabItem[${i}](${tabPage.Name || "?"})`);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
// Group 등 ChildElements 재귀 순회
|
|
638
|
+
if (el.Type !== "Tab" && el.ChildElements && Array.isArray(el.ChildElements)) {
|
|
639
|
+
walk(el.ChildElements, path);
|
|
640
|
+
}
|
|
641
|
+
// iGrid의 Controls 재귀 순회
|
|
642
|
+
if (el.Type === "iGrid" && el.Controls && Array.isArray(el.Controls)) {
|
|
643
|
+
walk(el.Controls, path);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
walk(elements, "");
|
|
648
|
+
}
|
|
649
|
+
}
|
|
463
650
|
// ---- 유틸: Element 트리 순회 ----
|
|
464
651
|
function walkElements(elements, callback, parentPath = "") {
|
|
465
652
|
for (const el of elements) {
|
|
@@ -468,16 +655,21 @@ function walkElements(elements, callback, parentPath = "") {
|
|
|
468
655
|
: `${el.Type || "?"}(${el.Name || el.Id || "?"})`;
|
|
469
656
|
callback(el, path);
|
|
470
657
|
// Group의 ChildElements 재귀 순회
|
|
471
|
-
if (el.ChildElements && Array.isArray(el.ChildElements)) {
|
|
658
|
+
if (el.Type !== "Tab" && el.ChildElements && Array.isArray(el.ChildElements)) {
|
|
472
659
|
walkElements(el.ChildElements, callback, path);
|
|
473
660
|
}
|
|
474
|
-
|
|
475
|
-
|
|
661
|
+
// iGrid의 Controls 재귀 순회
|
|
662
|
+
if (el.Type === "iGrid" && el.Controls && Array.isArray(el.Controls)) {
|
|
663
|
+
walkElements(el.Controls, callback, path);
|
|
664
|
+
}
|
|
665
|
+
// Tab > TabItems > Controls 또는 ChildElements 재귀 순회
|
|
666
|
+
if (el.Type === "Tab" && el.TabItems && Array.isArray(el.TabItems)) {
|
|
476
667
|
for (let i = 0; i < el.TabItems.length; i++) {
|
|
477
668
|
const tabPage = el.TabItems[i];
|
|
478
669
|
const tabPagePath = `${path} > TabItem[${i}](${tabPage.Name || "?"})`;
|
|
479
|
-
|
|
480
|
-
|
|
670
|
+
const children = tabPage.Controls || tabPage.ChildElements;
|
|
671
|
+
if (children && Array.isArray(children)) {
|
|
672
|
+
walkElements(children, callback, tabPagePath);
|
|
481
673
|
}
|
|
482
674
|
}
|
|
483
675
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bimatrix-aud-platform/aud_mcp_server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.25",
|
|
4
4
|
"description": "MCP Server for i-AUD MTSD document validation, generation, schema querying, control info extraction, and database operations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|