@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.
@@ -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 순회
@@ -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
- else if (el.Type === "Tab" && el.TabItems && Array.isArray(el.TabItems)) {
475
- // 탭이면 TabItems( 페이지) > Controls(자식 컨트롤) 재귀 순회
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
- if (tabPage.Controls && Array.isArray(tabPage.Controls)) {
480
- walkElements(tabPage.Controls, callback, tabPagePath);
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.23",
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",