@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.
- package/dist/generators/fixer.js +113 -0
- package/dist/index.js +99 -0
- package/package.json +1 -1
- package/schemas/mtsd.interface.ts +452 -60
- package/schemas/mtsd.schema.json +311 -39
package/dist/generators/fixer.js
CHANGED
|
@@ -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.
|
|
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",
|