@bimatrix-aud-platform/aud_mcp_server 1.1.24 → 1.1.26

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.
@@ -386,6 +386,28 @@ function fixEnumAndRangeValues(doc, datas, fixes) {
386
386
  for (const form of forms) {
387
387
  const elements = form.Elements || [];
388
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
+ }
389
411
  // ---- Style.Border.LineType ----
390
412
  const border = el.Style?.Border;
391
413
  if (border) {
@@ -412,6 +434,34 @@ function fixEnumAndRangeValues(doc, datas, fixes) {
412
434
  if (bg.Color)
413
435
  clampColorRGBA(bg.Color, `${path}.Style.Background.Color`, fixes);
414
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
+ }
415
465
  // ---- DataGrid / TreeGrid Columns ----
416
466
  if ((el.Type === "DataGrid" || el.Type === "TreeGrid") && Array.isArray(el.Columns)) {
417
467
  for (let i = 0; i < el.Columns.length; i++) {
@@ -427,6 +477,61 @@ function fixEnumAndRangeValues(doc, datas, fixes) {
427
477
  fixIntRange(col, "DataType", 0, 2, 0, colPath, fixes); // 기본값: 1(String)
428
478
  }
429
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
+ }
430
535
  // ---- OlapGrid Fields ----
431
536
  if (el.Type === "OlapGrid") {
432
537
  const fields = el.iOLAPView?.Fields;
@@ -533,6 +638,10 @@ function fixTabItemChildElements(doc, fixes) {
533
638
  if (el.Type !== "Tab" && el.ChildElements && Array.isArray(el.ChildElements)) {
534
639
  walk(el.ChildElements, path);
535
640
  }
641
+ // iGrid의 Controls 재귀 순회
642
+ if (el.Type === "iGrid" && el.Controls && Array.isArray(el.Controls)) {
643
+ walk(el.Controls, path);
644
+ }
536
645
  }
537
646
  }
538
647
  walk(elements, "");
@@ -549,6 +658,10 @@ function walkElements(elements, callback, parentPath = "") {
549
658
  if (el.Type !== "Tab" && el.ChildElements && Array.isArray(el.ChildElements)) {
550
659
  walkElements(el.ChildElements, callback, path);
551
660
  }
661
+ // iGrid의 Controls 재귀 순회
662
+ if (el.Type === "iGrid" && el.Controls && Array.isArray(el.Controls)) {
663
+ walkElements(el.Controls, callback, path);
664
+ }
552
665
  // Tab > TabItems > Controls 또는 ChildElements 재귀 순회
553
666
  if (el.Type === "Tab" && el.TabItems && Array.isArray(el.TabItems)) {
554
667
  for (let i = 0; i < el.TabItems.length; i++) {
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ import { generateDataSource } from "./generators/datasource.js";
13
13
  import { fixMtsd } from "./generators/fixer.js";
14
14
  import { getControlInfo } from "./generators/control-info.js";
15
15
  import { generateOlapFields } from "./generators/olap-field.js";
16
+ import { generateId } from "./utils/uuid.js";
16
17
  import { callSchemaService, callDbmsList, isAudConfigured, setWorkspaceRoots } from "./utils/aud-api-client.js";
17
18
  const __filename = fileURLToPath(import.meta.url);
18
19
  const __dirname = dirname(__filename);
@@ -614,6 +615,44 @@ const tools = [
614
615
  required: ["path"],
615
616
  },
616
617
  },
618
+ // ── UUID Generation Tool ───────────────────────────
619
+ {
620
+ name: "generate_uuid",
621
+ description: "i-AUD 보고서용 UUID(고유 식별자)를 생성합니다. Element, DataSource, Variable 등의 ID로 사용할 수 있는 'prefix + 32자리 HEX' 형식의 ID를 생성합니다. 한 번에 여러 개를 생성하거나, 여러 prefix를 지정하여 다양한 컴포넌트의 ID를 일괄 생성할 수 있습니다.",
622
+ inputSchema: {
623
+ type: "object",
624
+ properties: {
625
+ prefix: {
626
+ type: "string",
627
+ description: "ID 접두사 (예: Label, Button, TextBox, DataGrid, DS, Var 등). items 파라미터 사용 시 무시됩니다.",
628
+ default: "",
629
+ },
630
+ count: {
631
+ type: "number",
632
+ description: "생성할 UUID 개수 (기본값: 1, 최대: 50)",
633
+ default: 1,
634
+ },
635
+ items: {
636
+ type: "array",
637
+ items: {
638
+ type: "object",
639
+ properties: {
640
+ prefix: {
641
+ type: "string",
642
+ description: "ID 접두사 (예: Label, Button, DS 등)",
643
+ },
644
+ count: {
645
+ type: "number",
646
+ description: "해당 prefix로 생성할 개수 (기본값: 1)",
647
+ },
648
+ },
649
+ required: ["prefix"],
650
+ },
651
+ description: "여러 prefix를 한 번에 지정하여 일괄 생성. 예: [{prefix:'Label',count:2},{prefix:'DS',count:1}]",
652
+ },
653
+ },
654
+ },
655
+ },
617
656
  // ── i-AUD DBMS Connection List Tool ────────────────
618
657
  {
619
658
  name: "get_dbms_list",
@@ -1358,6 +1397,66 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1358
1397
  ],
1359
1398
  };
1360
1399
  }
1400
+ // ── UUID Generation Handler ──────────────────────────
1401
+ case "generate_uuid": {
1402
+ const items = args?.items;
1403
+ if (items && Array.isArray(items)) {
1404
+ // 일괄 생성 모드
1405
+ const totalRequested = items.reduce((sum, item) => sum + Math.min(Number(item.count) || 1, 50), 0);
1406
+ if (totalRequested > 100) {
1407
+ return {
1408
+ content: [{
1409
+ type: "text",
1410
+ text: JSON.stringify({ error: "총 생성 개수가 100개를 초과할 수 없습니다." }),
1411
+ }],
1412
+ };
1413
+ }
1414
+ const results = {};
1415
+ for (const item of items) {
1416
+ const prefix = item.prefix || "";
1417
+ const count = Math.min(Math.max(Number(item.count) || 1, 1), 50);
1418
+ const ids = [];
1419
+ for (let i = 0; i < count; i++) {
1420
+ ids.push(generateId(prefix));
1421
+ }
1422
+ if (results[prefix]) {
1423
+ results[prefix].push(...ids);
1424
+ }
1425
+ else {
1426
+ results[prefix] = ids;
1427
+ }
1428
+ }
1429
+ return {
1430
+ content: [{
1431
+ type: "text",
1432
+ text: JSON.stringify({
1433
+ success: true,
1434
+ format: "prefix + 32자리 HEX (16바이트)",
1435
+ results,
1436
+ }, null, 2),
1437
+ }],
1438
+ };
1439
+ }
1440
+ else {
1441
+ // 단일 prefix 모드
1442
+ const prefix = args?.prefix || "";
1443
+ const count = Math.min(Math.max(Number(args?.count) || 1, 1), 50);
1444
+ const ids = [];
1445
+ for (let i = 0; i < count; i++) {
1446
+ ids.push(generateId(prefix));
1447
+ }
1448
+ return {
1449
+ content: [{
1450
+ type: "text",
1451
+ text: JSON.stringify({
1452
+ success: true,
1453
+ format: "prefix + 32자리 HEX (16바이트)",
1454
+ ids,
1455
+ }, null, 2),
1456
+ }],
1457
+ };
1458
+ }
1459
+ }
1361
1460
  // ── i-AUD DBMS List Handler ──────────────────────────
1362
1461
  case "get_dbms_list": {
1363
1462
  if (!isAudConfigured()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bimatrix-aud-platform/aud_mcp_server",
3
- "version": "1.1.24",
3
+ "version": "1.1.26",
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",