@bimatrix-aud-platform/aud_mcp_server 1.1.52 → 1.1.56

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.
@@ -1,4 +1,5 @@
1
1
  import { readFileSync, writeFileSync } from "fs";
2
+ import { randomBytes } from "crypto";
2
3
  import { createDefaultOlapField, isNumericColumnType } from "./olap-field.js";
3
4
  /**
4
5
  * MTSD 파일을 읽고, 자동 보정 규칙을 적용한 뒤, 파일을 덮어씁니다.
@@ -60,6 +61,8 @@ export function fixMtsd(filePath) {
60
61
  fixEnumAndRangeValues(doc, datas, fixes);
61
62
  // Rule 4: Tab > TabItems 내 ChildElements → Controls 노드 이름 보정
62
63
  fixTabItemChildElements(doc, fixes);
64
+ // Rule 5: ServerScriptText Key 누락 보정
65
+ fixServerScriptKey(doc, fixes);
63
66
  // Rule (disabled): DataSource Params에 Value 누락 보정
64
67
  //fixParamsMissingValue(datas, fixes);
65
68
  // Rule 4: DataSource Columns에 Type 누락 보정
@@ -710,6 +713,28 @@ function fixTabItemChildElements(doc, fixes) {
710
713
  walk(elements, "");
711
714
  }
712
715
  }
716
+ // ---- Rule 5: ServerScriptText Key 누락 보정 ----
717
+ // Key가 없으면: Name이 @로 시작하면 Name을 그대로 Key로, 아니면 UUID 생성
718
+ function fixServerScriptKey(doc, fixes) {
719
+ const scripts = doc.ServerScriptText;
720
+ if (!scripts || !Array.isArray(scripts))
721
+ return;
722
+ for (let i = 0; i < scripts.length; i++) {
723
+ const script = scripts[i];
724
+ if (script.Key)
725
+ continue; // Key가 이미 있으면 스킵
726
+ const name = script.Name || "";
727
+ if (name.startsWith("@")) {
728
+ script.Key = name;
729
+ fixes.push(`[Rule5] ServerScriptText[${i}]("${name}"): Key 누락 → Name "${name}" 사용`);
730
+ }
731
+ else {
732
+ const uuid = randomBytes(16).toString("hex").toUpperCase();
733
+ script.Key = uuid;
734
+ fixes.push(`[Rule5] ServerScriptText[${i}]("${name}"): Key 누락 → UUID "${uuid}" 생성`);
735
+ }
736
+ }
737
+ }
713
738
  // ---- 유틸: Element 트리 순회 ----
714
739
  function walkElements(elements, callback, parentPath = "") {
715
740
  for (const el of elements) {
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import { generateOlapFields } from "./generators/olap-field.js";
16
16
  import { executeMtsdScript } from "./generators/mtsd-builder.js";
17
17
  import { generateId } from "./utils/uuid.js";
18
18
  import { callSchemaService, callDbmsList, callBoxStyleService, callBoxStyleSaveService, callSaveReportService, callReadReportService, downloadReportResources, getAudConfig, isAudConfigured, setWorkspaceRoots, callModuleService } from "./utils/aud-api-client.js";
19
- import { buildSaveModel, writeReportResponse, writePullResponse } from "./utils/report-publisher.js";
19
+ import { buildSaveModel, writeReportResponse, writePullResponse, readReportDocument } from "./utils/report-publisher.js";
20
20
  import { execSync, execFile } from "child_process";
21
21
  const __filename = fileURLToPath(import.meta.url);
22
22
  const __dirname = dirname(__filename);
@@ -549,13 +549,13 @@ const tools = [
549
549
  },
550
550
  {
551
551
  name: "fix_mtsd",
552
- description: "MTSD 파일을 읽어 자동 보정 규칙을 적용하고 파일을 덮어씁니다. [Rule1] DataSource Name→Id 참조 보정, [Rule2] OlapGrid DataSource 기반 Fields 자동 생성, [Rule2-2] OlapGrid Fields 내 CreateType=1 중복 보정 (#MEASURES_HEADER#만 허용), [Rule3] Enum/Range 값 범위 초과 보정 (Border.LineType, Font 정렬, Color RGBA clamp, GridColumn 속성, OlapField 속성 등), Params ParamType 누락 보정을 수행합니다.",
552
+ description: "MTSD 문서 파일(.design.json, .mtsd, .sc)을 읽어 자동 보정 규칙을 적용하고 파일을 덮어씁니다. [Rule1] DataSource Name→Id 참조 보정, [Rule2] OlapGrid DataSource 기반 Fields 자동 생성, [Rule2-2] OlapGrid Fields 내 CreateType=1 중복 보정 (#MEASURES_HEADER#만 허용), [Rule3] Enum/Range 값 범위 초과 보정 (Border.LineType, Font 정렬, Color RGBA clamp, GridColumn 속성, OlapField 속성 등), Params ParamType 누락 보정을 수행합니다.",
553
553
  inputSchema: {
554
554
  type: "object",
555
555
  properties: {
556
556
  path: {
557
557
  type: "string",
558
- description: "MTSD 파일의 전체 경로 (예: C:/reports/sample/sample.mtsd)",
558
+ description: "MTSD 문서 파일의 전체 경로 (.design.json 우선, 예: C:/reports/sample/sample.design.json)",
559
559
  },
560
560
  },
561
561
  required: ["path"],
@@ -833,13 +833,13 @@ const tools = [
833
833
  // ── i-AUD Save Report (Publish) Tool ──────────────
834
834
  {
835
835
  name: "save_report",
836
- description: "보고서를 i-AUD 서버에 저장(Publish)합니다. 보고서 폴더의 MTSD, DataSource, ServerScript, JScript를 수집하여 서버에 전송하고 응답으로 로컬 파일을 업데이트합니다.",
836
+ description: "보고서를 i-AUD 서버에 저장(Publish)합니다. 보고서 폴더의 MTSD(.design.json 또는 .mtsd), DataSource, ServerScript, JScript를 수집하여 서버에 전송하고 응답으로 .mtsd(서버 원본) 및 .design.json(개발용 파일 경로 참조) 파일을 갱신합니다. .design.json이 없는 보고서에서 실행하면 자동 생성됩니다.",
837
837
  inputSchema: {
838
838
  type: "object",
839
839
  properties: {
840
840
  reportPath: {
841
841
  type: "string",
842
- description: "보고서 폴더 경로 (.aud.json 있는 폴더)",
842
+ description: "보고서 폴더 경로 (.design.json 또는 .mtsd 파일이 있는 폴더)",
843
843
  },
844
844
  build: {
845
845
  type: "boolean",
@@ -853,13 +853,13 @@ const tools = [
853
853
  // ── i-AUD Pull Report (서버→로컬 동기화) Tool ──────────────
854
854
  {
855
855
  name: "pull_report",
856
- description: "i-AUD 서버에서 보고서의 최신 내용을 가져옵니다. 서버의 MTSD, DataSource, ServerScript, JScript를 로컬 폴더에 동기화합니다.",
856
+ description: "i-AUD 서버에서 보고서의 최신 내용을 가져옵니다. 서버의 MTSD, DataSource, ServerScript, JScript를 로컬 폴더에 동기화하고, .mtsd(서버 원본) 및 .design.json(개발용 파일 경로 참조)을 생성/갱신합니다. .design.json이 없는 보고서에서 실행하면 자동 생성됩니다.",
857
857
  inputSchema: {
858
858
  type: "object",
859
859
  properties: {
860
860
  reportPath: {
861
861
  type: "string",
862
- description: "보고서 폴더 경로 (.aud.json 있는 폴더)",
862
+ description: "보고서 폴더 경로 (.design.json 또는 .mtsd 파일이 있는 폴더)",
863
863
  },
864
864
  },
865
865
  required: ["reportPath"],
@@ -874,7 +874,7 @@ const tools = [
874
874
  properties: {
875
875
  reportPath: {
876
876
  type: "string",
877
- description: "보고서 폴더 경로 (.aud.json 있는 폴더)",
877
+ description: "보고서 폴더 경로 (.design.json 또는 .mtsd 파일이 있는 폴더)",
878
878
  },
879
879
  },
880
880
  required: ["reportPath"],
@@ -883,7 +883,7 @@ const tools = [
883
883
  // ── MTSD Builder Script Executor Tool ──────────────
884
884
  {
885
885
  name: "build_mtsd",
886
- description: "MtsdBuilder Fluent API를 사용하는 JavaScript 스크립트를 실행하여 MTSD 문서를 생성합니다. AI가 JS 스크립트를 작성하면, 이 도구가 실행하여 스키마를 준수하는 완전한 MTSD JSON을 반환합니다.",
886
+ description: "MtsdBuilder Fluent API를 사용하는 JavaScript 스크립트를 실행하여 MTSD 문서(화면 UI 디자인)를 생성합니다. AI가 JS 스크립트를 작성하면, 이 도구가 실행하여 스키마를 준수하는 완전한 MTSD JSON을 반환합니다. 반환된 JSON은 .design.json 파일로 저장합니다.",
887
887
  inputSchema: {
888
888
  type: "object",
889
889
  properties: {
@@ -2014,17 +2014,16 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2014
2014
  }],
2015
2015
  };
2016
2016
  }
2017
- // .aud.json 존재 확인
2018
- const audJsonPath = join(reportPath, ".aud.json");
2017
+ // 보고서 문서 존재 확인
2019
2018
  try {
2020
- readFileSync(audJsonPath, "utf-8");
2019
+ readReportDocument(reportPath);
2021
2020
  }
2022
2021
  catch {
2023
2022
  return {
2024
2023
  content: [{
2025
2024
  type: "text",
2026
2025
  text: JSON.stringify({
2027
- error: `보고서 폴더에 .aud.json 파일이 없습니다: ${audJsonPath}`,
2026
+ error: `보고서 폴더에 문서 파일(.design.json, .mtsd, .sc)이 없습니다: ${reportPath}`,
2028
2027
  }),
2029
2028
  }],
2030
2029
  };
@@ -2110,29 +2109,28 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2110
2109
  }],
2111
2110
  };
2112
2111
  }
2113
- // .aud.json 존재 확인 및 ReportCode 읽기
2114
- const audJsonPath = join(reportPath, ".aud.json");
2115
- let audJson;
2112
+ // 보고서 문서에서 ReportCode 읽기
2113
+ let reportDoc;
2116
2114
  try {
2117
- audJson = JSON.parse(readFileSync(audJsonPath, "utf-8"));
2115
+ reportDoc = readReportDocument(reportPath);
2118
2116
  }
2119
2117
  catch {
2120
2118
  return {
2121
2119
  content: [{
2122
2120
  type: "text",
2123
2121
  text: JSON.stringify({
2124
- error: `보고서 폴더에 .aud.json 파일이 없습니다: ${audJsonPath}`,
2122
+ error: `보고서 폴더에 문서 파일(.design.json, .mtsd, .sc)이 없습니다: ${reportPath}`,
2125
2123
  }),
2126
2124
  }],
2127
2125
  };
2128
2126
  }
2129
- const reportCode = audJson.ReportCode;
2127
+ const reportCode = reportDoc?.ReportInfo?.ReportCode;
2130
2128
  if (!reportCode) {
2131
2129
  return {
2132
2130
  content: [{
2133
2131
  type: "text",
2134
2132
  text: JSON.stringify({
2135
- error: ".aud.json에 ReportCode가 없습니다.",
2133
+ error: "보고서 문서에 ReportInfo.ReportCode가 없습니다.",
2136
2134
  }),
2137
2135
  }],
2138
2136
  };
@@ -2166,7 +2164,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2166
2164
  if (resModel.MX_GRID_ZIP_PATH) {
2167
2165
  mxGridFiles = await downloadReportResources(reportPath, resModel.MX_GRID_ZIP_PATH);
2168
2166
  }
2169
- const reportName = resModel.ReportModel?.ReportInfo?.ReportName || audJson.ReportName || "";
2167
+ const reportName = resModel.ReportModel?.ReportInfo?.ReportName || reportDoc?.ReportInfo?.ReportName || "";
2170
2168
  return {
2171
2169
  content: [{
2172
2170
  type: "text",
@@ -2199,26 +2197,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2199
2197
  }],
2200
2198
  };
2201
2199
  }
2202
- // .aud.json 읽기
2203
- const audJsonPath = join(reportPath, ".aud.json");
2204
- let audJson;
2200
+ // 보고서 문서에서 ReportCode 읽기
2201
+ let runDoc;
2205
2202
  try {
2206
- audJson = JSON.parse(readFileSync(audJsonPath, "utf-8"));
2203
+ runDoc = readReportDocument(reportPath);
2207
2204
  }
2208
2205
  catch {
2209
2206
  return {
2210
2207
  content: [{
2211
2208
  type: "text",
2212
- text: JSON.stringify({ error: `보고서 폴더에 .aud.json 파일이 없습니다: ${audJsonPath}` }),
2209
+ text: JSON.stringify({ error: `보고서 폴더에 문서 파일(.design.json, .mtsd, .sc)이 없습니다: ${reportPath}` }),
2213
2210
  }],
2214
2211
  };
2215
2212
  }
2216
- const reportCode = audJson.ReportCode;
2213
+ const reportCode = runDoc?.ReportInfo?.ReportCode;
2217
2214
  if (!reportCode) {
2218
2215
  return {
2219
2216
  content: [{
2220
2217
  type: "text",
2221
- text: JSON.stringify({ error: ".aud.json에 ReportCode가 없습니다." }),
2218
+ text: JSON.stringify({ error: "보고서 문서에 ReportInfo.ReportCode가 없습니다." }),
2222
2219
  }],
2223
2220
  };
2224
2221
  }
@@ -2293,7 +2290,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2293
2290
  success: true,
2294
2291
  message: `${browserName} 브라우저에서 Designer를 실행했습니다.`,
2295
2292
  reportCode,
2296
- reportName: audJson.ReportName || "",
2293
+ reportName: runDoc?.ReportInfo?.ReportName || "",
2297
2294
  url: designerUrl,
2298
2295
  }, null, 2),
2299
2296
  }],