ide-assi 0.708.0 → 0.710.0

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.
@@ -0,0 +1,1384 @@
1
+ import ninegrid from "ninegrid2";
2
+ import { IdeUtils } from "./ideUtils.js";
3
+ import { api } from "./ideFetch.js";
4
+ import { HumanMessage, SystemMessage } from '@langchain/core/messages';
5
+ import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
6
+ import { Ollama } from "@langchain/ollama";
7
+ import { ChatOpenAI } from '@langchain/openai';
8
+
9
+ export class IdeAi
10
+ {
11
+ #API_URL = "http://localhost:8091";
12
+ #SCHEMA = "booxtory_250131";
13
+ #model;
14
+ #parent;
15
+ prompt = null;
16
+
17
+ constructor(parent) {
18
+ this.#parent = parent;
19
+ }
20
+
21
+ #createModel = () => {
22
+
23
+ switch (this.#parent.settings.server) {
24
+ case "chatopenai":
25
+ this.#model = new ChatOpenAI({
26
+ modelName: this.#parent.settings.model,
27
+ openAIApiKey: this.#parent.settings.CHATOPENAI_API_KEY,
28
+ configuration: {
29
+ baseURL: "https://openrouter.ai/api/v1",
30
+ },
31
+ temperature: 0,
32
+ });
33
+ break;
34
+ case "gemini":
35
+ this.#model = new ChatGoogleGenerativeAI({ model: this.#parent.settings.model, apiKey: this.#parent.settings.geminiApiKey, temperature: 0,});
36
+ break;
37
+ case "openai":
38
+ this.#model = new ChatOpenAI({ model: this.#parent.settings.model, apiKey: this.#parent.settings.openaiApiKey, temperature: 0, });
39
+ break;
40
+ case "ollama":
41
+ this.#model = new Ollama({
42
+ model: this.#parent.settings.model,
43
+ host: this.#parent.settings.ollamaUrl,
44
+ temperature: 0,
45
+ });
46
+ break;
47
+ }
48
+
49
+ //this.#qdrantClient = new QdrantClient({ url: this.settings.qdrantUrl });
50
+ };
51
+
52
+ #getMenuInfo = () => {
53
+ let arr = [];
54
+
55
+ ninegrid.querySelectorAll("nx-side-menu-item[href][title]").forEach(elem => {
56
+ arr.push({
57
+ //menuId: elem.getAttribute("menu-id"),
58
+ url: elem.getAttribute("href"),
59
+ title: elem.getAttribute("title"),
60
+ })
61
+ });
62
+
63
+ return arr;
64
+ };
65
+
66
+ #getTableList = async () => {
67
+ const response = await fetch("/api/meta/selectTableList", {
68
+ method: "POST",
69
+ headers: { "Content-Type": "application/json" },
70
+ body: JSON.stringify({
71
+ schema: this.#SCHEMA,
72
+ })
73
+ });
74
+
75
+ return await response.json();
76
+ };
77
+
78
+ #getColumnInfo = async (tables) => {
79
+ const response = await fetch("/api/meta/selectColumnInfo", {
80
+ method: "POST",
81
+ headers: { "Content-Type": "application/json" },
82
+ body: JSON.stringify({
83
+ schema: this.#SCHEMA,
84
+ tables: tables,
85
+ })
86
+ });
87
+
88
+ return await response.json();
89
+ };
90
+
91
+ #toJavaPackage = (path) => {
92
+ // 확장자 및 파일 제거: 마지막 / 이후는 제거
93
+ const withoutFile = path.substring(0, path.lastIndexOf('/'));
94
+
95
+ // 슬래시(/) → 점(.) 변환
96
+ return withoutFile.replace(/\//g, '.');
97
+ }
98
+
99
+ /**
100
+ * 1. 소스 명칭 package 예) tmpl.population
101
+ * 2. 소스가 없으면 소스 생성
102
+ * 3.
103
+ *
104
+ * 1. 메뉴정보, 테이블정보로 해당 패키지, URL, 소스명칭을 유추
105
+ */
106
+ generateSource = async (userPrompt) => {
107
+
108
+ const menus = this.#getMenuInfo();
109
+ const tables = await this.#getTableList();
110
+
111
+ console.log(menus);
112
+ console.log(tables);
113
+
114
+ const response = await fetch(`${this.#API_URL}/ai/inferSourceMeta`, {
115
+ method: "POST",
116
+ headers: { "Content-Type": "application/json" },
117
+ body: JSON.stringify({
118
+ userPrompt: userPrompt,
119
+ menus: menus,
120
+ tables: tables.list,
121
+ })
122
+ });
123
+
124
+ const res = await response.json();
125
+ //console.log(res);
126
+
127
+ if (res.result == "1") {
128
+
129
+ const columnInfo = await this.#getColumnInfo(res.table);
130
+ console.log(columnInfo);
131
+
132
+ const response2 = await fetch(`${this.#API_URL}/ai/generateSource`, {
133
+ method: "POST",
134
+ headers: { "Content-Type": "application/json" },
135
+ body: JSON.stringify({
136
+ packageName: "ide.assi.be." + this.#toJavaPackage(res.service).replace(".service", ""),
137
+ userPrompt: userPrompt,
138
+ url: res.menu.url,
139
+ tables: columnInfo.list,
140
+ })
141
+ });
142
+
143
+ const source = await response2.json();
144
+
145
+ const response3 = await fetch(`/api/source/generateMybatisFile`, {
146
+ method: "POST",
147
+ headers: { "Content-Type": "application/json" },
148
+ body: JSON.stringify({
149
+ fileNm: res.xml,
150
+ contents: source.mybatis,
151
+ })
152
+ });
153
+ //console.log(response3);
154
+ //console.log(await response3.json());
155
+
156
+ const response4 = await fetch(`/api/source/generateJavaFile`, {
157
+ method: "POST",
158
+ headers: { "Content-Type": "application/json" },
159
+ body: JSON.stringify({
160
+ fileNm: res.service,
161
+ contents: source.service,
162
+ })
163
+ });
164
+
165
+ const response5 = await fetch(`/api/source/generateJavaFile`, {
166
+ method: "POST",
167
+ headers: { "Content-Type": "application/json" },
168
+ body: JSON.stringify({
169
+ fileNm: res.controller,
170
+ contents: source.controller,
171
+ })
172
+ });
173
+
174
+ const response6 = await fetch(`/api/source/generateJsFile`, {
175
+ method: "POST",
176
+ headers: { "Content-Type": "application/json" },
177
+ body: JSON.stringify({
178
+ fileNm: res.js + "x",
179
+ contents: source.js,
180
+ })
181
+ });
182
+
183
+ return await response4.json();
184
+ }
185
+
186
+ return null;
187
+ };
188
+
189
+ #invoke = async (path, params) => {
190
+
191
+ const prompt = await IdeUtils.generatePrompt(path, params);
192
+ //console.log(prompt);
193
+
194
+ try {
195
+ const response = await this.#model.invoke([
196
+ //new SystemMessage(systemMessage),
197
+ new HumanMessage(prompt),
198
+ ]);
199
+
200
+ return IdeUtils.extractResponse(response, this.#parent.settings.server);
201
+ }
202
+ catch (error) {
203
+ throw error;
204
+ }
205
+ }
206
+
207
+
208
+
209
+ #what = async (userPrompt) => {
210
+ const o = await this.#invoke('/prompts/meta/1.what.txt', { "userPrompt": userPrompt });
211
+
212
+ console.log(o);
213
+
214
+ if (Object.prototype.toString.call(o) === "[object Object]" && o.hasOwnProperty("result")) {
215
+ if (o.result === "0") throw new Error(o.reason);
216
+ }
217
+ else {
218
+ throw new Error(o);
219
+ }
220
+
221
+ return o.result;
222
+ };
223
+
224
+ #where = async (userPrompt, menuList, tableDefinitions) => {
225
+
226
+ console.log(menuList, tableDefinitions, JSON.stringify(menuList), JSON.stringify(tableDefinitions));
227
+
228
+ const o = await this.#invoke('/prompts/meta/2.where.txt', {
229
+ "userPrompt": userPrompt,
230
+ "menuList": JSON.stringify(menuList),
231
+ "tableDefinitions": JSON.stringify(tableDefinitions),
232
+ });
233
+
234
+ console.log("=======================================================");
235
+ console.log(o);
236
+ console.log( Object.prototype.toString.call(o));
237
+ console.log(o.hasOwnProperty("result"));
238
+
239
+ if (Object.prototype.toString.call(o) === "[object Object]" && o.hasOwnProperty("result")) {
240
+ if (o.result === "0") throw new Error(o.reason);
241
+ }
242
+ else {
243
+ throw new Error(o);
244
+ }
245
+
246
+
247
+ return o;
248
+ };
249
+
250
+ #generateRealFile = async (srcPath, apply) => {
251
+ const fileMap = {
252
+ mybatis: { name: "mybatis.xml", path: srcPath.mybatisPullPath },
253
+ service: { name: "service.java", path: srcPath.servicePullPath },
254
+ controller: { name: "controller.java", path: srcPath.controllerPullPath },
255
+ javascript: { name: "react.jsx", path: srcPath.javascriptPullPath },
256
+ };
257
+
258
+ const selectedFiles = Object.entries(fileMap)
259
+ .filter(([key]) => apply[key])
260
+ .map(([_, { name, path }]) => ({ name, path }));
261
+
262
+ const params = await Promise.all(
263
+ selectedFiles.map(async ({ name, path }) => ({
264
+ path,
265
+ contents: await fetch(`/api/templates/${name}`).then(res => res.text()),
266
+ }))
267
+ );
268
+
269
+ console.log(params);
270
+
271
+ api.post(`/api/source/generateRealFile`, { list: params });
272
+ };
273
+
274
+
275
+ #generateTmplFile = async (promptFile, generateFileName, params) => {
276
+
277
+ let src = await this.#invoke(promptFile, params);
278
+ if (src.endsWith("```")) {
279
+ src = src.slice(0, -3);
280
+ }
281
+
282
+ await api.post(`/api/source/generateTmplFile`, {
283
+ basePath: `${this.#parent.settings.beProjectName}/tmpl`,
284
+ fileNm: generateFileName,
285
+ contents: src,
286
+ });
287
+
288
+ return src;
289
+ };
290
+
291
+
292
+ #findFirstEmptyDetailWrapper = () => {
293
+ const allWrappers = document.querySelectorAll('div[class^="detail-wrapper-"]');
294
+
295
+ for (const el of allWrappers) {
296
+ if (el.innerHTML.trim() === '') {
297
+ // 클래스명 전체를 반환하거나, 특정 패턴을 찾아 반환
298
+ const className = el.className;
299
+ const match = className.match(/detail-wrapper-([^ ]+)/); // 숫자뿐만 아니라 다른 문자도 포함
300
+
301
+ if (match && match[1]) {
302
+ return match[1];
303
+ }
304
+ }
305
+ }
306
+
307
+ return null; // 비어있는 요소가 없을 경우 null 반환
308
+ };
309
+
310
+ #findActiveDetailWrapperIndex = () => {
311
+ const allWrappers = document.querySelectorAll('div[class^="detail-wrapper-"]');
312
+
313
+ for (let i = 0; i < allWrappers.length; i++) {
314
+ const el = allWrappers[i];
315
+ if (el.classList.contains('active')) {
316
+ const className = el.className;
317
+ const match = className.match(/detail-wrapper-([^ ]+)/);
318
+
319
+ if (match && match[1]) {
320
+ return match[1];
321
+ }
322
+ }
323
+ }
324
+
325
+ return null; // 'active' 클래스를 가진 요소가 없을 경우 null 반환
326
+ };
327
+
328
+
329
+
330
+ #getSourcePath = (menuUrl) => {
331
+ const path = menuUrl.replace(/^\/+/, '');
332
+
333
+ const raw = path.split("/").join(".").toLowerCase();
334
+ const cleaned = raw.replace(/[^a-z0-9.]/g, "");
335
+ const namespace = `${this.#parent.config.basePackage}.${cleaned}`;
336
+
337
+ const packageName = namespace.split(".").slice(0, -1).join(".");
338
+
339
+ //const packageName = `${path.split("/").slice(0, -1).join(".").toLowerCase()}`;
340
+ //const packageName = path.split("/").join(".").toLowerCase();
341
+ const fileName = path.split("/").at(-1).toLowerCase().split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
342
+
343
+ const javascript = `${cleaned.split(".").slice(0, -1).join("/")}/${path.split("/").at(-1)}`;
344
+ const emptyIndex = this.#findFirstEmptyDetailWrapper();
345
+ const activeIndex = this.#findActiveDetailWrapperIndex();
346
+ const javascriptFrom = activeIndex ? javascript + "-detail-" + activeIndex : javascript;
347
+ const javascriptTo = javascript + "-detail-" + emptyIndex;
348
+ const classFrom = activeIndex ? fileName + "Detail" + activeIndex : fileName;
349
+ const classTo = fileName + "Detail" + emptyIndex;
350
+
351
+ //console.log("************", javascriptFrom, javascriptTo);
352
+
353
+ return {
354
+ package: packageName,
355
+ namespace: namespace,
356
+ baseClass: fileName,
357
+ resultType: this.#parent.config.basePackage.split(".").slice(0, -1).join(".") + ".core.utils.CamelCaseMap",
358
+ mybatis: `${cleaned.split(".").slice(0, -1).join("/")}/${fileName}Mapper.xml`,
359
+ //javascript: `${javascript}.jsx`,
360
+ //javascriptFrom: `${javascriptFrom}.jsx`,
361
+ //javascriptTo: `${javascriptTo}.jsx`,
362
+ classFrom: classFrom,
363
+ classTo: classTo,
364
+ activeIndex: activeIndex,
365
+ emptyIndex: emptyIndex,
366
+ mybatisPullPath: `${this.#parent.settings.beProjectName}/src/main/resources/mapper/${cleaned.split(".").slice(0, -1).join("/")}/${fileName}Mapper.xml`,
367
+ controllerPullPath: `${this.#parent.settings.beProjectName}/src/main/java/${packageName.replaceAll(".", "/")}/controller/${fileName}Controller.java`,
368
+ servicePullPath: `${this.#parent.settings.beProjectName}/src/main/java/${packageName.replaceAll(".", "/")}/service/${fileName}Service.java`,
369
+ //javascriptPullPath: `${this.#parent.settings.feProjectName}${javascript}.jsx`,
370
+ javascriptFrom: `${this.#parent.settings.feProjectName}/src/views/${javascriptFrom}.jsx`,
371
+ javascriptTo: `${this.#parent.settings.feProjectName}/src/views/${javascriptTo}.jsx`,
372
+ };
373
+ };
374
+
375
+
376
+ #modifySource = async (userPrompt, apply, progressMessageInstance) => {
377
+
378
+ const el = ninegrid.querySelector("nx-side-menu-item.active");
379
+ if (!el) throw new Error("관련 메뉴를 찾을 수 없습니다.");
380
+
381
+ const href = el.getAttribute("href");
382
+ const title = el.getAttribute("title");
383
+
384
+ console.log(el, href, title);
385
+
386
+ const srcPath = this.#getSourcePath(href);
387
+ console.log(srcPath);
388
+
389
+
390
+ /**
391
+ * {
392
+ * "package": "ide.assi.be.tmpla",
393
+ * "namespace": "ide.assi.be.tmpla.docmanager",
394
+ * "baseClass": "DocManager",
395
+ * "resultType": "ide.assi.core.utils.CamelCaseMap",
396
+ * "mybatis": "tmpla/DocManagerMapper.xml",
397
+ * "mybatisPullPath": "ide-assi-be/src/main/resources/mapper/tmpla/DocManagerMapper.xml",
398
+ * "controllerPullPath": "ide-assi-be/src/main/java/ide/assi/be/tmpla/controller/DocManagerController.java",
399
+ * "servicePullPath": "ide-assi-be/src/main/java/ide/assi/be/tmpla/service/DocManagerService.java",
400
+ * "javascriptPullPath": "ide-assi-fe-vite-react-js/src/views/tmpla/doc-manager.jsx"
401
+ * }
402
+ */
403
+ const src = await api.post("/api/source/read", srcPath);
404
+ //console.log(src);
405
+
406
+ /**
407
+ const response = await fetch(srcPath.javascript);
408
+ src.javascript = await response.text();*/
409
+
410
+ //console.log(src);
411
+ //const template = await fetch(path).then(res => res.text());
412
+ /*
413
+ arr.push({
414
+ //menuId: elem.getAttribute("menu-id"),
415
+ url: elem.getAttribute("href"),
416
+ title: elem.getAttribute("title"),
417
+ })*/
418
+
419
+
420
+
421
+
422
+
423
+ const where = await this.#where(`${title}에서 ${userPrompt}`, [{url: href, title: title}], await this.#getTableList());
424
+ //this.#parent.addMessage("대상 메뉴와 테이블을 찾았습니다.");
425
+ progressMessageInstance.updateProgress('prepare2', 'completed');
426
+
427
+ console.log(where);
428
+
429
+ //const srcPath = this.#getSourcePath(where.menu.url);
430
+
431
+ console.log(srcPath);
432
+
433
+ const columnInfo = await this.#getColumnInfo(where.table);
434
+
435
+ let mybatisXmlSource;
436
+ if (apply.mybatis) {
437
+ mybatisXmlSource = await this.#generateTmplFile("/prompts/meta/U.BuildMyBatisMapper.txt", "mybatis.xml", {
438
+ userPrompt: userPrompt,
439
+ originSrc: src.mybatis,
440
+ resultType: srcPath.resultType,
441
+ namespace: srcPath.namespace,
442
+ tableDefinitions: JSON.stringify(columnInfo),
443
+ });
444
+ //this.#parent.addMessage("MyBatis 소스파일을 생성했습니다.");
445
+ progressMessageInstance.updateProgress('mybatis', 'completed');
446
+ }
447
+ else {
448
+ mybatisXmlSource = src.mybatis;
449
+ }
450
+
451
+ let serviceSrc;
452
+ if (apply.service) {
453
+ serviceSrc = await this.#generateTmplFile("/prompts/meta/U.BuildService.txt", "service.java", {
454
+ userPrompt: userPrompt,
455
+ originSrc: src.service,
456
+ baseClass: srcPath.baseClass,
457
+ myBatisPath: srcPath.mybatis,
458
+ namespace: srcPath.namespace,
459
+ package: srcPath.package + ".service",
460
+ mybatisXmlSource: mybatisXmlSource,
461
+ });
462
+ //this.#parent.addMessage("Java(Service) 소스파일을 생성했습니다.");
463
+ progressMessageInstance.updateProgress('service', 'completed');
464
+ }
465
+ else {
466
+ serviceSrc = src.service;
467
+ }
468
+
469
+ let controllerSrc;
470
+ if (apply.controller) {
471
+ controllerSrc = await this.#generateTmplFile("/prompts/meta/U.BuildController.txt", "controller.java", {
472
+ userPrompt: userPrompt,
473
+ originSrc: src.controller,
474
+ baseClass: srcPath.baseClass,
475
+ menuUrl: where.menu.url,
476
+ package: srcPath.package + ".controller",
477
+ serviceSource: serviceSrc,
478
+ });
479
+ //this.#parent.addMessage("Java(Controller) 소스파일을 생성했습니다.");
480
+ progressMessageInstance.updateProgress('controller', 'completed');
481
+ }
482
+ else {
483
+ controllerSrc = src.controller;
484
+ }
485
+
486
+ let jsSrc;
487
+ if (apply.javascript) {
488
+ jsSrc = await this.#generateTmplFile("/prompts/meta/U.BuildReactJsx.txt", "react.jsx", {
489
+ userPrompt: userPrompt,
490
+ mybatis: srcPath.mybatis,
491
+ originSrc: src.javascript,
492
+ menuUrl: where.menu.url,
493
+ menuName: where.menu.name,
494
+ baseClass: srcPath.baseClass,
495
+ mybatisXmlSource: mybatisXmlSource,
496
+ controllerSource: controllerSrc,
497
+ tableDefinitions: JSON.stringify(columnInfo),
498
+ });
499
+ //this.#parent.addMessage("Jsx(React) 소스파일을 생성했습니다.");
500
+ progressMessageInstance.updateProgress('javascript', 'completed');
501
+ }
502
+ else {
503
+ jsSrc = src.javascript;
504
+ }
505
+
506
+ //await this.#generateRealFile(srcPath, apply);
507
+
508
+ const returnSrc = [];
509
+
510
+ const mapping = {
511
+ mybatis: {
512
+ path: srcPath.mybatisPullPath,
513
+ src: mybatisXmlSource,
514
+ },
515
+ service: {
516
+ path: srcPath.servicePullPath,
517
+ src: serviceSrc,
518
+ },
519
+ controller: {
520
+ path: srcPath.controllerPullPath,
521
+ src: controllerSrc,
522
+ },
523
+ javascript: {
524
+ path: srcPath.javascriptPullPath,
525
+ src: jsSrc,
526
+ }
527
+ };
528
+
529
+ for (const key in apply) {
530
+ if (apply[key]) {
531
+ returnSrc.push({
532
+ [key]: {
533
+ asis: src[key],
534
+ tobe: mapping[key].src,
535
+ tobePath: mapping[key].path,
536
+ }
537
+ });
538
+ }
539
+ }
540
+
541
+ console.log(returnSrc);
542
+
543
+ return returnSrc;
544
+ };
545
+
546
+ #generateSource = async (what, userPrompt, apply, progressMessageInstance) => {
547
+
548
+ /**
549
+ const el = ninegrid.querySelector("nx-side-menu-item.active");
550
+ if (!el) throw new Error("관련 메뉴를 찾을 수 없습니다.");
551
+
552
+ const href = el.getAttribute("href");
553
+ const title = el.getAttribute("title");
554
+
555
+ console.log(el, href, title);
556
+
557
+ const srcPath = this.#getSourcePath(href);
558
+ console.log(srcPath);
559
+ */
560
+
561
+ let where;
562
+ let href;
563
+
564
+ if (what === "C1") {
565
+ where = await this.#where(userPrompt, this.#getMenuInfo(), await this.#getTableList());
566
+ href = where.menu.url;
567
+ }
568
+ else if (what === "U1") {
569
+ const el = ninegrid.querySelector("nx-side-menu-item.active");
570
+ if (!el) throw new Error("관련 메뉴를 찾을 수 없습니다.");
571
+
572
+ href = el.getAttribute("href");
573
+ const title = el.getAttribute("title");
574
+
575
+ where = await this.#where(`${title}에서 ${userPrompt}`, [{url: href, title: title}], await this.#getTableList());
576
+ }
577
+ else {
578
+ throw new Error("invalid command type.");
579
+ }
580
+
581
+ const srcPath = this.#getSourcePath(href);
582
+ console.log(where, srcPath);
583
+
584
+ const src = await api.post("/api/source/read", srcPath);
585
+ console.log(src);
586
+
587
+ progressMessageInstance.updateProgress('prepare2', 'completed');
588
+
589
+
590
+ const columnInfo = await this.#getColumnInfo(where.table);
591
+
592
+ let generatedSource = {
593
+ mybatis: src.mybatis,
594
+ service: src.service,
595
+ controller: src.controller,
596
+ javascriptFrom: src.javascriptFrom,
597
+ javascriptTo: src.javascriptTo,
598
+ };
599
+
600
+ if (apply.mybatis) {
601
+ generatedSource.mybatis = await this.#generateTmplFile("/prompts/meta/U.BuildMyBatisMapper.txt", "mybatis.xml", {
602
+ userPrompt: userPrompt,
603
+ originSrc: src.mybatis,
604
+ resultType: srcPath.resultType,
605
+ namespace: srcPath.namespace,
606
+ tableDefinitions: JSON.stringify(columnInfo),
607
+ });
608
+ //this.#parent.addMessage("MyBatis 소스파일을 생성했습니다.");
609
+ progressMessageInstance.updateProgress('mybatis', 'completed');
610
+ }
611
+
612
+ if (apply.service) {
613
+ generatedSource.service = await this.#generateTmplFile("/prompts/meta/U.BuildService.txt", "service.java", {
614
+ userPrompt: userPrompt,
615
+ originSrc: src.service,
616
+ baseClass: srcPath.baseClass,
617
+ myBatisPath: srcPath.mybatis,
618
+ namespace: srcPath.namespace,
619
+ package: srcPath.package + ".service",
620
+ mybatisXmlSource: generatedSource.mybatis,
621
+ });
622
+ //this.#parent.addMessage("Java(Service) 소스파일을 생성했습니다.");
623
+ progressMessageInstance.updateProgress('service', 'completed');
624
+ }
625
+
626
+ if (apply.controller) {
627
+ generatedSource.controller = await this.#generateTmplFile("/prompts/meta/U.BuildController.txt", "controller.java", {
628
+ userPrompt: userPrompt,
629
+ originSrc: src.controller,
630
+ baseClass: srcPath.baseClass,
631
+ menuUrl: where.menu.url,
632
+ package: srcPath.package + ".controller",
633
+ serviceSource: generatedSource.service,
634
+ });
635
+ //this.#parent.addMessage("Java(Controller) 소스파일을 생성했습니다.");
636
+ progressMessageInstance.updateProgress('controller', 'completed');
637
+ }
638
+
639
+ if (apply.javascript) {
640
+ generatedSource.javascriptFrom = await this.#generateTmplFile(this.prompt.react.filter(item => item.includes(".main.") || item.includes(".all.")), "react.jsx", {
641
+ userPrompt: userPrompt,
642
+ mybatis: srcPath.mybatis,
643
+ originSrc: src.javascriptFrom,
644
+ menuUrl: where.menu.url,
645
+ menuName: where.menu.name,
646
+ baseClass: srcPath.baseClass,
647
+ mybatisXmlSource: generatedSource.mybatis,
648
+ controllerSource: generatedSource.controller,
649
+ tableDefinitions: JSON.stringify(columnInfo),
650
+ });
651
+ //this.#parent.addMessage("Jsx(React) 소스파일을 생성했습니다.");
652
+ progressMessageInstance.updateProgress('javascript', 'completed');
653
+ }
654
+
655
+ //await this.#generateRealFile(srcPath, apply);
656
+
657
+ const returnSrc = [];
658
+
659
+ const mapping = {
660
+ mybatis: {
661
+ path: srcPath.mybatisPullPath,
662
+ src: generatedSource.mybatis,
663
+ },
664
+ service: {
665
+ path: srcPath.servicePullPath,
666
+ src: generatedSource.service,
667
+ },
668
+ controller: {
669
+ path: srcPath.controllerPullPath,
670
+ src: generatedSource.controller,
671
+ },
672
+ javascriptFrom: {
673
+ path: srcPath.javascriptFrom,
674
+ src: generatedSource.javascriptFrom,
675
+ },
676
+ javascriptTo: {
677
+ path: srcPath.javascriptTo,
678
+ src: generatedSource.javascriptTo,
679
+ },
680
+ };
681
+
682
+ if (apply.javascript) {
683
+ apply.javascriptFrom = true;
684
+ apply.javascriptTo = true;
685
+ apply.javascript = false;
686
+ }
687
+
688
+ for (const key in apply) {
689
+ if (apply[key] && mapping[key].src) {
690
+ returnSrc.push({
691
+ [key]: {
692
+ asis: src[key],
693
+ tobe: mapping[key].src,
694
+ tobePath: mapping[key].path,
695
+ }
696
+ });
697
+ }
698
+ }
699
+
700
+ console.log(returnSrc);
701
+
702
+ return returnSrc;
703
+ };
704
+
705
+ #generateListSource = async (userPrompt, apply, progressMessageInstance) => {
706
+
707
+ /**
708
+ const el = ninegrid.querySelector("nx-side-menu-item.active");
709
+ if (!el) throw new Error("관련 메뉴를 찾을 수 없습니다.");
710
+
711
+ const href = el.getAttribute("href");
712
+ const title = el.getAttribute("title");
713
+
714
+ console.log(el, href, title);
715
+
716
+ const srcPath = this.#getSourcePath(href);
717
+ console.log(srcPath);
718
+ */
719
+
720
+
721
+ const where = await this.#where(userPrompt, this.#getMenuInfo(), await this.#getTableList());
722
+ //this.#parent.addMessage("대상 메뉴와 테이블을 찾았습니다.")
723
+
724
+ console.log(where);
725
+
726
+ const srcPath = this.#getSourcePath(where.menu.url);
727
+ console.log(srcPath);
728
+
729
+
730
+ /**
731
+ * {
732
+ * "package": "ide.assi.be.tmpla",
733
+ * "namespace": "ide.assi.be.tmpla.docmanager",
734
+ * "baseClass": "DocManager",
735
+ * "resultType": "ide.assi.core.utils.CamelCaseMap",
736
+ * "mybatis": "tmpla/DocManagerMapper.xml",
737
+ * "mybatisPullPath": "ide-assi-be/src/main/resources/mapper/tmpla/DocManagerMapper.xml",
738
+ * "controllerPullPath": "ide-assi-be/src/main/java/ide/assi/be/tmpla/controller/DocManagerController.java",
739
+ * "servicePullPath": "ide-assi-be/src/main/java/ide/assi/be/tmpla/service/DocManagerService.java",
740
+ * "javascriptPullPath": "ide-assi-fe-vite-react-js/src/views/tmpla/doc-manager.jsx"
741
+ * }
742
+ */
743
+ const src = await api.post("/api/source/read", srcPath);
744
+ //console.log(src);
745
+
746
+ /**
747
+ const response = await fetch(srcPath.javascript);
748
+ src.javascript = await response.text();*/
749
+
750
+ //console.log(src);
751
+ //const template = await fetch(path).then(res => res.text());
752
+ /*
753
+ arr.push({
754
+ //menuId: elem.getAttribute("menu-id"),
755
+ url: elem.getAttribute("href"),
756
+ title: elem.getAttribute("title"),
757
+ })*/
758
+
759
+
760
+
761
+
762
+
763
+ //const where = await this.#where(`${title}에서 ${userPrompt}`, [{url: href, title: title}], await this.#getTableList());
764
+ //this.#parent.addMessage("대상 메뉴와 테이블을 찾았습니다.");
765
+ progressMessageInstance.updateProgress('prepare2', 'completed');
766
+
767
+ //console.log(where);
768
+
769
+ //const srcPath = this.#getSourcePath(where.menu.url);
770
+
771
+
772
+
773
+ const columnInfo = await this.#getColumnInfo(where.table);
774
+
775
+ let mybatisXmlSource;
776
+ if (apply.mybatis) {
777
+ mybatisXmlSource = await this.#generateTmplFile("/prompts/meta/U.BuildMyBatisMapper.txt", "mybatis.xml", {
778
+ userPrompt: userPrompt,
779
+ originSrc: src.mybatis,
780
+ resultType: srcPath.resultType,
781
+ namespace: srcPath.namespace,
782
+ tableDefinitions: JSON.stringify(columnInfo),
783
+ });
784
+ //this.#parent.addMessage("MyBatis 소스파일을 생성했습니다.");
785
+ progressMessageInstance.updateProgress('mybatis', 'completed');
786
+ }
787
+ else {
788
+ mybatisXmlSource = src.mybatis;
789
+ }
790
+
791
+ let serviceSrc;
792
+ if (apply.service) {
793
+ serviceSrc = await this.#generateTmplFile("/prompts/meta/U.BuildService.txt", "service.java", {
794
+ userPrompt: userPrompt,
795
+ originSrc: src.service,
796
+ baseClass: srcPath.baseClass,
797
+ myBatisPath: srcPath.mybatis,
798
+ namespace: srcPath.namespace,
799
+ package: srcPath.package + ".service",
800
+ mybatisXmlSource: mybatisXmlSource,
801
+ });
802
+ //this.#parent.addMessage("Java(Service) 소스파일을 생성했습니다.");
803
+ progressMessageInstance.updateProgress('service', 'completed');
804
+ }
805
+ else {
806
+ serviceSrc = src.service;
807
+ }
808
+
809
+ let controllerSrc;
810
+ if (apply.controller) {
811
+ controllerSrc = await this.#generateTmplFile("/prompts/meta/U.BuildController.txt", "controller.java", {
812
+ userPrompt: userPrompt,
813
+ originSrc: src.controller,
814
+ baseClass: srcPath.baseClass,
815
+ menuUrl: where.menu.url,
816
+ package: srcPath.package + ".controller",
817
+ serviceSource: serviceSrc,
818
+ });
819
+ //this.#parent.addMessage("Java(Controller) 소스파일을 생성했습니다.");
820
+ progressMessageInstance.updateProgress('controller', 'completed');
821
+ }
822
+ else {
823
+ controllerSrc = src.controller;
824
+ }
825
+
826
+ let jsSrc;
827
+ if (apply.javascript) {
828
+ jsSrc = await this.#generateTmplFile(this.prompt.react.filter(item => item.includes(".main.") || item.includes(".all.")), "react.jsx", {
829
+ userPrompt: userPrompt,
830
+ mybatis: srcPath.mybatis,
831
+ originSrc: src.javascript,
832
+ menuUrl: where.menu.url,
833
+ menuName: where.menu.name,
834
+ baseClass: srcPath.baseClass,
835
+ mybatisXmlSource: mybatisXmlSource,
836
+ controllerSource: controllerSrc,
837
+ tableDefinitions: JSON.stringify(columnInfo),
838
+ });
839
+ //this.#parent.addMessage("Jsx(React) 소스파일을 생성했습니다.");
840
+ progressMessageInstance.updateProgress('javascript', 'completed');
841
+ }
842
+ else {
843
+ jsSrc = src.javascript;
844
+ }
845
+
846
+ //await this.#generateRealFile(srcPath, apply);
847
+
848
+ const returnSrc = [];
849
+
850
+ const mapping = {
851
+ mybatis: {
852
+ path: srcPath.mybatisPullPath,
853
+ src: mybatisXmlSource,
854
+ },
855
+ service: {
856
+ path: srcPath.servicePullPath,
857
+ src: serviceSrc,
858
+ },
859
+ controller: {
860
+ path: srcPath.controllerPullPath,
861
+ src: controllerSrc,
862
+ },
863
+ javascript: {
864
+ path: srcPath.javascriptPullPath,
865
+ src: jsSrc,
866
+ }
867
+ };
868
+
869
+ for (const key in apply) {
870
+ if (apply[key]) {
871
+ returnSrc.push({
872
+ [key]: {
873
+ asis: src[key],
874
+ tobe: mapping[key].src,
875
+ tobePath: mapping[key].path,
876
+ }
877
+ });
878
+ }
879
+ }
880
+
881
+ console.log(returnSrc);
882
+
883
+ return returnSrc;
884
+ };
885
+
886
+ #generateDetailSource = async (userPrompt, apply, progressMessageInstance) => {
887
+
888
+ const el = ninegrid.querySelector("nx-side-menu-item.active");
889
+ if (!el) throw new Error("관련 메뉴를 찾을 수 없습니다.");
890
+
891
+ const href = el.getAttribute("href");
892
+ const title = el.getAttribute("title");
893
+
894
+ //console.log(el, href, title);
895
+
896
+ const srcPath = this.#getSourcePath(href);
897
+ console.log(srcPath);
898
+
899
+
900
+ /**
901
+ * {
902
+ * "package": "ide.assi.be.tmpla",
903
+ * "namespace": "ide.assi.be.tmpla.docmanager",
904
+ * "baseClass": "DocManager",
905
+ * "resultType": "ide.assi.core.utils.CamelCaseMap",
906
+ * "mybatis": "tmpla/DocManagerMapper.xml",
907
+ * "mybatisPullPath": "ide-assi-be/src/main/resources/mapper/tmpla/DocManagerMapper.xml",
908
+ * "controllerPullPath": "ide-assi-be/src/main/java/ide/assi/be/tmpla/controller/DocManagerController.java",
909
+ * "servicePullPath": "ide-assi-be/src/main/java/ide/assi/be/tmpla/service/DocManagerService.java",
910
+ * "javascriptPullPath": "ide-assi-fe-vite-react-js/src/views/tmpla/doc-manager.jsx"
911
+ * }
912
+ */
913
+ const src = await api.post("/api/source/read", srcPath);
914
+ //console.log(src);
915
+
916
+ /**
917
+ const response = await fetch(srcPath.javascript);
918
+ src.javascript = await response.text();*/
919
+
920
+ //console.log(src);
921
+ //const template = await fetch(path).then(res => res.text());
922
+ /*
923
+ arr.push({
924
+ //menuId: elem.getAttribute("menu-id"),
925
+ url: elem.getAttribute("href"),
926
+ title: elem.getAttribute("title"),
927
+ })*/
928
+
929
+
930
+
931
+
932
+
933
+ const where = await this.#where(`${title}에서 ${userPrompt}`, [{url: href, title: title}], await this.#getTableList());
934
+ //this.#parent.addMessage("대상 메뉴와 테이블을 찾았습니다.");
935
+ progressMessageInstance.updateProgress('prepare2', 'completed');
936
+
937
+ console.log(where);
938
+
939
+ //const srcPath = this.#getSourcePath(where.menu.url);
940
+ console.log(srcPath);
941
+
942
+ const columnInfo = await this.#getColumnInfo(where.table);
943
+
944
+ let mybatisXmlSource;
945
+ if (apply.mybatis) {
946
+ mybatisXmlSource = await this.#generateTmplFile("/prompts/meta/U.BuildMyBatisMapper.txt", "mybatis.xml", {
947
+ userPrompt: userPrompt,
948
+ originSrc: src.mybatis,
949
+ resultType: srcPath.resultType,
950
+ namespace: srcPath.namespace,
951
+ tableDefinitions: JSON.stringify(columnInfo),
952
+ });
953
+ //this.#parent.addMessage("MyBatis 소스파일을 생성했습니다.");
954
+ progressMessageInstance.updateProgress('mybatis', 'completed');
955
+ }
956
+ else {
957
+ mybatisXmlSource = src.mybatis;
958
+ }
959
+
960
+ let serviceSrc;
961
+ if (apply.service) {
962
+ serviceSrc = await this.#generateTmplFile("/prompts/meta/U.BuildService.txt", "service.java", {
963
+ userPrompt: userPrompt,
964
+ originSrc: src.service,
965
+ baseClass: srcPath.baseClass,
966
+ myBatisPath: srcPath.mybatis,
967
+ namespace: srcPath.namespace,
968
+ package: srcPath.package + ".service",
969
+ mybatisXmlSource: mybatisXmlSource,
970
+ });
971
+ //this.#parent.addMessage("Java(Service) 소스파일을 생성했습니다.");
972
+ progressMessageInstance.updateProgress('service', 'completed');
973
+ }
974
+ else {
975
+ serviceSrc = src.service;
976
+ }
977
+
978
+ let controllerSrc;
979
+ if (apply.controller) {
980
+ controllerSrc = await this.#generateTmplFile("/prompts/meta/U.BuildController.txt", "controller.java", {
981
+ userPrompt: userPrompt,
982
+ originSrc: src.controller,
983
+ baseClass: srcPath.baseClass,
984
+ menuUrl: where.menu.url,
985
+ package: srcPath.package + ".controller",
986
+ serviceSource: serviceSrc,
987
+ });
988
+ //this.#parent.addMessage("Java(Controller) 소스파일을 생성했습니다.");
989
+ progressMessageInstance.updateProgress('controller', 'completed');
990
+ }
991
+ else {
992
+ controllerSrc = src.controller;
993
+ }
994
+
995
+ console.log("=---------", src.javascript2);
996
+
997
+ let jsSrcFrom;
998
+ let jsSrcTo;
999
+ if (apply.javascript) {
1000
+ const pathArray = srcPath.javascriptTo.split("/");
1001
+ const javascriptFileTo = pathArray.pop();
1002
+
1003
+ jsSrcFrom = await this.#generateTmplFile("/prompts/meta/detail/4.BuildReactJsx_Link.txt", "reactFrom.jsx", {
1004
+ userPrompt: userPrompt,
1005
+ mybatis: srcPath.mybatis,
1006
+ originSrc: src.javascript2,
1007
+ menuUrl: where.menu.url,
1008
+ menuName: where.menu.name,
1009
+ baseClass: srcPath.baseClass,
1010
+ classFrom: srcPath.classFrom,
1011
+ classTo: srcPath.classTo,
1012
+ emptyIndex: srcPath.emptyIndex,
1013
+ activeIndex: srcPath.activeIndex,
1014
+ javascriptFileTo: javascriptFileTo,
1015
+ mybatisXmlSource: mybatisXmlSource,
1016
+ controllerSource: controllerSrc,
1017
+ tableDefinitions: JSON.stringify(columnInfo),
1018
+ });
1019
+ //this.#parent.addMessage("Jsx(React) 소스파일을 생성했습니다.");
1020
+ //progressMessageInstance.updateProgress('javascript', 'completed');
1021
+
1022
+ jsSrcTo = await this.#generateTmplFile("/prompts/meta/detail/4.BuildReactJsx_Detail.txt", "reactTo.jsx", {
1023
+ userPrompt: userPrompt,
1024
+ mybatis: srcPath.mybatis,
1025
+ originSrc: src.javascript,
1026
+ menuUrl: where.menu.url,
1027
+ menuName: where.menu.name,
1028
+ baseClass: srcPath.baseClass,
1029
+ className: srcPath.classTo,
1030
+ emptyIndex: srcPath.emptyIndex,
1031
+ activeIndex: srcPath.activeIndex,
1032
+ mybatisXmlSource: mybatisXmlSource,
1033
+ controllerSource: controllerSrc,
1034
+ tableDefinitions: JSON.stringify(columnInfo),
1035
+ });
1036
+ //this.#parent.addMessage("Jsx(React) 소스파일을 생성했습니다.");
1037
+ progressMessageInstance.updateProgress('javascript', 'completed');
1038
+ /**
1039
+ jsSrc = await this.#generateTmplFile("/prompts/meta/detail/4.BuildReactJsx_Detail.txt", "react2.jsx", {
1040
+ userPrompt: userPrompt,
1041
+ mybatis: srcPath.mybatis,
1042
+ originSrc: "", //src.javascript,
1043
+ menuUrl: where.menu.url,
1044
+ menuName: where.menu.name,
1045
+ baseClass: srcPath.baseClass,
1046
+ mybatisXmlSource: mybatisXmlSource,
1047
+ controllerSource: controllerSrc,
1048
+ tableDefinitions: JSON.stringify(columnInfo),
1049
+ });
1050
+ //this.#parent.addMessage("Jsx(React) 소스파일을 생성했습니다.");
1051
+ progressMessageInstance.updateProgress('javascript', 'completed');
1052
+ */
1053
+ }
1054
+ else {
1055
+ jsSrcTo = src.javascriptTo;
1056
+ }
1057
+
1058
+ //await this.#generateRealFile(srcPath, apply);
1059
+
1060
+ const returnSrc = [];
1061
+
1062
+ const mapping = {
1063
+ mybatis: {
1064
+ path: srcPath.mybatisPullPath,
1065
+ src: mybatisXmlSource,
1066
+ },
1067
+ service: {
1068
+ path: srcPath.servicePullPath,
1069
+ src: serviceSrc,
1070
+ },
1071
+ controller: {
1072
+ path: srcPath.controllerPullPath,
1073
+ src: controllerSrc,
1074
+ },
1075
+ javascript: {
1076
+ path: srcPath.javascriptToPullPath,
1077
+ src: jsSrcTo,
1078
+ },
1079
+ javascript2: {
1080
+ path: srcPath.javascriptFromPullPath,
1081
+ src: jsSrcFrom,
1082
+ },
1083
+ };
1084
+
1085
+ //console.log(srcPath.javascriptToPullPath, jsSrcTo);
1086
+
1087
+ if (apply.javascript) {
1088
+ apply.javascript2 = true;
1089
+ }
1090
+
1091
+ //console.log(apply);
1092
+
1093
+ for (const key in apply) {
1094
+ if (apply[key]) {
1095
+ returnSrc.push({
1096
+ [key]: {
1097
+ asis: src[key],
1098
+ tobe: mapping[key].src,
1099
+ tobePath: mapping[key].path,
1100
+ }
1101
+ });
1102
+ }
1103
+ }
1104
+
1105
+ console.log(returnSrc);
1106
+
1107
+ return returnSrc;
1108
+ };
1109
+
1110
+ #modifyDetailSource = async (userPrompt, apply, progressMessageInstance) => {
1111
+
1112
+ const el = ninegrid.querySelector("nx-side-menu-item.active");
1113
+ if (!el) throw new Error("관련 메뉴를 찾을 수 없습니다.");
1114
+
1115
+ const href = el.getAttribute("href");
1116
+ const title = el.getAttribute("title");
1117
+
1118
+ //console.log(el, href, title);
1119
+
1120
+ const srcPath = this.#getSourcePath(href);
1121
+ console.log(srcPath);
1122
+
1123
+ const src = await api.post("/api/source/read", srcPath);
1124
+
1125
+ const where = await this.#where(`${title}에서 ${userPrompt}`, [{url: href, title: title}], await this.#getTableList());
1126
+ //this.#parent.addMessage("대상 메뉴와 테이블을 찾았습니다.");
1127
+ progressMessageInstance.updateProgress('prepare2', 'completed');
1128
+
1129
+ console.log(where);
1130
+
1131
+ //const srcPath = this.#getSourcePath(where.menu.url);
1132
+ console.log(srcPath);
1133
+
1134
+ const columnInfo = await this.#getColumnInfo(where.table);
1135
+
1136
+ let mybatisXmlSource;
1137
+ if (apply.mybatis) {
1138
+ mybatisXmlSource = await this.#generateTmplFile("/prompts/meta/U.BuildMyBatisMapper.txt", "mybatis.xml", {
1139
+ userPrompt: userPrompt,
1140
+ originSrc: src.mybatis,
1141
+ resultType: srcPath.resultType,
1142
+ namespace: srcPath.namespace,
1143
+ tableDefinitions: JSON.stringify(columnInfo),
1144
+ });
1145
+ //this.#parent.addMessage("MyBatis 소스파일을 생성했습니다.");
1146
+ progressMessageInstance.updateProgress('mybatis', 'completed');
1147
+ }
1148
+ else {
1149
+ mybatisXmlSource = src.mybatis;
1150
+ }
1151
+
1152
+ let serviceSrc;
1153
+ if (apply.service) {
1154
+ serviceSrc = await this.#generateTmplFile("/prompts/meta/U.BuildService.txt", "service.java", {
1155
+ userPrompt: userPrompt,
1156
+ originSrc: src.service,
1157
+ baseClass: srcPath.baseClass,
1158
+ myBatisPath: srcPath.mybatis,
1159
+ namespace: srcPath.namespace,
1160
+ package: srcPath.package + ".service",
1161
+ mybatisXmlSource: mybatisXmlSource,
1162
+ });
1163
+ //this.#parent.addMessage("Java(Service) 소스파일을 생성했습니다.");
1164
+ progressMessageInstance.updateProgress('service', 'completed');
1165
+ }
1166
+ else {
1167
+ serviceSrc = src.service;
1168
+ }
1169
+
1170
+ let controllerSrc;
1171
+ if (apply.controller) {
1172
+ controllerSrc = await this.#generateTmplFile("/prompts/meta/U.BuildController.txt", "controller.java", {
1173
+ userPrompt: userPrompt,
1174
+ originSrc: src.controller,
1175
+ baseClass: srcPath.baseClass,
1176
+ menuUrl: where.menu.url,
1177
+ package: srcPath.package + ".controller",
1178
+ serviceSource: serviceSrc,
1179
+ });
1180
+ //this.#parent.addMessage("Java(Controller) 소스파일을 생성했습니다.");
1181
+ progressMessageInstance.updateProgress('controller', 'completed');
1182
+ }
1183
+ else {
1184
+ controllerSrc = src.controller;
1185
+ }
1186
+
1187
+ console.log("=---------", src.javascript2);
1188
+
1189
+ let jsSrcFrom;
1190
+ if (apply.javascript) {
1191
+ jsSrcFrom = await this.#generateTmplFile("/prompts/meta/detail/4.BuildReactJsx_Detail.txt", "reactTo.jsx", {
1192
+ userPrompt: userPrompt,
1193
+ mybatis: srcPath.mybatis,
1194
+ originSrc: src.javascriptFrom,
1195
+ menuUrl: where.menu.url,
1196
+ menuName: where.menu.name,
1197
+ baseClass: srcPath.baseClass,
1198
+ className: srcPath.classFrom,
1199
+ emptyIndex: srcPath.emptyIndex,
1200
+ activeIndex: srcPath.activeIndex,
1201
+ mybatisXmlSource: mybatisXmlSource,
1202
+ controllerSource: controllerSrc,
1203
+ tableDefinitions: JSON.stringify(columnInfo),
1204
+ });
1205
+ //this.#parent.addMessage("Jsx(React) 소스파일을 생성했습니다.");
1206
+ progressMessageInstance.updateProgress('javascript', 'completed');
1207
+ }
1208
+ else {
1209
+ jsSrcFrom = src.javascriptTo;
1210
+ }
1211
+
1212
+ //await this.#generateRealFile(srcPath, apply);
1213
+
1214
+ const returnSrc = [];
1215
+
1216
+ const mapping = {
1217
+ mybatis: {
1218
+ path: srcPath.mybatisPullPath,
1219
+ src: mybatisXmlSource,
1220
+ },
1221
+ service: {
1222
+ path: srcPath.servicePullPath,
1223
+ src: serviceSrc,
1224
+ },
1225
+ controller: {
1226
+ path: srcPath.controllerPullPath,
1227
+ src: controllerSrc,
1228
+ },
1229
+ javascript: {
1230
+ path: srcPath.javascriptFromPullPath,
1231
+ src: jsSrcFrom,
1232
+ },
1233
+ };
1234
+
1235
+ //console.log(srcPath.javascriptToPullPath, jsSrcTo);
1236
+
1237
+ //console.log(apply);
1238
+ src.javascript = src.javascriptFrom;
1239
+
1240
+ for (const key in apply) {
1241
+ if (apply[key]) {
1242
+ returnSrc.push({
1243
+ [key]: {
1244
+ asis: src[key],
1245
+ tobe: mapping[key].src,
1246
+ tobePath: mapping[key].path,
1247
+ }
1248
+ });
1249
+ }
1250
+ }
1251
+
1252
+ console.log(returnSrc);
1253
+
1254
+ return returnSrc;
1255
+ };
1256
+
1257
+ generateSourceClient = async (userPrompt, apply) => {
1258
+
1259
+ this.#createModel();
1260
+
1261
+ const initialProgressData = [
1262
+ { id: 'prepare1', message: '명령을 해석중입니다.', completedMessage: '명령을 해석했습니다.' },
1263
+ { id: 'prepare2', message: '메뉴와 테이블을 검색중입니다.', completedMessage: '관련 메뉴와 테이블을 찾았습니다.' },
1264
+ ];
1265
+ if (apply.mybatis) {
1266
+ initialProgressData.push({ id: 'mybatis', message: 'MyBatis 소스를 생성중입니다.', completedMessage: 'MyBatis 소스를 생성했습니다.' });
1267
+ }
1268
+ if (apply.service) {
1269
+ initialProgressData.push({ id: 'service', message: 'Java(Service) 소스를 생성중입니다.', completedMessage: 'Java(Service) 소스를 생성했습니다.' });
1270
+ }
1271
+ if (apply.controller) {
1272
+ initialProgressData.push({ id: 'controller', message: 'Java(Controller) 소스를 생성중입니다.', completedMessage: 'Java(Controller) 소스를 생성했습니다.' });
1273
+ }
1274
+ if (apply.javascript) {
1275
+ initialProgressData.push({ id: 'javascript', message: 'Jsx(React) 소스를 생성중입니다.', completedMessage: 'Jsx(React) 소스를 생성했습니다.' });
1276
+ }
1277
+
1278
+ const elAiChat = this.#parent.shadowRoot.querySelector("nx-ai-chat");
1279
+ const progressMessageInstance = elAiChat.addProgress(initialProgressData);
1280
+
1281
+ const what = await this.#what(userPrompt);
1282
+ //this.#parent.addMessage("명령을 이해했습니다.");
1283
+ progressMessageInstance.updateProgress('prepare1', 'completed');
1284
+
1285
+ if (what === "C1") {
1286
+ if (!apply.mybatis || !apply.service || !apply.controller || !apply.javascript) {
1287
+ //return "소스 생성하실려면 변경대상 소스를 모두 선택하세요.";
1288
+ }
1289
+ //await this.#createSource(userPrompt, apply);
1290
+ //return await this.#modifySource(userPrompt, apply, progressMessageInstance);
1291
+ return await this.#generateSource(what, userPrompt, apply, progressMessageInstance);
1292
+ }
1293
+ else if (what === "C2") {
1294
+ if (!apply.mybatis || !apply.service || !apply.controller || !apply.javascript) {
1295
+ //return "소스 생성하실려면 변경대상 소스를 모두 선택하세요.";
1296
+ }
1297
+ //await this.#createSource(userPrompt, apply);
1298
+ return await this.#generateDetailSource(userPrompt, apply, progressMessageInstance);
1299
+ }
1300
+ else if (what === "U1") {
1301
+ // .list-wrapper 또는 .detail-wrapper-* 중에서 .active 클래스를 가진 첫 번째 요소를 찾습니다.
1302
+ const el = document.querySelector(".list-wrapper.active");
1303
+
1304
+ if (el) {
1305
+ //return await this.#modifySource(userPrompt, apply, progressMessageInstance);
1306
+ return await this.#generateSource(what, userPrompt, apply, progressMessageInstance);
1307
+ }
1308
+ else {
1309
+ return await this.#modifyDetailSource(userPrompt, apply, progressMessageInstance);
1310
+ }
1311
+ }
1312
+ }
1313
+
1314
+ static generateWhereCause = async (xmlPath, queryId, userPrompt, apiKey) => {
1315
+
1316
+ const invoke = async (path, params) => {
1317
+ const prompt = await IdeUtils.generatePrompt(path, params);
1318
+ //console.log(prompt);
1319
+
1320
+ try {
1321
+ const model = new ChatGoogleGenerativeAI({ model: "gemini-2.5-flash", apiKey: apiKey, temperature: 0,});
1322
+
1323
+ const response = await model.invoke([
1324
+ //new SystemMessage(systemMessage),
1325
+ new HumanMessage(prompt),
1326
+ ]);
1327
+
1328
+ console.log(response);
1329
+
1330
+ let r = IdeUtils.extractResponse(response, "gemini");
1331
+
1332
+ /**
1333
+ if ((r.startsWith("'") && r.endsWith("'")) || (r.startsWith('"') && r.endsWith('"')) || (r.startsWith('`') && r.endsWith('`'))) {
1334
+ r = r.slice(1, -1); // 맨 앞, 맨 뒤 한 글자씩 제거
1335
+ } */
1336
+
1337
+
1338
+ return r;
1339
+ }
1340
+ catch (error) {
1341
+ throw error;
1342
+ }
1343
+ }
1344
+
1345
+ const res = await api.post("/api/source/query", {
1346
+ xmlPath: xmlPath,
1347
+ queryId: queryId
1348
+ });
1349
+
1350
+ //console.log(res.query);
1351
+
1352
+ if (res.query) {
1353
+ const o = await invoke('/prompts/user/generateWhereCause.txt', {
1354
+ "query": res.query,
1355
+ "userPrompt": userPrompt
1356
+ });
1357
+
1358
+ //console.log(o);
1359
+ /**
1360
+ if (Object.prototype.toString.call(o) === "[object Object]" && o.hasOwnProperty("result")) {
1361
+ if (o.result !== true) throw new Error(o.condition);
1362
+ }
1363
+ else {
1364
+ throw new Error(o);
1365
+ } */
1366
+
1367
+ return o;
1368
+
1369
+ /**
1370
+ const o = await invoke('/prompts/user/generateWhereCause.txt', {
1371
+ "query": res.query,
1372
+ "userPrompt": userPrompt
1373
+ });
1374
+
1375
+ //console.log(o);
1376
+
1377
+ return o;
1378
+ */
1379
+ }
1380
+
1381
+
1382
+ };
1383
+ }
1384
+