From 7d97628d385d67e4a094f01e3e6909ecf70d1631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=98=84=EC=84=B1=ED=95=84?= Date: Wed, 17 Apr 2024 22:03:02 +0900 Subject: [PATCH] =?UTF-8?q?Socket=20Client=20UI=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EA=B3=A8=EA=B2=A9=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ApiTestManager/src/APIClient.js | 84 ++- ApiTestManager/src/APITester.js | 573 +++--------------- .../src/components/HTTPClientView.js | 255 ++++++++ .../src/components/ServerManager.js | 44 ++ .../src/components/TCPClientView.js | 386 ++++++++++++ .../controller/ApiRequestMgmtController.java | 33 +- .../testmaster/client/dto/ApiLayoutDTO.java | 167 +++++ .../client/dto/ApiLayoutItemDTO.java | 275 +++++++++ .../testmaster/client/dto/ApiRequestDTO.java | 16 +- .../testmaster/client/entity/ApiLayout.java | 167 +++++ .../client/entity/ApiLayoutItem.java | 270 +++++++++ .../client/mapper/ApiLayoutItemMapper.java | 39 ++ .../client/mapper/ApiLayoutMapper.java | 60 ++ .../client/mapper/ApiRequestMapper.java | 43 +- .../repository/ApiLayoutItemRepository.java | 9 + .../repository/ApiLayoutRepository.java | 11 + .../client/service/ApiLayoutMgmtService.java | 86 +++ .../client/service/NettyTcpApiClient.java | 16 - .../internal/FixedLengthFrameDecoder.java | 25 + .../testmaster/server/dto/ServerDTO.java | 60 ++ .../testmaster/server/entity/Server.java | 67 +- .../server/mapper/ServerMapper.java | 12 + .../server/service/ServerMgmtService.java | 6 + src/main/resources/static/css/custom.css | 13 + .../plugins/apitestmanager/app.bundle.js | 39 +- .../templates/page/servers/serverEdit.html | 53 +- .../templates/page/servers/serverList.html | 5 +- 27 files changed, 2244 insertions(+), 570 deletions(-) create mode 100644 ApiTestManager/src/components/HTTPClientView.js create mode 100644 ApiTestManager/src/components/ServerManager.js create mode 100644 ApiTestManager/src/components/TCPClientView.js create mode 100644 src/main/java/com/eactive/testmaster/client/dto/ApiLayoutDTO.java create mode 100644 src/main/java/com/eactive/testmaster/client/dto/ApiLayoutItemDTO.java create mode 100644 src/main/java/com/eactive/testmaster/client/entity/ApiLayout.java create mode 100644 src/main/java/com/eactive/testmaster/client/entity/ApiLayoutItem.java create mode 100644 src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutItemMapper.java create mode 100644 src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutMapper.java create mode 100644 src/main/java/com/eactive/testmaster/client/repository/ApiLayoutItemRepository.java create mode 100644 src/main/java/com/eactive/testmaster/client/repository/ApiLayoutRepository.java create mode 100644 src/main/java/com/eactive/testmaster/client/service/ApiLayoutMgmtService.java create mode 100644 src/main/java/com/eactive/testmaster/client/service/internal/FixedLengthFrameDecoder.java diff --git a/ApiTestManager/src/APIClient.js b/ApiTestManager/src/APIClient.js index 99cc6bd..9abaed1 100644 --- a/ApiTestManager/src/APIClient.js +++ b/ApiTestManager/src/APIClient.js @@ -28,35 +28,6 @@ class APIClient { return this.contextPath + this.CLIENT_URL; } - async sendAPIRequest(model, preProcessCallback, consoleOutput) { - try { - let variables = {}; - const updatedModel = await this.executePreRequestScript(model, variables, consoleOutput); - let processedRequest = this.replacePlaceholdersWithVariables(updatedModel, variables); - - if (preProcessCallback) { - preProcessCallback(processedRequest); - } - const response = await this.makeAjaxRequest(processedRequest, model, consoleOutput); - const responseData = await response.json(); // Parse the JSON response - - if (!response.ok) { - const errorMessage = responseData.error || 'Unknown error'; - throw new Error(`API 호출 중 오류가 발생했습니다. 사유[${errorMessage}]`); - } - - const finalResponse = this.formatResponse(responseData); - return this.executePostRequestScript(model.postRequestScript, variables, processedRequest, finalResponse, consoleOutput).catch(error => { - $('.toast-body').text(error); - $('.toast').toast('show'); - return finalResponse; // Return the original response even if there's an error in the post-request script - }); - - } catch (error) { - throw error; - } - } - formatResponse(data) { // Format response as needed before post-request script let response = {}; @@ -99,6 +70,61 @@ class APIClient { } } + async processPreScriptAndVariables(model, value, consoleOutput){ + let variables = {}; + const updatedModel = await this.executePreRequestScript(model, variables, consoleOutput); + return this.replacePlaceholderValueWithVariables(updatedModel, value, variables); + } + + replacePlaceholderValueWithVariables(model, originalValue, variables) { + let mergedVariables = {}; + _.forEach(window.globals, (value, key) => { + mergedVariables[key] = value; + }); + + if (variables) { + _.forEach(variables, (value, key) => { + mergedVariables[key] = value; + }); + } + + _.forEach(mergedVariables, (value, key) => { + const placeholder = `{{${key}}}`; + // Replace in path + originalValue = originalValue.replace(new RegExp(placeholder, 'g'), value); + }); + return originalValue; + } + + async sendAPIRequest(model, preProcessCallback, consoleOutput) { + try { + let variables = {}; + const updatedModel = await this.executePreRequestScript(model, variables, consoleOutput); + let processedRequest = this.replacePlaceholdersWithVariables(updatedModel, variables); + + if (preProcessCallback) { + preProcessCallback(processedRequest); + } + const response = await this.makeAjaxRequest(processedRequest, model, consoleOutput); + const responseData = await response.json(); // Parse the JSON response + + if (!response.ok) { + const errorMessage = responseData.error || 'Unknown error'; + throw new Error(`API 호출 중 오류가 발생했습니다. 사유[${errorMessage}]`); + } + + const finalResponse = this.formatResponse(responseData); + return this.executePostRequestScript(model.postRequestScript, variables, processedRequest, finalResponse, consoleOutput).catch(error => { + $('.toast-body').text(error); + $('.toast').toast('show'); + return finalResponse; // Return the original response even if there's an error in the post-request script + }); + + } catch (error) { + throw error; + } + } + replacePlaceholdersWithVariables(original, variables) { let request = JSON.parse(JSON.stringify(original)); diff --git a/ApiTestManager/src/APITester.js b/ApiTestManager/src/APITester.js index 763ec9a..682c06b 100644 --- a/ApiTestManager/src/APITester.js +++ b/ApiTestManager/src/APITester.js @@ -1,9 +1,10 @@ import * as monaco from 'monaco-editor'; import APIClient from './APIClient'; -import EditableInput from './components/EditableInput'; import {createPopper} from '@popperjs/core/lib/popper-lite'; -import PropertyTable from './components/PropertyTable'; import VariableSnippet from './components/VariableSnippet'; +import HTTPClientView from './components/HTTPClientView'; +import TCPClientView from './components/TCPClientView'; +import ServerManager from './components/ServerManager'; class APITester { @@ -25,6 +26,7 @@ class APITester { this.popperContent = document.getElementById('popperContent'); this.popperInstance = null; this.contextPath = contextPath || '/'; + } getCollectionListURL() { @@ -51,281 +53,6 @@ class APITester { return this.contextPath + `mgmt/collections/${collectionId}/apis/delete.do`; } - renderServers(selectedServer) { - const optionsHtml = this.servers.map(server => ``).join(''); - - return ``; - } - - basePath(serverId) { - if (serverId === undefined || serverId === null || serverId === '') { - return ''; - } - return this.servers.filter(server => server.id == serverId)[0].basePath; // == : 타입 비교 없이 값만 비교 - } - - httpApiRequestTemplate(apiRequest, index) { - return ` -
-
${apiRequest.collectionName} > ${apiRequest.name}
-
-
- - -
-
- ${this.renderServers(apiRequest.server)} - -
-
- - -
-
- -
- - -
-
-
- -
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Response - - - -
- -
-
-
-
-
- - - - - - - - - -
이름
-
-
-
-
-
-
-
-
- - `; - } - - tcpApiRequestTemplate(apiRequest, index) { - return ` -
-
${apiRequest.collectionName} > ${apiRequest.name}
-
-
- ${this.renderServers(apiRequest.server)} - -
- - -
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Response - - - -
- -
-
-
-
-
-
-
-
-
-
-
- - `; - } - headerTemplate(header, index) { return ` @@ -402,6 +129,7 @@ class APITester { $('.toast').toast('show'); } } + this.serverManager = new ServerManager(this.servers); this.bindEvents(); this.loadCollections(); } @@ -424,8 +152,7 @@ class APITester { {selector: '.delete_api_request', action: this.showDeleteApiRequestModal.bind(this)}, {selector: '.open_api_request', action: this.openApiRequest.bind(this)}, {selector: '.confirm_delete_api', action: this.deleteApiRequest.bind(this)}, - {selector: '.close_tab', action: this.closeTab.bind(this)} - ]; + {selector: '.close_tab', action: this.closeTab.bind(this)}]; for (let event of events) { $(document).on('click', event.selector, event.action); @@ -601,7 +328,7 @@ class APITester { const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request')); let model = this.apiRequests[tabIndex]; let target = $('#api_request_' + model.id); - target.find('input[name="basePath"]').val(this.basePath(model.server)); + target.find('input[name="basePath"]').val(this.serverManager.basePath(model.server)); } renderHeaders(headers) { @@ -633,12 +360,10 @@ class APITester { placement: 'bottom', // Popper below the element modifiers: [ { - name: 'offset', - options: { + name: 'offset', options: { offset: [0, 8] // Adjust the position if needed } - } - ] + }] }); } @@ -655,87 +380,36 @@ class APITester { let apiRequestTabContent = $(this.apiTabContentTarget); let model = this.apiRequests[index]; - if (model.type ==='HTTP'){ - apiRequestTabContent.append(this.httpApiRequestTemplate(model, index)); - let editableInput = new EditableInput({ - name: 'path', - value: model.path - }); - - let queryParamTable = new PropertyTable({ - propertyName: 'queryParams', - properties: model.queryParams - }); - - let headerTable = new PropertyTable({ - propertyName: 'headers', - properties: model.headers - }); - - apiRequestTabContent.find(`#api_request_${model.id}`).find('.api_request_info').find('.path').each(function() { - editableInput.init(this, (value) => { - model.path = value; - model.queryParams = me.parseParam(model.path); - queryParamTable.setProperties(model.queryParams); - $('span.variable').off('mouseover'); - $('span.variable').off('mouseout'); - document.querySelectorAll('span.variable').forEach(element => { - let text = element.innerText; - element.addEventListener('mouseover', () => me.showPopper(element, text)); - element.addEventListener('mouseout', () => me.hidePopper(element)); - }); - }); - - $(this).append(``); - - $('span.variable').off('mouseover'); - $('span.variable').off('mouseout'); - }); - queryParamTable.init(apiRequestTabContent.find(`#api_request_${model.id}`).find('.query_params')[0], (properties) => { - model.queryParams = properties; - console.log(model.queryParams); - this.buildPath(model); - editableInput.setValue(model.path); - $('span.variable').off('mouseover'); - $('span.variable').off('mouseout'); - document.querySelectorAll('span.variable').forEach(element => { - let text = element.innerText; - element.addEventListener('mouseover', () => me.showPopper(element, text)); - element.addEventListener('mouseout', () => me.hidePopper(element)); - }); - }); - - headerTable.init(apiRequestTabContent.find(`#api_request_${model.id}`).find('.request_headers')[0], (properties) => { - model.headers = properties; - $('span.variable').off('mouseover'); - $('span.variable').off('mouseout'); - document.querySelectorAll('span.variable').forEach(element => { - let text = element.innerText; - element.addEventListener('mouseover', () => me.showPopper(element, text)); - element.addEventListener('mouseout', () => me.hidePopper(element)); - }); - }); - } - - if (model.type ==='TCP'){ - apiRequestTabContent.append(this.tcpApiRequestTemplate(model, index)); - } - document.querySelectorAll('.variable').forEach(element => { let text = element.innerText; element.addEventListener('mouseover', () => me.showPopper(element, text)); element.addEventListener('mouseout', () => me.hidePopper(element)); }); + let language = model.type === 'HTTP' ? 'json' : 'text'; - this.openTab(model.id); - let target = $('#api_request_' + model.id); - let language = model.type ==='TCP'? 'text': 'json'; + let target = null; + let requestBodyEditor = null; - let requestBodyEditor = monaco.editor.create(target.find('.request_body')[0], { - value: model.requestBody, - language: language, - automaticLayout: true - }); + if (model.type === 'HTTP') { + let httpClientView = new HTTPClientView(me, this.serverManager, apiRequestTabContent, model); + httpClientView.init(); + this.openTab(model.id); + target = $('#api_request_' + model.id); + requestBodyEditor = monaco.editor.create(target.find('.request_body')[0], { + value: model.requestBody, language: 'json', automaticLayout: true + }); + } + + if (model.type === 'TCP') { + const tcpClientView = new TCPClientView(me, this.serverManager, apiRequestTabContent, model); + tcpClientView.init(); + this.openTab(model.id); + target = $('#api_request_' + model.id); + requestBodyEditor = monaco.editor.create(target.find('.request_body')[0], { + value: model.requestBody, language: 'text', automaticLayout: false + }); + tcpClientView.setRequestBodyEditor(requestBodyEditor); + } requestBodyEditor.onMouseMove((e) => { let position = e.target.position; @@ -768,27 +442,19 @@ class APITester { }); let responseBodyEditor = monaco.editor.create(target.find('.response_body')[0], { - value: '', - language: language, - automaticLayout: true, - quickSuggestions: false + value: '', language: language, automaticLayout: true, quickSuggestions: false }); me.responseEditors.push(responseBodyEditor); let consoleEditor = monaco.editor.create(target.find('.console')[0], { - value: '', - automaticLayout: true, - quickSuggestions: false + value: '', automaticLayout: true, quickSuggestions: false }); me.consoleEditors.push(consoleEditor); let preRequestEditor = monaco.editor.create(target.find('.pre-request')[0], { - value: model.preRequestScript, - language: 'javascript', - automaticLayout: true, - quickSuggestions: false + value: model.preRequestScript, language: 'javascript', automaticLayout: true, quickSuggestions: false }); const snippet1 = new VariableSnippet(); @@ -804,10 +470,7 @@ class APITester { }); let postRequestEditor = monaco.editor.create(target.find('.post-request')[0], { - value: model.postRequestScript, - language: 'javascript', - automaticLayout: true, - quickSuggestions: false + value: model.postRequestScript, language: 'javascript', automaticLayout: true, quickSuggestions: false }); const snippet2 = new VariableSnippet(); @@ -874,12 +537,10 @@ class APITester { } $('li .api_request_sortable').draggable({ - helper: this.customHelper, - start: function(event, ui) { + helper: this.customHelper, start: function(event, ui) { // You can add any additional data or styles you want when dragging starts $(this).addClass('dragging'); - }, - stop: function(event, ui) { + }, stop: function(event, ui) { // Clean up, e.g., remove styles or data $(this).removeClass('dragging'); } @@ -907,9 +568,7 @@ class APITester { const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request')); let model = this.apiRequests[tabIndex]; model.headers.push({ - enabled: true, - key: '', - value: '' + enabled: true, key: '', value: '' }); this.renderHeaderView(tabIndex); } @@ -938,32 +597,14 @@ class APITester { let queryParam = queryParamArray[i].split('='); queryParams.push({ - enabled: true, - key: queryParam[0], - value: (queryParam[1] === undefined ? '' : queryParam[1]) + enabled: true, key: queryParam[0], value: (queryParam[1] === undefined ? '' : queryParam[1]) }); } } + console.log(queryParams); return queryParams; } - buildPath(model) { - let queryString = model.path.split('?')[0]; - if (model.queryParams.length > 0) { - queryString += '?'; - } - for (let i = 0; i < model.queryParams.length; i++) { - if (!model.queryParams[i].enabled) { - continue; - } - queryString += model.queryParams[i].key + '=' + model.queryParams[i].value; - if (i < model.queryParams.length - 1) { - queryString += '&'; - } - } - model.path = queryString; - } - showLoadingOverlay() { $('#loading-overlay').show(); } @@ -998,11 +639,7 @@ class APITester { model.responseModel.time = endTime - startTime; } else { model.responseModel = { - status: 0, - time: 0, - size: 0, - headers: [], - body: '' + status: 0, time: 0, size: 0, headers: [], body: '' }; } @@ -1022,10 +659,7 @@ class APITester { message = JSON.stringify(message, null, 2); } var op = { - identifier: id, - range: range, - text: message + '\n', - forceMoveMarkers: true + identifier: id, range: range, text: message + '\n', forceMoveMarkers: true }; console.executeEdits('my-source', [op]); } @@ -1033,23 +667,18 @@ class APITester { loadCollections() { const me = this; this.currentAjaxRequest = $.ajax({ - url: this.getCollectionListURL(), - type: 'GET', - contentType: 'application/json', - success: function(data) { + url: this.getCollectionListURL(), type: 'GET', contentType: 'application/json', success: function(data) { me.collections = data.map(collection => { if (collection.apis) { collection.apis = collection.apis.map(api => ({...api, collectionId: collection.id})); } return collection; }); - }, - error: function(response, textStatus, errorThrown) { + }, error: function(response, textStatus, errorThrown) { me.hideLoadingOverlay(); $('.toast-body').text(response.responseJSON.error); $('.toast').toast('show'); - }, - complete: function() { + }, complete: function() { me.renderCollections(); me.hideLoadingOverlay(); } @@ -1061,16 +690,11 @@ class APITester { const me = this; me.showLoadingOverlay(); this.currentAjaxRequest = $.ajax({ - url: this.getCollectionCreateURL(), - type: 'POST', - contentType: 'application/json', - data: JSON.stringify({name: name}), - error: function(response, textStatus, errorThrown) { + url: this.getCollectionCreateURL(), type: 'POST', contentType: 'application/json', data: JSON.stringify({name: name}), error: function(response, textStatus, errorThrown) { me.hideLoadingOverlay(); $('.toast-body').text(response.responseJSON.error); $('.toast').toast('show'); - }, - complete: function() { + }, complete: function() { me.loadCollections(); me.hideLoadingOverlay(); $('#new_collection_modal').modal('hide'); @@ -1082,16 +706,11 @@ class APITester { const me = this; me.showLoadingOverlay(); this.currentAjaxRequest = $.ajax({ - url: this.getCollectionUpdateURL(), - type: 'POST', - contentType: 'application/json', - data: JSON.stringify({id: id, name: name}), - error: function(response, textStatus, errorThrown) { + url: this.getCollectionUpdateURL(), type: 'POST', contentType: 'application/json', data: JSON.stringify({id: id, name: name}), error: function(response, textStatus, errorThrown) { me.hideLoadingOverlay(); $('.toast-body').text(response.responseJSON.error); $('.toast').toast('show'); - }, - complete: function() { + }, complete: function() { me.loadCollections(); me.hideLoadingOverlay(); $('#new_collection_modal').modal('hide'); @@ -1104,18 +723,12 @@ class APITester { const me = this; me.showLoadingOverlay(); this.currentAjaxRequest = $.ajax({ - url: this.getCollectionDeleteURL(), - type: 'POST', - contentType: 'application/json', - data: JSON.stringify({id: collectionId}), - success: function() { - }, - error: function(response, textStatus, errorThrown) { + url: this.getCollectionDeleteURL(), type: 'POST', contentType: 'application/json', data: JSON.stringify({id: collectionId}), success: function() { + }, error: function(response, textStatus, errorThrown) { me.hideLoadingOverlay(); $('.toast-body').text(response.responseJSON.error); $('.toast').toast('show'); - }, - complete: function() { + }, complete: function() { me.loadCollections(); me.hideLoadingOverlay(); $('#confirm_delete_modal').modal('hide'); @@ -1127,21 +740,15 @@ class APITester { const me = this; me.showLoadingOverlay(); this.currentAjaxRequest = $.ajax({ - url: this.getAPISaveURL(model.collectionId), - type: 'POST', - contentType: 'application/json', - data: JSON.stringify(model), - success: function(data) { + url: this.getAPISaveURL(model.collectionId), type: 'POST', contentType: 'application/json', data: JSON.stringify(model), success: function(data) { let message = '저장되었습니다.'; $('.toast-body').text(message); $('.toast').toast('show'); - }, - error: function(response, textStatus, errorThrown) { + }, error: function(response, textStatus, errorThrown) { me.hideLoadingOverlay(); $('.toast-body').text(response.responseJSON.error); $('.toast').toast('show'); - }, - complete: function() { + }, complete: function() { me.hideLoadingOverlay(); } }); @@ -1154,21 +761,15 @@ class APITester { me.showLoadingOverlay(); this.currentAjaxRequest = $.ajax({ - url: this.getAPISaveURL(model.collectionId), - type: 'POST', - contentType: 'application/json', - data: JSON.stringify(model), - success: function(data) { + url: this.getAPISaveURL(model.collectionId), type: 'POST', contentType: 'application/json', data: JSON.stringify(model), success: function(data) { let message = '저장되었습니다.'; $('.toast-body').text(message); $('.toast').toast('show'); - }, - error: function(response, textStatus, errorThrown) { + }, error: function(response, textStatus, errorThrown) { me.hideLoadingOverlay(); $('.toast-body').text(response.responseJSON.error); $('.toast').toast('show'); - }, - complete: function() { + }, complete: function() { me.hideLoadingOverlay(); } }); @@ -1190,42 +791,26 @@ class APITester { })[0]; let me = this; let newApi = { - id: '', - server: null, - method: 'GET', - name: newApiName, - path: '', - type : newApiType, - headers: [], - queryParams: [], - requestBody: '', - preRequestScript: '', - postRequestScript: '', - collectionId: collectionId, - responseModel: { - status: 0, - time: 0, - size: 0, - headers: [], - ody: '' + id: '', server: null, method: 'GET', name: newApiName, path: '', type: newApiType, headers: [], queryParams: [], requestBody: '', preRequestScript: '', postRequestScript: '', collectionId: collectionId, responseModel: { + status: 0, time: 0, size: 0, headers: [], ody: '' } }; newApi.collectionName = collection.name; + if (newApiType === 'TCP') { + newApi.layout = []; + newApi.layout.push({layoutItems: []}); + } + + this.currentAjaxRequest = $.ajax({ - url: this.getAPISaveURL(collectionId), - type: 'POST', - contentType: 'application/json', - data: JSON.stringify(newApi), - success: function(data) { + url: this.getAPISaveURL(collectionId), type: 'POST', contentType: 'application/json', data: JSON.stringify(newApi), success: function(data) { newApi.id = data; - }, - error: function(response, textStatus, errorThrown) { + }, error: function(response, textStatus, errorThrown) { me.hideLoadingOverlay(); $('.toast-body').text(response.responseJSON.error); $('.toast').toast('show'); - }, - complete: function() { + }, complete: function() { me.loadCollections(); me.apiRequests.push(newApi); me.currentIndex = me.apiRequests.length - 1; @@ -1271,11 +856,7 @@ class APITester { if (!selectedApi.responseModel) { selectedApi.responseModel = { - status: 0, - time: 0, - size: 0, - headers: [], - body: '' + status: 0, time: 0, size: 0, headers: [], body: '' }; } @@ -1305,17 +886,11 @@ class APITester { } const me = this; this.currentAjaxRequest = $.ajax({ - url: this.getAPIDeleteURL(collectionId), - type: 'POST', - contentType: 'application/json', - data: JSON.stringify({id: apiId}), - success: function(data) { - }, - error: function(response, textStatus, errorThrown) { + url: this.getAPIDeleteURL(collectionId), type: 'POST', contentType: 'application/json', data: JSON.stringify({id: apiId}), success: function(data) { + }, error: function(response, textStatus, errorThrown) { $('.toast-body').text(response.responseJSON.error); me.hideLoadingOverlay(); - }, - complete: function() { + }, complete: function() { me.hideLoadingOverlay(); me.loadCollections(); $('#confirm_delete_api_modal').modal('hide'); diff --git a/ApiTestManager/src/components/HTTPClientView.js b/ApiTestManager/src/components/HTTPClientView.js new file mode 100644 index 0000000..86501de --- /dev/null +++ b/ApiTestManager/src/components/HTTPClientView.js @@ -0,0 +1,255 @@ +import EditableInput from './EditableInput'; +import PropertyTable from './PropertyTable'; + +class HTTPClientView { + constructor(parent, serverManager, apiRequestTabContent, model, index) { + this.parent = parent; + this.serverManager = serverManager; + this.apiRequestTabContent = apiRequestTabContent; + this.model = model; + this.index = index; + } + + init() { + let me = this; + this.apiRequestTabContent.append(this.httpApiRequestTemplate(this.model, this.index)); + let editableInput = new EditableInput({ + name: 'path', + value: this.model.path + }); + let queryParamTable = new PropertyTable({ + propertyName: 'queryParams', + properties: this.model.queryParams + }); + + let headerTable = new PropertyTable({ + propertyName: 'headers', + properties: this.model.headers + }); + + this.apiRequestTabContent.find(`#api_request_${this.model.id}`).find('.api_request_info').find('.path').each(function() { + editableInput.init(this, (value) => { + me.model.path = value; + me.model.queryParams = me.parent.parseParam(me.model.path); + queryParamTable.setProperties(me.model.queryParams); + $('span.variable').off('mouseover'); + $('span.variable').off('mouseout'); + document.querySelectorAll('span.variable').forEach(element => { + let text = element.innerText; + element.addEventListener('mouseover', () => this.parent.showPopper(element, text)); + element.addEventListener('mouseout', () => this.parent.hidePopper(element)); + }); + }); + + $(this).append(``); + + $('span.variable').off('mouseover'); + $('span.variable').off('mouseout'); + }); + + queryParamTable.init(this.apiRequestTabContent.find(`#api_request_${this.model.id}`).find('.query_params')[0], (properties) => { + this.model.queryParams = properties; + console.log(this.model.queryParams); + this.buildPath(this.model); + editableInput.setValue(this.model.path); + $('span.variable').off('mouseover'); + $('span.variable').off('mouseout'); + document.querySelectorAll('span.variable').forEach(element => { + let text = element.innerText; + element.addEventListener('mouseover', () => this.parent.showPopper(element, text)); + element.addEventListener('mouseout', () => this.parent.hidePopper(element)); + }); + }); + + headerTable.init(this.apiRequestTabContent.find(`#api_request_${this.model.id}`).find('.request_headers')[0], (properties) => { + this.model.headers = properties; + $('span.variable').off('mouseover'); + $('span.variable').off('mouseout'); + document.querySelectorAll('span.variable').forEach(element => { + let text = element.innerText; + element.addEventListener('mouseover', () => this.parent.showPopper(element, text)); + element.addEventListener('mouseout', () => this.parent.hidePopper(element)); + }); + }); + + } + + buildPath(model) { + let queryString = model.path.split('?')[0]; + if (model.queryParams.length > 0) { + queryString += '?'; + } + for (let i = 0; i < model.queryParams.length; i++) { + if (!model.queryParams[i].enabled) { + continue; + } + queryString += model.queryParams[i].key + '=' + model.queryParams[i].value; + if (i < model.queryParams.length - 1) { + queryString += '&'; + } + } + model.path = queryString; + } + + httpApiRequestTemplate(apiRequest, index) { + return ` +
+
${apiRequest.collectionName} > ${apiRequest.name}
+
+
+ + +
+
+ ${this.serverManager.renderHttpServers(apiRequest.server)} + +
+
+ + +
+
+ +
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Response + + + +
+ +
+
+
+
+
+ + + + + + + + + +
이름
+
+
+
+
+
+
+
+
+ + `; + } +} + +export default HTTPClientView; diff --git a/ApiTestManager/src/components/ServerManager.js b/ApiTestManager/src/components/ServerManager.js new file mode 100644 index 0000000..6836d1a --- /dev/null +++ b/ApiTestManager/src/components/ServerManager.js @@ -0,0 +1,44 @@ +class ServerManager { + constructor(servers) { + this.servers = servers ||[]; + } + + basePath(serverId) { + if (serverId === undefined || serverId === null || serverId === '') { + return ''; + } + return this.servers.filter(server => server.id == serverId)[0].basePath; // == : 타입 비교 없이 값만 비교 + } + + getServer(serverId) { + return this.servers.filter(server => server.id == serverId)[0]; + } + + renderServers(selectedServer) { + const optionsHtml = this.servers.map(server => ``).join(''); + + return ``; + } + + renderTcpServers(selectedServer) { + const optionsHtml = this.servers.filter( server => server.scheme === 'tcp') + .map(server => ``).join(''); + + return ``; + } + + renderHttpServers(selectedServer) { + const optionsHtml = this.servers.filter( server => server.scheme !== 'tcp') + .map(server => ``).join(''); + + return ``; + } +} + +export default ServerManager; diff --git a/ApiTestManager/src/components/TCPClientView.js b/ApiTestManager/src/components/TCPClientView.js new file mode 100644 index 0000000..ffc0dd9 --- /dev/null +++ b/ApiTestManager/src/components/TCPClientView.js @@ -0,0 +1,386 @@ +import EditableInput from './EditableInput'; +import APIClient from '../APIClient'; + + +class TCPClientView { + + constructor(parent, serverManager, apiRequestTabContent, model, index) { + this.parent = parent; + this.serverManager = serverManager; + this.apiRequestTabContent = apiRequestTabContent; + this.model = model; + this.index = index; + this.server = this.serverManager.getServer(this.model.server); + this.apiClient = new APIClient(); + } + + init() { + this.apiRequestTabContent.append(this.tcpApiRequestTemplate(this.model, this.index)); + this.renderApiLayout(this.model.layout); + } + + setRequestBodyEditor(editor) { + this.requestBodyEditor = editor; + } + + renderApiLayout(layout) { + const requestContainer = this.apiRequestTabContent.find('.request_layout'); + requestContainer.empty(); + + const headerHtml = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; + + const footerHtml = ` + +
#항목명(영문)항목설명깊이아이템 유형반복 횟수 반복 참조 필드데이터 타입데이터 길이비고
+ `; + + const fieldsHtml = layout.layoutItems ? layout.layoutItems.map((item, index) => { + return this.renderApiLayoutItem(item, index); + }).join('') : ''; + + requestContainer.append(headerHtml + fieldsHtml + footerHtml); + + requestContainer.find('.editable').each((index, editableElement) => { + const editableInput = new EditableInput({ + name: editableElement.dataset.name, + value: editableElement.dataset.value + }); + + editableInput.init(editableElement, (value) => { + _.set(this.model.layout, editableElement.dataset.name, value); + this.buildMessage(); + $('span.variable').off('mouseover'); + $('span.variable').off('mouseover'); + document.querySelectorAll('span.variable').forEach(element => { + let text = element.innerText; + element.addEventListener('mouseover', () => this.parent.showPopper(element, text)); + element.addEventListener('mouseout', () => this.parent.hidePopper(element)); + }); + }); + }); + + let totalLength = 0; + this.model.layout.layoutItems.forEach(item => { + totalLength += parseInt(item.loutItemLength); + }); + this.apiRequestTabContent.find('.total_message_length').text(totalLength); + this.setupListeners(); + } + + + handleUIUpdate(event) { + if (event) { + event.preventDefault(); + const element = event.currentTarget; + const fieldName = $(element).attr('name'); + const newValue = this.getFieldValue(element); + if (fieldName !== '') { + _.set(this.model.layout, fieldName, newValue); + this.buildMessage(); + } + } + let totalLength = 0; + this.model.layout.layoutItems.forEach(item => { + totalLength += parseInt(item.loutItemLength); + }); + this.apiRequestTabContent.find('.total_message_length').text(totalLength); + } + + getFieldValue(element) { + if ($(element).is('select') || $(element).is('input[type="text"]') || $(element).is('input[type="number"]')) { + return $(element).val(); + } + if ($(element).is('input[type="checkbox"]')) { + return $(element).is(':checked'); + } + } + + renderApiLayoutItem(item, index) { + if (item.value === null) + item.value = ''; + + return ` + + ${item.loutItemSerno} + + + + + + + + + + + + + +
+ + +
+ + + + +
+ + + `; + + } + + recalculateSerno() { + // Reassign loutItemSerno sequentially based on the current order + this.model.layout.layoutItems.forEach((item, index) => { + item.loutItemSerno = index + 1; // Assuming you want to start numbering from 1 + }); + } + + setupListeners() { + const table = this.apiRequestTabContent.find('.layout_table'); + table.on('change', 'select.field, input.field', this.handleUIUpdate.bind(this)); + + table.on('click', '.add-layout-item', event => { + let item = { + 'parent': 0, + 'level': 1, + 'loutName': '', + 'loutItemName': '', + 'loutItemDesc': '', + 'loutItemDepth': 1, + 'loutItemType': 'Field', + 'loutItemOccCnt': '', + 'loutItemOccRef': '', + 'loutItemDataType': 'String', + 'loutItemLength': 1, + 'loutItemDecimal': 0, + 'loutItemDefault': '', + 'loutItemMaskYn': 'N', + 'loutItemMaskOffset': 0, + 'loutItemMaskLength': 0, + 'parentLoutItemIndex': 0, + 'expanded': true, + 'isLeaf': true, + 'LOUTITEMPATH': '', + 'value' : '' + }; + this.model.layout.layoutItems.push(item); + this.recalculateSerno(); + this.renderApiLayout(this.model.layout); + }); + + table.on('click', '.move-up', event => { + const index = $(event.currentTarget).data('index'); + if (index > 0) { + const temp = this.model.layout.layoutItems[index]; + this.model.layout.layoutItems[index] = this.model.layout.layoutItems[index - 1]; + this.model.layout.layoutItems[index - 1] = temp; + this.recalculateSerno(); + this.renderApiLayout(this.model.layout); + } + }); + + table.on('click', '.move-down', event => { + const index = $(event.currentTarget).data('index'); + if (index < this.model.layout.layoutItems.length - 1) { + const temp = this.model.layout.layoutItems[index]; + this.model.layout.layoutItems[index] = this.model.layout.layoutItems[index + 1]; + this.model.layout.layoutItems[index + 1] = temp; + this.recalculateSerno(); + this.renderApiLayout(this.model.layout); + } + }); + + table.on('click', '.delete', event => { + const index = $(event.currentTarget).data('index'); + this.model.layout.layoutItems.splice(index, 1); + this.recalculateSerno(); + this.renderApiLayout(this.model.layout); + }); + } + + async buildMessage() { + let message = ''; + this.requestBodyEditor.setValue(message); + + for (const item of this.model.layout.layoutItems) { + let duplicated = item.value; + const value = await this.apiClient.processPreScriptAndVariables(this.model, duplicated, null); + message += this.fillPadding(item.loutItemLength, value); + } + + this.requestBodyEditor.setValue(message); + } + + fillPadding(dataLength, value) { + value = String(value); + return value.padStart(dataLength, ' '); + } + + tcpApiRequestTemplate(apiRequest, index) { + return ` +
+
${apiRequest.collectionName} > ${apiRequest.name}
+
+
+ ${this.serverManager.renderTcpServers(apiRequest.server)} + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 전체 메시지 길이: + +
+
+
+
+
+ Response + + +
+ +
+
+
+
+
+
+
+
+
+
+
+ + `; + } +} + +export default TCPClientView; diff --git a/src/main/java/com/eactive/testmaster/client/controller/ApiRequestMgmtController.java b/src/main/java/com/eactive/testmaster/client/controller/ApiRequestMgmtController.java index 8127381..98f424e 100644 --- a/src/main/java/com/eactive/testmaster/client/controller/ApiRequestMgmtController.java +++ b/src/main/java/com/eactive/testmaster/client/controller/ApiRequestMgmtController.java @@ -3,12 +3,17 @@ package com.eactive.testmaster.client.controller; import com.eactive.testmaster.client.dto.ApiCollectionDTO; import com.eactive.testmaster.client.dto.ApiRequestDTO; import com.eactive.testmaster.client.entity.ApiCollection; +import com.eactive.testmaster.client.entity.ApiLayout; import com.eactive.testmaster.client.entity.ApiRequestInfo; +import com.eactive.testmaster.client.mapper.ApiLayoutMapper; import com.eactive.testmaster.client.mapper.ApiRequestMapper; +import com.eactive.testmaster.client.service.ApiLayoutMgmtService; import com.eactive.testmaster.client.service.ApiRequestMgmtService; import com.eactive.testmaster.common.util.SecurityUtil; import com.eactive.testmaster.user.entity.StaffUser; import com.eactive.testmaster.user.service.UserService; +import javax.transaction.Transactional; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -20,13 +25,19 @@ public class ApiRequestMgmtController { private static final String SUCCESS = "success"; private final ApiRequestMgmtService apiRequestMgmtService; + private final ApiLayoutMgmtService apiLayoutMgmtService; + private final ApiRequestMapper apiRequestMapper; + private final ApiLayoutMapper apiLayoutMapper; + private final UserService userService; - public ApiRequestMgmtController(ApiRequestMgmtService apiRequestMgmtService, ApiRequestMapper apiRequestMapper, UserService userService) { + public ApiRequestMgmtController(ApiRequestMgmtService apiRequestMgmtService, ApiLayoutMgmtService apiLayoutMgmtService, ApiRequestMapper apiRequestMapper, ApiLayoutMapper apiLayoutMapper, UserService userService) { this.apiRequestMgmtService = apiRequestMgmtService; + this.apiLayoutMgmtService = apiLayoutMgmtService; this.apiRequestMapper = apiRequestMapper; + this.apiLayoutMapper = apiLayoutMapper; this.userService = userService; } @@ -39,7 +50,7 @@ public class ApiRequestMgmtController { @PostMapping("/mgmt/collections/create.do") public ResponseEntity createApiCollection( - @RequestBody ApiCollectionDTO dto) { + @RequestBody ApiCollectionDTO dto) { ApiCollection collection = apiRequestMapper.map(dto); StaffUser user = userService.findByEsntlId(SecurityUtil.getCurrentUserEsntlId()); @@ -64,18 +75,28 @@ public class ApiRequestMgmtController { } @PostMapping("/mgmt/collections/{id}/apis/save.do") - public ResponseEntity addApiToCollection(@PathVariable(name = "id") String id, - @RequestBody ApiRequestDTO dto) { + @Transactional + public ResponseEntity addApiToCollection(@PathVariable(name = "id") String id, @RequestBody ApiRequestDTO dto) { ApiRequestInfo apiRequestInfo = apiRequestMapper.map(dto); StaffUser user = userService.findByEsntlId(SecurityUtil.getCurrentUserEsntlId()); apiRequestInfo.setOwner(user); String apiId = apiRequestMgmtService.saveApiToCollection(id, apiRequestInfo); + + if (dto.getLayout() != null) { + dto.getLayout().setApiRequestId(apiId); + apiLayoutMgmtService.saveLayout(apiLayoutMapper.map(dto.getLayout())); + } return ResponseEntity.ok(apiId); + } @PostMapping("/mgmt/collections/{id}/apis/delete.do") - public ResponseEntity removeApiFromCollection(@PathVariable(name = "id") String id, - @RequestBody ApiRequestDTO dto) { + @Transactional + public ResponseEntity removeApiFromCollection(@PathVariable(name = "id") String id, @RequestBody ApiRequestDTO dto) { + ApiLayout layout = apiLayoutMgmtService.findLayoutByApiRequest(dto.getId()); + if (layout != null) { + apiLayoutMgmtService.deleteLayout(layout.getId()); + } apiRequestMgmtService.removeApiFromCollection(id, dto.getId()); return ResponseEntity.ok(SUCCESS); } diff --git a/src/main/java/com/eactive/testmaster/client/dto/ApiLayoutDTO.java b/src/main/java/com/eactive/testmaster/client/dto/ApiLayoutDTO.java new file mode 100644 index 0000000..206d0ee --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/dto/ApiLayoutDTO.java @@ -0,0 +1,167 @@ +package com.eactive.testmaster.client.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApiLayoutDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @JsonProperty("id") + private String id; + + @JsonProperty("APIREQUESTID") + private String apiRequestId; + + @JsonProperty("LOUTNAME") + private String loutName; + + @JsonProperty("LOUTPTRNNAME") + private String loutPtrnName; + + @JsonProperty("LOUTDESC") + private String loutDesc; + + @JsonProperty("EAIBZWKDSTCD") + private String eaiBzwkDstCd; + + @JsonProperty("UAPPLNAME") + private String uApplName; + + @JsonProperty("SYSINTFACNAME") + private String sysIntFacName; + + @JsonProperty("AUTHOR") + private String author; + + @JsonProperty("EAISEVRDSTCD") + private String eaiSevRdStCd; + + @JsonProperty("MODFMGTSTUSDSTCD") + private String modfMgtStusDstCd; + + @JsonProperty("USEYN") + private String useYn; + + @JsonProperty("VERINFO") + private String verInfo; + + @JsonProperty("layoutItems") + List layoutItems = new ArrayList<>(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getApiRequestId() { + return apiRequestId; + } + + public void setApiRequestId(String apiRequestId) { + this.apiRequestId = apiRequestId; + } + + public String getLoutName() { + return loutName; + } + + public void setLoutName(String loutName) { + this.loutName = loutName; + } + + public String getLoutPtrnName() { + return loutPtrnName; + } + + public void setLoutPtrnName(String loutPtrnName) { + this.loutPtrnName = loutPtrnName; + } + + public String getLoutDesc() { + return loutDesc; + } + + public void setLoutDesc(String loutDesc) { + this.loutDesc = loutDesc; + } + + public String getEaiBzwkDstCd() { + return eaiBzwkDstCd; + } + + public void setEaiBzwkDstCd(String eaiBzwkDstCd) { + this.eaiBzwkDstCd = eaiBzwkDstCd; + } + + public String getuApplName() { + return uApplName; + } + + public void setuApplName(String uApplName) { + this.uApplName = uApplName; + } + + public String getSysIntFacName() { + return sysIntFacName; + } + + public void setSysIntFacName(String sysIntFacName) { + this.sysIntFacName = sysIntFacName; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getEaiSevRdStCd() { + return eaiSevRdStCd; + } + + public void setEaiSevRdStCd(String eaiSevRdStCd) { + this.eaiSevRdStCd = eaiSevRdStCd; + } + + public String getModfMgtStusDstCd() { + return modfMgtStusDstCd; + } + + public void setModfMgtStusDstCd(String modfMgtStusDstCd) { + this.modfMgtStusDstCd = modfMgtStusDstCd; + } + + public String getUseYn() { + return useYn; + } + + public void setUseYn(String useYn) { + this.useYn = useYn; + } + + public String getVerInfo() { + return verInfo; + } + + public void setVerInfo(String verInfo) { + this.verInfo = verInfo; + } + + public List getLayoutItems() { + return layoutItems; + } + + public void setLayoutItems(List layoutItems) { + this.layoutItems = layoutItems; + } +} diff --git a/src/main/java/com/eactive/testmaster/client/dto/ApiLayoutItemDTO.java b/src/main/java/com/eactive/testmaster/client/dto/ApiLayoutItemDTO.java new file mode 100644 index 0000000..ca21a05 --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/dto/ApiLayoutItemDTO.java @@ -0,0 +1,275 @@ +package com.eactive.testmaster.client.dto; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ApiLayoutItemDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @JsonProperty("itemId") + private Long itemId; + + @JsonProperty("id") + private Long id; + + @JsonProperty("parent") + private Long parent; + + @JsonProperty("level") + private Integer level; + + @JsonProperty("loutName") + private String loutName; + + @JsonProperty("loutItemSerno") + private Integer loutItemSerno; + + @JsonProperty("loutItemName") + private String loutItemName; + + @JsonProperty("loutItemDesc") + private String loutItemDesc; + + @JsonProperty("loutItemDepth") + private Integer loutItemDepth; + + @JsonProperty("loutItemType") + private String loutItemType; + + @JsonProperty("loutItemOccCnt") + private String loutItemOccCnt; + + @JsonProperty("loutItemOccRef") + private String loutItemOccRef; + + @JsonProperty("loutItemDataType") + private String loutItemDataType; + + @JsonProperty("loutItemLength") + private Integer loutItemLength; + + @JsonProperty("loutItemDecimal") + private Integer loutItemDecimal; + + @JsonProperty("loutItemDefault") + private String loutItemDefault; + + @JsonProperty("loutItemMaskYn") + private String loutItemMaskYn; + + @JsonProperty("loutItemMaskOffset") + private Integer loutItemMaskOffset; + + @JsonProperty("loutItemMaskLength") + private Integer loutItemMaskLength; + + @JsonProperty("parentLoutItemIndex") + private Integer parentLoutItemIndex; + + @JsonProperty("expanded") + private Boolean expanded; + + @JsonProperty("isLeaf") + private Boolean isLeaf; + + @JsonProperty("LOUTITEMPATH") + private String loutItemPath; + + @JsonProperty(value = "value", defaultValue = "") + private String value; + + public Long getItemId() { + return itemId; + } + + public void setItemId(Long itemId) { + this.itemId = itemId; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getParent() { + return parent; + } + + public void setParent(Long parent) { + this.parent = parent; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public String getLoutName() { + return loutName; + } + + public void setLoutName(String loutName) { + this.loutName = loutName; + } + + public Integer getLoutItemSerno() { + return loutItemSerno; + } + + public void setLoutItemSerno(Integer loutItemSerno) { + this.loutItemSerno = loutItemSerno; + } + + public String getLoutItemName() { + return loutItemName; + } + + public void setLoutItemName(String loutItemName) { + this.loutItemName = loutItemName; + } + + public String getLoutItemDesc() { + return loutItemDesc; + } + + public void setLoutItemDesc(String loutItemDesc) { + this.loutItemDesc = loutItemDesc; + } + + public Integer getLoutItemDepth() { + return loutItemDepth; + } + + public void setLoutItemDepth(Integer loutItemDepth) { + this.loutItemDepth = loutItemDepth; + } + + public String getLoutItemType() { + return loutItemType; + } + + public void setLoutItemType(String loutItemType) { + this.loutItemType = loutItemType; + } + + public String getLoutItemOccCnt() { + return loutItemOccCnt; + } + + public void setLoutItemOccCnt(String loutItemOccCnt) { + this.loutItemOccCnt = loutItemOccCnt; + } + + public String getLoutItemOccRef() { + return loutItemOccRef; + } + + public void setLoutItemOccRef(String loutItemOccRef) { + this.loutItemOccRef = loutItemOccRef; + } + + public String getLoutItemDataType() { + return loutItemDataType; + } + + public void setLoutItemDataType(String loutItemDataType) { + this.loutItemDataType = loutItemDataType; + } + + public Integer getLoutItemLength() { + return loutItemLength; + } + + public void setLoutItemLength(Integer loutItemLength) { + this.loutItemLength = loutItemLength; + } + + public Integer getLoutItemDecimal() { + return loutItemDecimal; + } + + public void setLoutItemDecimal(Integer loutItemDecimal) { + this.loutItemDecimal = loutItemDecimal; + } + + public String getLoutItemDefault() { + return loutItemDefault; + } + + public void setLoutItemDefault(String loutItemDefault) { + this.loutItemDefault = loutItemDefault; + } + + public String getLoutItemMaskYn() { + return loutItemMaskYn; + } + + public void setLoutItemMaskYn(String loutItemMaskYn) { + this.loutItemMaskYn = loutItemMaskYn; + } + + public Integer getLoutItemMaskOffset() { + return loutItemMaskOffset; + } + + public void setLoutItemMaskOffset(Integer loutItemMaskOffset) { + this.loutItemMaskOffset = loutItemMaskOffset; + } + + public Integer getLoutItemMaskLength() { + return loutItemMaskLength; + } + + public void setLoutItemMaskLength(Integer loutItemMaskLength) { + this.loutItemMaskLength = loutItemMaskLength; + } + + public Integer getParentLoutItemIndex() { + return parentLoutItemIndex; + } + + public void setParentLoutItemIndex(Integer parentLoutItemIndex) { + this.parentLoutItemIndex = parentLoutItemIndex; + } + + public Boolean getExpanded() { + return expanded; + } + + public void setExpanded(Boolean expanded) { + this.expanded = expanded; + } + + public Boolean getLeaf() { + return isLeaf; + } + + public void setLeaf(Boolean leaf) { + isLeaf = leaf; + } + + public String getLoutItemPath() { + return loutItemPath; + } + + public void setLoutItemPath(String loutItemPath) { + this.loutItemPath = loutItemPath; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/com/eactive/testmaster/client/dto/ApiRequestDTO.java b/src/main/java/com/eactive/testmaster/client/dto/ApiRequestDTO.java index a939a66..0609eaa 100644 --- a/src/main/java/com/eactive/testmaster/client/dto/ApiRequestDTO.java +++ b/src/main/java/com/eactive/testmaster/client/dto/ApiRequestDTO.java @@ -33,7 +33,7 @@ public class ApiRequestDTO implements Serializable { private String postRequestScript; - private long sentBytes; //estimated size of the request + private ApiLayoutDTO layout; public String getId() { return id; @@ -131,11 +131,11 @@ public class ApiRequestDTO implements Serializable { this.postRequestScript = postRequestScript; } -// public long getSentBytes() { -// return sentBytes; -// } -// -// public void setSentBytes(long sentBytes) { -// this.sentBytes = sentBytes; -// } + public ApiLayoutDTO getLayout() { + return layout; + } + + public void setLayout(ApiLayoutDTO layout) { + this.layout = layout; + } } diff --git a/src/main/java/com/eactive/testmaster/client/entity/ApiLayout.java b/src/main/java/com/eactive/testmaster/client/entity/ApiLayout.java new file mode 100644 index 0000000..a39434b --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/entity/ApiLayout.java @@ -0,0 +1,167 @@ +package com.eactive.testmaster.client.entity; + +import java.util.ArrayList; +import java.util.List; +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "API_LAYOUT") +public class ApiLayout { + + @Id + private String id; + + @ManyToOne + @JoinColumn(name = "API_REQUEST_INFO_ID") + private ApiRequestInfo apiRequestInfo; + + private String loutName; + + private String loutPtrnName; + + private String loutDesc; + + private String eaiBzwkDstCd; + + private String uApplName; + + private String sysIntFacName; + + private String author; + + private String eaiSevRdStCd; + + private String modfMgtStusDstCd; + + private String useYn; + + private String verInfo; + + @OneToMany(mappedBy = "apiLayout", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + private List layoutItems = new ArrayList<>(); + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public ApiRequestInfo getApiRequestInfo() { + return apiRequestInfo; + } + + public void setApiRequestInfo(ApiRequestInfo apiRequestInfo) { + this.apiRequestInfo = apiRequestInfo; + } + + public String getLoutName() { + return loutName; + } + + public void setLoutName(String loutName) { + this.loutName = loutName; + } + + public String getLoutPtrnName() { + return loutPtrnName; + } + + public void setLoutPtrnName(String loutPtrnName) { + this.loutPtrnName = loutPtrnName; + } + + public String getLoutDesc() { + return loutDesc; + } + + public void setLoutDesc(String loutDesc) { + this.loutDesc = loutDesc; + } + + public String getEaiBzwkDstCd() { + return eaiBzwkDstCd; + } + + public void setEaiBzwkDstCd(String eaiBzwkDstCd) { + this.eaiBzwkDstCd = eaiBzwkDstCd; + } + + public String getUApplName() { + return uApplName; + } + + public void setUApplName(String uApplName) { + this.uApplName = uApplName; + } + + public String getSysIntFacName() { + return sysIntFacName; + } + + public void setSysIntFacName(String sysIntFacName) { + this.sysIntFacName = sysIntFacName; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getEaiSevRdStCd() { + return eaiSevRdStCd; + } + + public void setEaiSevRdStCd(String eaiSevRdStCd) { + this.eaiSevRdStCd = eaiSevRdStCd; + } + + public String getModfMgtStusDstCd() { + return modfMgtStusDstCd; + } + + public void setModfMgtStusDstCd(String modfMgtStusDstCd) { + this.modfMgtStusDstCd = modfMgtStusDstCd; + } + + public String getUseYn() { + return useYn; + } + + public void setUseYn(String useYn) { + this.useYn = useYn; + } + + public String getVerInfo() { + return verInfo; + } + + public void setVerInfo(String verInfo) { + this.verInfo = verInfo; + } + + public List getLayoutItems() { + return layoutItems; + } + + public void setLayoutItems(List layoutItems) { + this.layoutItems = layoutItems; + } + + public void addApiLayoutItem(ApiLayoutItem item) { + item.setApiLayout(this); + this.layoutItems.add(item); + } + +} diff --git a/src/main/java/com/eactive/testmaster/client/entity/ApiLayoutItem.java b/src/main/java/com/eactive/testmaster/client/entity/ApiLayoutItem.java new file mode 100644 index 0000000..2a53db7 --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/entity/ApiLayoutItem.java @@ -0,0 +1,270 @@ +package com.eactive.testmaster.client.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "API_LAYOUT_ITEM") +public class ApiLayoutItem { + + @ManyToOne + @JoinColumn(name = "API_LAYOUT_ID", nullable = false) + private ApiLayout apiLayout; // This is the back-reference to the parent + + @Id + @Column(name = "API_LAYOUT_ITEM_ID") + @GeneratedValue(strategy = GenerationType.AUTO) + private Long itemId; + + private Long id; + + private Long parent; + + private Integer level; + + private String loutName; + + private Integer loutItemSerno; + + private String loutItemName; + + private String loutItemDesc; + + private Integer loutItemDepth; + + private String loutItemType; + + private String loutItemOccCnt; + + private String loutItemOccRef; + + private String loutItemDataType; + + private Integer loutItemLength; + + private Integer loutItemDecimal; + + private String loutItemDefault; + + private String loutItemMaskYn; + + private Integer loutItemMaskOffset; + + private Integer loutItemMaskLength; + + private Integer parentLoutItemIndex; + + private Boolean expanded; + + private Boolean isLeaf; + + private String loutItemPath; + + private String value; + + public Long getItemId() { + return itemId; + } + + public void setItemId(Long itemId) { + this.itemId = itemId; + } + + public ApiLayout getApiLayout() { + return apiLayout; + } + + public void setApiLayout(ApiLayout apiLayout) { + this.apiLayout = apiLayout; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getParent() { + return parent; + } + + public void setParent(Long parent) { + this.parent = parent; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public String getLoutName() { + return loutName; + } + + public void setLoutName(String loutName) { + this.loutName = loutName; + } + + public Integer getLoutItemSerno() { + return loutItemSerno; + } + + public void setLoutItemSerno(Integer loutItemSerno) { + this.loutItemSerno = loutItemSerno; + } + + public String getLoutItemName() { + return loutItemName; + } + + public void setLoutItemName(String loutItemName) { + this.loutItemName = loutItemName; + } + + public String getLoutItemDesc() { + return loutItemDesc; + } + + public void setLoutItemDesc(String loutItemDesc) { + this.loutItemDesc = loutItemDesc; + } + + public Integer getLoutItemDepth() { + return loutItemDepth; + } + + public void setLoutItemDepth(Integer loutItemDepth) { + this.loutItemDepth = loutItemDepth; + } + + public String getLoutItemType() { + return loutItemType; + } + + public void setLoutItemType(String loutItemType) { + this.loutItemType = loutItemType; + } + + public String getLoutItemOccCnt() { + return loutItemOccCnt; + } + + public void setLoutItemOccCnt(String loutItemOccCnt) { + this.loutItemOccCnt = loutItemOccCnt; + } + + public String getLoutItemOccRef() { + return loutItemOccRef; + } + + public void setLoutItemOccRef(String loutItemOccRef) { + this.loutItemOccRef = loutItemOccRef; + } + + public String getLoutItemDataType() { + return loutItemDataType; + } + + public void setLoutItemDataType(String loutItemDataType) { + this.loutItemDataType = loutItemDataType; + } + + public Integer getLoutItemLength() { + return loutItemLength; + } + + public void setLoutItemLength(Integer loutItemLength) { + this.loutItemLength = loutItemLength; + } + + public Integer getLoutItemDecimal() { + return loutItemDecimal; + } + + public void setLoutItemDecimal(Integer loutItemDecimal) { + this.loutItemDecimal = loutItemDecimal; + } + + public String getLoutItemDefault() { + return loutItemDefault; + } + + public void setLoutItemDefault(String loutItemDefault) { + this.loutItemDefault = loutItemDefault; + } + + public String getLoutItemMaskYn() { + return loutItemMaskYn; + } + + public void setLoutItemMaskYn(String loutItemMaskYn) { + this.loutItemMaskYn = loutItemMaskYn; + } + + public Integer getLoutItemMaskOffset() { + return loutItemMaskOffset; + } + + public void setLoutItemMaskOffset(Integer loutItemMaskOffset) { + this.loutItemMaskOffset = loutItemMaskOffset; + } + + public Integer getLoutItemMaskLength() { + return loutItemMaskLength; + } + + public void setLoutItemMaskLength(Integer loutItemMaskLength) { + this.loutItemMaskLength = loutItemMaskLength; + } + + public Integer getParentLoutItemIndex() { + return parentLoutItemIndex; + } + + public void setParentLoutItemIndex(Integer parentLoutItemIndex) { + this.parentLoutItemIndex = parentLoutItemIndex; + } + + public Boolean getExpanded() { + return expanded; + } + + public void setExpanded(Boolean expanded) { + this.expanded = expanded; + } + + public Boolean getLeaf() { + return isLeaf; + } + + public void setLeaf(Boolean leaf) { + isLeaf = leaf; + } + + public String getLoutItemPath() { + return loutItemPath; + } + + public void setLoutItemPath(String loutItemPath) { + this.loutItemPath = loutItemPath; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutItemMapper.java b/src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutItemMapper.java new file mode 100644 index 0000000..c3ee935 --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutItemMapper.java @@ -0,0 +1,39 @@ +package com.eactive.testmaster.client.mapper; + +import com.eactive.testmaster.client.dto.ApiLayoutItemDTO; +import com.eactive.testmaster.client.entity.ApiLayoutItem; +import com.eactive.testmaster.client.repository.ApiLayoutItemRepository; +import com.eactive.testmaster.common.mapper.CommonMapper; +import java.util.List; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Mapper(componentModel = "spring", + uses = {CommonMapper.class}, + unmappedTargetPolicy = ReportingPolicy.IGNORE) +@Component +public abstract class ApiLayoutItemMapper { + + @Autowired + private ApiLayoutItemRepository apiLayoutItemRepository; + + public abstract ApiLayoutItem map(ApiLayoutItemDTO dto); + + public abstract ApiLayoutItemDTO map(ApiLayoutItem entity); + + public ApiLayoutItem map(Long id) { + if (id == null) { + return null; + } + return apiLayoutItemRepository.findById(id) + .orElseThrow(() -> new IllegalArgumentException("No ApiLayoutItem found for ID: " + id)); + } + + // Method to map lists of ApiLayoutItemDTOs to lists of ApiLayoutItem entities + public abstract List mapItems(List dtos); + + // Method to map lists of ApiLayoutItem entities to lists of ApiLayoutItemDTOs + public abstract List mapItemDTOs(List entities); +} diff --git a/src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutMapper.java b/src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutMapper.java new file mode 100644 index 0000000..026d1e8 --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/mapper/ApiLayoutMapper.java @@ -0,0 +1,60 @@ +package com.eactive.testmaster.client.mapper; + +import com.eactive.testmaster.client.dto.ApiLayoutDTO; +import com.eactive.testmaster.client.entity.ApiLayout; +import com.eactive.testmaster.client.entity.ApiRequestInfo; +import com.eactive.testmaster.client.repository.ApiLayoutRepository; +import com.eactive.testmaster.client.repository.ApiRequestRepository; +import com.eactive.testmaster.common.mapper.CommonMapper; +import java.util.List; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Mapper(componentModel = "spring", + uses = {CommonMapper.class, ApiLayoutItemMapper.class}, + unmappedTargetPolicy = ReportingPolicy.IGNORE) +@Component +public abstract class ApiLayoutMapper { + + @Autowired + private ApiLayoutRepository apiLayoutRepository; + + @Autowired + private ApiRequestRepository apiRequestRepository; + + + @Mapping(target = "apiRequestInfo", source = "apiRequestId") + public abstract ApiLayout map(ApiLayoutDTO dto); + + @Mapping(target = "apiRequestId", source = "apiRequestInfo") + public abstract ApiLayoutDTO map(ApiLayout entity); + + public ApiRequestInfo mapApiRequestInfo(String id) { + if (id == null) { + return null; + } + return apiRequestRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("No ApiRequest found for ID: " + id)); + } + + public String mapApiRequestId(ApiRequestInfo entity) { + if (entity == null) { + return null; + } + return entity.getId(); + } + + + public ApiLayout map(String id) { + if (id == null) { + return null; + } + return apiLayoutRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("No ApiLayout found for ID: " + id)); + } + +// public abstract List mapLayouts(List dtos); + + public abstract List mapLayoutDTOs(List entities); +} diff --git a/src/main/java/com/eactive/testmaster/client/mapper/ApiRequestMapper.java b/src/main/java/com/eactive/testmaster/client/mapper/ApiRequestMapper.java index 1e326fb..d07c8c7 100644 --- a/src/main/java/com/eactive/testmaster/client/mapper/ApiRequestMapper.java +++ b/src/main/java/com/eactive/testmaster/client/mapper/ApiRequestMapper.java @@ -3,40 +3,73 @@ package com.eactive.testmaster.client.mapper; import com.eactive.testmaster.client.dto.ApiCollectionDTO; import com.eactive.testmaster.client.dto.ApiRequestDTO; import com.eactive.testmaster.client.entity.ApiCollection; +import com.eactive.testmaster.client.entity.ApiLayout; +import com.eactive.testmaster.client.entity.ApiLayoutItem; import com.eactive.testmaster.client.entity.ApiRequestInfo; +import com.eactive.testmaster.client.repository.ApiLayoutRepository; import com.eactive.testmaster.client.repository.ApiRequestRepository; import com.eactive.testmaster.common.mapper.CommonMapper; import com.eactive.testmaster.server.mapper.ServerMapper; +import java.util.Comparator; +import java.util.List; +import org.mapstruct.AfterMapping; import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; import org.mapstruct.ReportingPolicy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.util.List; - @Mapper(componentModel = "spring", - uses = {CommonMapper.class, ServerMapper.class}, - unmappedTargetPolicy = ReportingPolicy.IGNORE) + uses = {CommonMapper.class, ServerMapper.class}, + unmappedTargetPolicy = ReportingPolicy.IGNORE) @Component public abstract class ApiRequestMapper { @Autowired private ApiRequestRepository apiRequestRepository; + @Autowired + private ApiLayoutRepository apiLayoutRepository; + + @Autowired + private ApiLayoutMapper apiLayoutMapper; + public abstract ApiCollection map(ApiCollectionDTO dto); public abstract ApiRequestInfo map(ApiRequestDTO dto); + @Mapping(target = "layout", ignore = true) public abstract ApiRequestDTO map(ApiRequestInfo entity); + public String mapId(ApiRequestInfo entity) { + if (entity == null) { + return null; + } + return entity.getId(); + } + public ApiRequestInfo map(String id) { - if(id == null) { + if (id == null) { return null; } return apiRequestRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("No ApiRequest found for ID: " + id)); } + @AfterMapping + public void handleTypeSpecificMapping(ApiRequestInfo entity, @MappingTarget ApiRequestDTO dto) { + if ("TCP".equals(entity.getType())) { + ApiLayout layout = apiLayoutRepository.findFirstByApiRequestInfo(entity); + if (layout!=null) { + layout.getLayoutItems().sort(Comparator.comparingInt(ApiLayoutItem::getLoutItemSerno)); + dto.setLayout(apiLayoutMapper.map(layout)); + } + } + } + + + public abstract List mapApis(List apis); public abstract List mapCollections(List apis); diff --git a/src/main/java/com/eactive/testmaster/client/repository/ApiLayoutItemRepository.java b/src/main/java/com/eactive/testmaster/client/repository/ApiLayoutItemRepository.java new file mode 100644 index 0000000..b20b87d --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/repository/ApiLayoutItemRepository.java @@ -0,0 +1,9 @@ +package com.eactive.testmaster.client.repository; + +import com.eactive.testmaster.client.entity.ApiLayoutItem; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface ApiLayoutItemRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/src/main/java/com/eactive/testmaster/client/repository/ApiLayoutRepository.java b/src/main/java/com/eactive/testmaster/client/repository/ApiLayoutRepository.java new file mode 100644 index 0000000..f889712 --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/repository/ApiLayoutRepository.java @@ -0,0 +1,11 @@ +package com.eactive.testmaster.client.repository; + +import com.eactive.testmaster.client.entity.ApiLayout; +import com.eactive.testmaster.client.entity.ApiRequestInfo; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface ApiLayoutRepository extends JpaRepository, JpaSpecificationExecutor { + + ApiLayout findFirstByApiRequestInfo(ApiRequestInfo apiRequestInfo); +} diff --git a/src/main/java/com/eactive/testmaster/client/service/ApiLayoutMgmtService.java b/src/main/java/com/eactive/testmaster/client/service/ApiLayoutMgmtService.java new file mode 100644 index 0000000..ecf865c --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/service/ApiLayoutMgmtService.java @@ -0,0 +1,86 @@ +package com.eactive.testmaster.client.service; + + +import com.eactive.testmaster.client.entity.ApiLayout; +import com.eactive.testmaster.client.entity.ApiRequestInfo; +import com.eactive.testmaster.client.repository.ApiLayoutRepository; +import com.eactive.testmaster.client.repository.ApiRequestRepository; +import com.eactive.testmaster.common.exception.NotFoundException; +import java.util.UUID; +import javax.transaction.Transactional; +import org.springframework.stereotype.Service; + +@Service +@Transactional +public class ApiLayoutMgmtService { + + private final ApiLayoutRepository apiLayoutRepository; + + private final ApiRequestRepository apiRequestRepository; + + public ApiLayoutMgmtService(ApiRequestRepository apiRequestRepository, ApiLayoutRepository apiLayoutRepository) { + this.apiRequestRepository = apiRequestRepository; + this.apiLayoutRepository = apiLayoutRepository; + } + + public ApiLayout findLayoutByApiRequest(String apiRequestId) { + ApiRequestInfo apiRequestInfo = apiRequestRepository.findById(apiRequestId) + .orElseThrow(() -> new NotFoundException(String.format("ApiRequestInfo with ID %s not found", apiRequestId))); + + return apiLayoutRepository.findFirstByApiRequestInfo(apiRequestInfo); + } + + public ApiLayout saveLayout(ApiLayout layout) { + if (layout.getId() == null) { + return createLayout(layout); + } else { + return updateLayout(layout.getId(), layout); + } + } + + public ApiLayout createLayout(ApiLayout layout) { + layout.setId(UUID.randomUUID().toString()); + if (layout.getLayoutItems() != null && !layout.getLayoutItems().isEmpty()) { + layout.getLayoutItems().forEach(layoutItem -> { + layoutItem.setApiLayout(layout); + }); + } + return apiLayoutRepository.save(layout); + } + + public ApiLayout updateLayout(String layoutId, ApiLayout updatedLayout) { + ApiLayout layout = apiLayoutRepository.findById(layoutId) + .orElseThrow(() -> new NotFoundException(String.format("Layout with ID %s not found", layoutId))); + + // Update fields based on the values provided in updatedLayout + layout.setLoutName(updatedLayout.getLoutName()); + layout.setLoutDesc(updatedLayout.getLoutDesc()); + layout.setLoutPtrnName(updatedLayout.getLoutPtrnName()); + layout.setLoutDesc(updatedLayout.getLoutDesc()); + layout.setEaiBzwkDstCd(updatedLayout.getEaiBzwkDstCd()); + layout.setUApplName(updatedLayout.getUApplName()); + layout.setSysIntFacName(updatedLayout.getSysIntFacName()); + layout.setAuthor(updatedLayout.getAuthor()); + layout.setEaiSevRdStCd(updatedLayout.getEaiSevRdStCd()); + layout.setModfMgtStusDstCd(updatedLayout.getModfMgtStusDstCd()); + layout.setUseYn(updatedLayout.getUseYn()); + layout.setVerInfo(updatedLayout.getVerInfo()); + + if (updatedLayout.getLayoutItems() != null && !updatedLayout.getLayoutItems().isEmpty()) { + layout.getLayoutItems().clear(); + updatedLayout.getLayoutItems().forEach(layoutItem -> { + layoutItem.setApiLayout(layout); // Set back reference to layout + layout.getLayoutItems().add(layoutItem); + }); + } + + return apiLayoutRepository.save(layout); + } + + // Method to delete a layout + public void deleteLayout(String id) { + ApiLayout layout = apiLayoutRepository.findById(id) + .orElseThrow(() -> new NotFoundException(String.format("Layout with ID %s not found", id))); + apiLayoutRepository.delete(layout); + } +} diff --git a/src/main/java/com/eactive/testmaster/client/service/NettyTcpApiClient.java b/src/main/java/com/eactive/testmaster/client/service/NettyTcpApiClient.java index 0c0c09d..aafe9ae 100644 --- a/src/main/java/com/eactive/testmaster/client/service/NettyTcpApiClient.java +++ b/src/main/java/com/eactive/testmaster/client/service/NettyTcpApiClient.java @@ -85,22 +85,6 @@ public class NettyTcpApiClient implements ApiClient { ChannelFuture f = b.connect(host, port).sync(); f.channel().closeFuture().sync(); - // Wait for the response return answer.take(); // This will block until a message is available } - - -// public static void main(String[] args) { -// NettyTcpApiClient client = new NettyTcpApiClient(); -// try { -// String response = client.sendMessage("localhost", 30913, "00340000BASICTST010134567890ABCDEF"); -// System.out.println("Server replied: " + response); -// } catch (InterruptedException e) { -// Thread.currentThread().interrupt(); -// e.printStackTrace(); -// } finally { -// client.shutdown(); -// } -// } - } diff --git a/src/main/java/com/eactive/testmaster/client/service/internal/FixedLengthFrameDecoder.java b/src/main/java/com/eactive/testmaster/client/service/internal/FixedLengthFrameDecoder.java new file mode 100644 index 0000000..bd7c9e5 --- /dev/null +++ b/src/main/java/com/eactive/testmaster/client/service/internal/FixedLengthFrameDecoder.java @@ -0,0 +1,25 @@ +package com.eactive.testmaster.client.service.internal; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; +import java.util.List; + +public class FixedLengthFrameDecoder extends ByteToMessageDecoder { + private final int frameLength; + + public FixedLengthFrameDecoder(int frameLength) { + if (frameLength <= 0) { + throw new IllegalArgumentException("frameLength must be a positive integer: " + frameLength); + } + this.frameLength = frameLength; + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) { + while (in.readableBytes() >= frameLength) { + ByteBuf buf = in.readBytes(frameLength); + out.add(buf); + } + } +} diff --git a/src/main/java/com/eactive/testmaster/server/dto/ServerDTO.java b/src/main/java/com/eactive/testmaster/server/dto/ServerDTO.java index ad8ffaf..b7b4118 100644 --- a/src/main/java/com/eactive/testmaster/server/dto/ServerDTO.java +++ b/src/main/java/com/eactive/testmaster/server/dto/ServerDTO.java @@ -22,6 +22,18 @@ public class ServerDTO { private boolean enabled = true; + private boolean messageKeyInclude = false; + + private Integer messageKeyOffset; + + private Integer messageKeyLength; + + private boolean lengthFieldInclude = false; + + private Integer lengthFieldOffset; + + private Integer lengthFieldLength; + public Long getId() { return id; } @@ -77,4 +89,52 @@ public class ServerDTO { public void setEnabled(boolean enabled) { this.enabled = enabled; } + + public boolean isMessageKeyInclude() { + return messageKeyInclude; + } + + public void setMessageKeyInclude(boolean messageKeyInclude) { + this.messageKeyInclude = messageKeyInclude; + } + + public Integer getMessageKeyOffset() { + return messageKeyOffset; + } + + public void setMessageKeyOffset(Integer messageKeyOffset) { + this.messageKeyOffset = messageKeyOffset; + } + + public Integer getMessageKeyLength() { + return messageKeyLength; + } + + public void setMessageKeyLength(Integer messageKeyLength) { + this.messageKeyLength = messageKeyLength; + } + + public boolean isLengthFieldInclude() { + return lengthFieldInclude; + } + + public void setLengthFieldInclude(boolean lengthFieldInclude) { + this.lengthFieldInclude = lengthFieldInclude; + } + + public Integer getLengthFieldOffset() { + return lengthFieldOffset; + } + + public void setLengthFieldOffset(Integer lengthFieldOffset) { + this.lengthFieldOffset = lengthFieldOffset; + } + + public Integer getLengthFieldLength() { + return lengthFieldLength; + } + + public void setLengthFieldLength(Integer lengthFieldLength) { + this.lengthFieldLength = lengthFieldLength; + } } diff --git a/src/main/java/com/eactive/testmaster/server/entity/Server.java b/src/main/java/com/eactive/testmaster/server/entity/Server.java index e943e19..d4f3aa3 100644 --- a/src/main/java/com/eactive/testmaster/server/entity/Server.java +++ b/src/main/java/com/eactive/testmaster/server/entity/Server.java @@ -23,6 +23,24 @@ public class Server { @Column(name = "IS_ENABLED", columnDefinition = "boolean default true") private boolean enabled; + @Column(name = "MESSAGE_KEY_INCLUDE", columnDefinition = "boolean default false") + private boolean messageKeyInclude; + + @Column(name = "MESSAGE_KEY_OFFSET", columnDefinition = "integer") + private Integer messageKeyOffset; + + @Column(name = "MESSAGE_KEY_LENGTH", columnDefinition = "integer") + private Integer messageKeyLength; + + @Column(name = "LENGTH_FIELD_INCLUDE", columnDefinition = "boolean default false") + private boolean lengthFieldInclude; + + @Column(name = "LENGTH_FIELD_OFFSET", columnDefinition = "integer") + private Integer lengthFieldOffset; + + @Column(name = "LENGTH_FIELD_LENGTH", columnDefinition = "integer") + private Integer lengthFieldLength; + public Long getId() { return id; } @@ -71,7 +89,6 @@ public class Server { this.port = port; } - public boolean isEnabled() { return enabled; } @@ -80,6 +97,54 @@ public class Server { this.enabled = enabled; } + public boolean isMessageKeyInclude() { + return messageKeyInclude; + } + + public void setMessageKeyInclude(boolean messageKeyInclude) { + this.messageKeyInclude = messageKeyInclude; + } + + public boolean isLengthFieldInclude() { + return lengthFieldInclude; + } + + public void setLengthFieldInclude(boolean lengthFieldInclude) { + this.lengthFieldInclude = lengthFieldInclude; + } + + public Integer getMessageKeyOffset() { + return messageKeyOffset; + } + + public void setMessageKeyOffset(Integer messageKeyOffset) { + this.messageKeyOffset = messageKeyOffset; + } + + public Integer getMessageKeyLength() { + return messageKeyLength; + } + + public void setMessageKeyLength(Integer messageKeyLength) { + this.messageKeyLength = messageKeyLength; + } + + public Integer getLengthFieldOffset() { + return lengthFieldOffset; + } + + public void setLengthFieldOffset(Integer lengthFieldOffset) { + this.lengthFieldOffset = lengthFieldOffset; + } + + public Integer getLengthFieldLength() { + return lengthFieldLength; + } + + public void setLengthFieldLength(Integer lengthFieldLength) { + this.lengthFieldLength = lengthFieldLength; + } + @Transient public String getFullHostAddress() { return scheme + "://" + hostname + (port == null ? "" : ":" + port) + basePath; diff --git a/src/main/java/com/eactive/testmaster/server/mapper/ServerMapper.java b/src/main/java/com/eactive/testmaster/server/mapper/ServerMapper.java index 959861c..84c1013 100644 --- a/src/main/java/com/eactive/testmaster/server/mapper/ServerMapper.java +++ b/src/main/java/com/eactive/testmaster/server/mapper/ServerMapper.java @@ -47,6 +47,12 @@ public class ServerMapper { dto.setScheme(server.getScheme()); dto.setBasePath(server.getBasePath()); dto.setEnabled(server.isEnabled()); + dto.setLengthFieldInclude(server.isLengthFieldInclude()); + dto.setMessageKeyInclude(server.isMessageKeyInclude()); + dto.setLengthFieldLength(server.getLengthFieldLength()); + dto.setLengthFieldOffset(server.getLengthFieldOffset()); + dto.setMessageKeyLength(server.getMessageKeyLength()); + dto.setMessageKeyOffset(server.getMessageKeyOffset()); return dto; } @@ -66,6 +72,12 @@ public class ServerMapper { server.setScheme(dto.getScheme()); server.setBasePath(dto.getBasePath()); server.setEnabled(dto.isEnabled()); + server.setLengthFieldInclude(dto.isLengthFieldInclude()); + server.setMessageKeyInclude(dto.isMessageKeyInclude()); + server.setLengthFieldLength(dto.getLengthFieldLength()); + server.setLengthFieldOffset(dto.getLengthFieldOffset()); + server.setMessageKeyLength(dto.getMessageKeyLength()); + server.setMessageKeyOffset(dto.getMessageKeyOffset()); return server; } diff --git a/src/main/java/com/eactive/testmaster/server/service/ServerMgmtService.java b/src/main/java/com/eactive/testmaster/server/service/ServerMgmtService.java index 376a3bf..1d3ac70 100644 --- a/src/main/java/com/eactive/testmaster/server/service/ServerMgmtService.java +++ b/src/main/java/com/eactive/testmaster/server/service/ServerMgmtService.java @@ -39,6 +39,12 @@ public class ServerMgmtService { server.setBasePath(updated.getBasePath()); server.setPort(updated.getPort()); server.setEnabled(updated.isEnabled()); + server.setLengthFieldInclude(updated.isLengthFieldInclude()); + server.setMessageKeyInclude(updated.isMessageKeyInclude()); + server.setMessageKeyLength(updated.getMessageKeyLength()); + server.setMessageKeyOffset(updated.getMessageKeyOffset()); + server.setLengthFieldLength(updated.getLengthFieldLength()); + server.setLengthFieldOffset(updated.getLengthFieldOffset()); serverRepository.save(server); diff --git a/src/main/resources/static/css/custom.css b/src/main/resources/static/css/custom.css index 733df47..e1bf241 100644 --- a/src/main/resources/static/css/custom.css +++ b/src/main/resources/static/css/custom.css @@ -2030,3 +2030,16 @@ footer div.foot_info span { .query_params .prop-table { width: calc(100vw - 240px); } + + +.layout_table { + width: 1500px; +} + +.api_request_info .show { + display: block; +} + +.api_request_info .hide { + display: none; +} diff --git a/src/main/resources/static/plugins/apitestmanager/app.bundle.js b/src/main/resources/static/plugins/apitestmanager/app.bundle.js index 3abcb58..77f42c6 100644 --- a/src/main/resources/static/plugins/apitestmanager/app.bundle.js +++ b/src/main/resources/static/plugins/apitestmanager/app.bundle.js @@ -510,7 +510,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _regeneratorRuntime() { \"use strict\"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = \"function\" == typeof Symbol ? Symbol : {}, a = i.iterator || \"@@iterator\", c = i.asyncIterator || \"@@asyncIterator\", u = i.toStringTag || \"@@toStringTag\"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, \"\"); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, \"_invoke\", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: \"normal\", arg: t.call(e, r) }; } catch (t) { return { type: \"throw\", arg: t }; } } e.wrap = wrap; var h = \"suspendedStart\", l = \"suspendedYield\", f = \"executing\", s = \"completed\", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { [\"next\", \"throw\", \"return\"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if (\"throw\" !== c.type) { var u = c.arg, h = u.value; return h && \"object\" == _typeof(h) && n.call(h, \"__await\") ? e.resolve(h.__await).then(function (t) { invoke(\"next\", t, i, a); }, function (t) { invoke(\"throw\", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke(\"throw\", t, i, a); }); } a(c.arg); } var r; o(this, \"_invoke\", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error(\"Generator is already running\"); if (o === s) { if (\"throw\" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if (\"next\" === n.method) n.sent = n._sent = n.arg;else if (\"throw\" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else \"return\" === n.method && n.abrupt(\"return\", n.arg); o = f; var p = tryCatch(e, r, n); if (\"normal\" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } \"throw\" === p.type && (o = s, n.method = \"throw\", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, \"throw\" === n && e.iterator[\"return\"] && (r.method = \"return\", r.arg = t, maybeInvokeDelegate(e, r), \"throw\" === r.method) || \"return\" !== n && (r.method = \"throw\", r.arg = new TypeError(\"The iterator does not provide a '\" + n + \"' method\")), y; var i = tryCatch(o, e.iterator, r.arg); if (\"throw\" === i.type) return r.method = \"throw\", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, \"return\" !== r.method && (r.method = \"next\", r.arg = t), r.delegate = null, y) : a : (r.method = \"throw\", r.arg = new TypeError(\"iterator result is not an object\"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = \"normal\", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: \"root\" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || \"\" === e) { var r = e[a]; if (r) return r.call(e); if (\"function\" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + \" is not iterable\"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, \"constructor\", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, \"constructor\", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, \"GeneratorFunction\"), e.isGeneratorFunction = function (t) { var e = \"function\" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || \"GeneratorFunction\" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, \"GeneratorFunction\")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, \"Generator\"), define(g, a, function () { return this; }), define(g, \"toString\", function () { return \"[object Generator]\"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = \"next\", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) \"t\" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if (\"throw\" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = \"throw\", a.arg = e, r.next = n, o && (r.method = \"next\", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if (\"root\" === i.tryLoc) return handle(\"end\"); if (i.tryLoc <= this.prev) { var c = n.call(i, \"catchLoc\"), u = n.call(i, \"finallyLoc\"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error(\"try statement without catch or finally\"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, \"finallyLoc\") && this.prev < o.finallyLoc) { var i = o; break; } } i && (\"break\" === t || \"continue\" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = \"next\", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if (\"throw\" === t.type) throw t.arg; return \"break\" === t.type || \"continue\" === t.type ? this.next = t.arg : \"return\" === t.type ? (this.rval = this.arg = t.arg, this.method = \"return\", this.next = \"end\") : \"normal\" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, \"catch\": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if (\"throw\" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error(\"illegal catch attempt\"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, \"next\" === this.method && (this.arg = t), y; } }, e; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \"prototype\", { writable: false }); return Constructor; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : String(i); }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n/**\n * 처리 순서\n * 1. preRequestScript 실행 -> executePreRequestScript\n * 2. 변수 치환 -> replacePlaceholdersWithVariables\n * 3. API 호출 -> sendAPIRequest\n * 4. postRequestScript 실행 -> executePostRequestScript\n */\nvar APIClient = /*#__PURE__*/function () {\n function APIClient() {\n _classCallCheck(this, APIClient);\n _defineProperty(this, \"CLIENT_URL\", 'mgmt/api/test.do');\n window.globals = {};\n this.abortController = null;\n this.contextPath = document.querySelector('meta[name=\"context-path\"]').getAttribute('content');\n if (!this.contextPath) {\n this.contextPath = '/';\n }\n if (!this.contextPath.endsWith('/')) {\n this.contextPath += '/';\n }\n }\n _createClass(APIClient, [{\n key: \"getClientUrl\",\n value: function getClientUrl() {\n return this.contextPath + this.CLIENT_URL;\n }\n }, {\n key: \"sendAPIRequest\",\n value: function () {\n var _sendAPIRequest = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(model, preProcessCallback, consoleOutput) {\n var variables, updatedModel, processedRequest, response, responseData, errorMessage, finalResponse;\n return _regeneratorRuntime().wrap(function _callee$(_context) {\n while (1) switch (_context.prev = _context.next) {\n case 0:\n _context.prev = 0;\n variables = {};\n _context.next = 4;\n return this.executePreRequestScript(model, variables, consoleOutput);\n case 4:\n updatedModel = _context.sent;\n processedRequest = this.replacePlaceholdersWithVariables(updatedModel, variables);\n if (preProcessCallback) {\n preProcessCallback(processedRequest);\n }\n _context.next = 9;\n return this.makeAjaxRequest(processedRequest, model, consoleOutput);\n case 9:\n response = _context.sent;\n _context.next = 12;\n return response.json();\n case 12:\n responseData = _context.sent;\n if (response.ok) {\n _context.next = 16;\n break;\n }\n errorMessage = responseData.error || 'Unknown error';\n throw new Error(\"API \\uD638\\uCD9C \\uC911 \\uC624\\uB958\\uAC00 \\uBC1C\\uC0DD\\uD588\\uC2B5\\uB2C8\\uB2E4. \\uC0AC\\uC720[\".concat(errorMessage, \"]\"));\n case 16:\n finalResponse = this.formatResponse(responseData);\n return _context.abrupt(\"return\", this.executePostRequestScript(model.postRequestScript, variables, processedRequest, finalResponse, consoleOutput)[\"catch\"](function (error) {\n $('.toast-body').text(error);\n $('.toast').toast('show');\n return finalResponse; // Return the original response even if there's an error in the post-request script\n }));\n case 20:\n _context.prev = 20;\n _context.t0 = _context[\"catch\"](0);\n throw _context.t0;\n case 23:\n case \"end\":\n return _context.stop();\n }\n }, _callee, this, [[0, 20]]);\n }));\n function sendAPIRequest(_x, _x2, _x3) {\n return _sendAPIRequest.apply(this, arguments);\n }\n return sendAPIRequest;\n }()\n }, {\n key: \"formatResponse\",\n value: function formatResponse(data) {\n // Format response as needed before post-request script\n var response = {};\n response.body = data.body;\n response.status = data.status;\n response.headers = {};\n response.size = data.size;\n _.forEach(data.headers, function (header) {\n response.headers[header.key] = header.value;\n });\n return response;\n }\n }, {\n key: \"abort\",\n value: function abort() {\n if (this.abortController) {\n this.abortController.abort(); // abort the fetch\n this.abortController = null; // reset the controller\n }\n }\n }, {\n key: \"makeAjaxRequest\",\n value: function makeAjaxRequest(processedRequest, model) {\n this.abortController = new AbortController();\n var signal = this.abortController.signal;\n try {\n return fetch(this.getClientUrl(), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-XSRF-TOKEN': $('meta[name=\"_csrf\"]').attr('content')\n },\n body: JSON.stringify(processedRequest),\n signal: signal // pass the signal to the fetch\n });\n } catch (error) {\n if (error.name !== 'AbortError') {\n console.error('Network request failed:', error);\n }\n throw error;\n }\n }\n }, {\n key: \"replacePlaceholdersWithVariables\",\n value: function replacePlaceholdersWithVariables(original, variables) {\n var request = JSON.parse(JSON.stringify(original));\n var mergedVariables = {};\n _.forEach(window.globals, function (value, key) {\n mergedVariables[key] = value;\n });\n if (variables) {\n _.forEach(variables, function (value, key) {\n mergedVariables[key] = value;\n });\n }\n _.forEach(mergedVariables, function (value, key) {\n var placeholder = \"{{\".concat(key, \"}}\");\n // Replace in path\n request.path = request.path.replace(new RegExp(placeholder, 'g'), value);\n\n // Replace in requestBody\n if (request.requestBody) {\n request.requestBody = request.requestBody.replace(new RegExp(placeholder, 'g'), value);\n }\n\n // Replace in headers\n if (request.headers) {\n var replaced = JSON.stringify(request.headers).replace(new RegExp(placeholder, 'g'), value);\n request.headers = JSON.parse(replaced);\n }\n\n // Replace in queryParams\n if (request.queryParams) {\n var _replaced = JSON.stringify(request.queryParams).replace(new RegExp(placeholder, 'g'), value);\n request.queryParams = JSON.parse(_replaced);\n }\n });\n return request;\n }\n }, {\n key: \"executePreRequestScript\",\n value: function executePreRequestScript(model, variables, consoleOutput) {\n return new Promise(function (resolve, reject) {\n var script = model.preRequestScript;\n var resultFrame = document.getElementById('preRequest');\n window.preRequestComplete = function (updatedModel, error) {\n if (error) {\n reject(error);\n } else {\n resolve(updatedModel);\n }\n };\n window.temp_variable = variables;\n window.currentRequest = model;\n window.consoleOutput = consoleOutput;\n resultFrame.srcdoc = \"\");\n });\n }\n }, {\n key: \"executePostRequestScript\",\n value: function executePostRequestScript(script, variables, request, response, consoleOutput) {\n return new Promise(function (resolve, reject) {\n var resultFrame = document.getElementById('postRequest');\n window.request = request;\n window.response = response;\n window.temp_variable = variables;\n window.postRequestComplete = function (response, error) {\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n };\n window.consoleOutput = consoleOutput;\n resultFrame.srcdoc = \"\");\n });\n }\n }]);\n return APIClient;\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (APIClient);\n\n//# sourceURL=webpack://APITestManager/./src/APIClient.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _regeneratorRuntime() { \"use strict\"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = \"function\" == typeof Symbol ? Symbol : {}, a = i.iterator || \"@@iterator\", c = i.asyncIterator || \"@@asyncIterator\", u = i.toStringTag || \"@@toStringTag\"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, \"\"); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, \"_invoke\", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: \"normal\", arg: t.call(e, r) }; } catch (t) { return { type: \"throw\", arg: t }; } } e.wrap = wrap; var h = \"suspendedStart\", l = \"suspendedYield\", f = \"executing\", s = \"completed\", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { [\"next\", \"throw\", \"return\"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if (\"throw\" !== c.type) { var u = c.arg, h = u.value; return h && \"object\" == _typeof(h) && n.call(h, \"__await\") ? e.resolve(h.__await).then(function (t) { invoke(\"next\", t, i, a); }, function (t) { invoke(\"throw\", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke(\"throw\", t, i, a); }); } a(c.arg); } var r; o(this, \"_invoke\", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error(\"Generator is already running\"); if (o === s) { if (\"throw\" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if (\"next\" === n.method) n.sent = n._sent = n.arg;else if (\"throw\" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else \"return\" === n.method && n.abrupt(\"return\", n.arg); o = f; var p = tryCatch(e, r, n); if (\"normal\" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } \"throw\" === p.type && (o = s, n.method = \"throw\", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, \"throw\" === n && e.iterator[\"return\"] && (r.method = \"return\", r.arg = t, maybeInvokeDelegate(e, r), \"throw\" === r.method) || \"return\" !== n && (r.method = \"throw\", r.arg = new TypeError(\"The iterator does not provide a '\" + n + \"' method\")), y; var i = tryCatch(o, e.iterator, r.arg); if (\"throw\" === i.type) return r.method = \"throw\", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, \"return\" !== r.method && (r.method = \"next\", r.arg = t), r.delegate = null, y) : a : (r.method = \"throw\", r.arg = new TypeError(\"iterator result is not an object\"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = \"normal\", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: \"root\" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || \"\" === e) { var r = e[a]; if (r) return r.call(e); if (\"function\" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + \" is not iterable\"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, \"constructor\", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, \"constructor\", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, \"GeneratorFunction\"), e.isGeneratorFunction = function (t) { var e = \"function\" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || \"GeneratorFunction\" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, \"GeneratorFunction\")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, \"Generator\"), define(g, a, function () { return this; }), define(g, \"toString\", function () { return \"[object Generator]\"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = \"next\", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) \"t\" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if (\"throw\" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = \"throw\", a.arg = e, r.next = n, o && (r.method = \"next\", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if (\"root\" === i.tryLoc) return handle(\"end\"); if (i.tryLoc <= this.prev) { var c = n.call(i, \"catchLoc\"), u = n.call(i, \"finallyLoc\"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error(\"try statement without catch or finally\"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, \"finallyLoc\") && this.prev < o.finallyLoc) { var i = o; break; } } i && (\"break\" === t || \"continue\" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = \"next\", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if (\"throw\" === t.type) throw t.arg; return \"break\" === t.type || \"continue\" === t.type ? this.next = t.arg : \"return\" === t.type ? (this.rval = this.arg = t.arg, this.method = \"return\", this.next = \"end\") : \"normal\" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, \"catch\": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if (\"throw\" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error(\"illegal catch attempt\"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, \"next\" === this.method && (this.arg = t), y; } }, e; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \"prototype\", { writable: false }); return Constructor; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : String(i); }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n/**\n * 처리 순서\n * 1. preRequestScript 실행 -> executePreRequestScript\n * 2. 변수 치환 -> replacePlaceholdersWithVariables\n * 3. API 호출 -> sendAPIRequest\n * 4. postRequestScript 실행 -> executePostRequestScript\n */\nvar APIClient = /*#__PURE__*/function () {\n function APIClient() {\n _classCallCheck(this, APIClient);\n _defineProperty(this, \"CLIENT_URL\", 'mgmt/api/test.do');\n window.globals = {};\n this.abortController = null;\n this.contextPath = document.querySelector('meta[name=\"context-path\"]').getAttribute('content');\n if (!this.contextPath) {\n this.contextPath = '/';\n }\n if (!this.contextPath.endsWith('/')) {\n this.contextPath += '/';\n }\n }\n _createClass(APIClient, [{\n key: \"getClientUrl\",\n value: function getClientUrl() {\n return this.contextPath + this.CLIENT_URL;\n }\n }, {\n key: \"formatResponse\",\n value: function formatResponse(data) {\n // Format response as needed before post-request script\n var response = {};\n response.body = data.body;\n response.status = data.status;\n response.headers = {};\n response.size = data.size;\n _.forEach(data.headers, function (header) {\n response.headers[header.key] = header.value;\n });\n return response;\n }\n }, {\n key: \"abort\",\n value: function abort() {\n if (this.abortController) {\n this.abortController.abort(); // abort the fetch\n this.abortController = null; // reset the controller\n }\n }\n }, {\n key: \"makeAjaxRequest\",\n value: function makeAjaxRequest(processedRequest, model) {\n this.abortController = new AbortController();\n var signal = this.abortController.signal;\n try {\n return fetch(this.getClientUrl(), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-XSRF-TOKEN': $('meta[name=\"_csrf\"]').attr('content')\n },\n body: JSON.stringify(processedRequest),\n signal: signal // pass the signal to the fetch\n });\n } catch (error) {\n if (error.name !== 'AbortError') {\n console.error('Network request failed:', error);\n }\n throw error;\n }\n }\n }, {\n key: \"processPreScriptAndVariables\",\n value: function () {\n var _processPreScriptAndVariables = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(model, value, consoleOutput) {\n var variables, updatedModel;\n return _regeneratorRuntime().wrap(function _callee$(_context) {\n while (1) switch (_context.prev = _context.next) {\n case 0:\n variables = {};\n _context.next = 3;\n return this.executePreRequestScript(model, variables, consoleOutput);\n case 3:\n updatedModel = _context.sent;\n return _context.abrupt(\"return\", this.replacePlaceholderValueWithVariables(updatedModel, value, variables));\n case 5:\n case \"end\":\n return _context.stop();\n }\n }, _callee, this);\n }));\n function processPreScriptAndVariables(_x, _x2, _x3) {\n return _processPreScriptAndVariables.apply(this, arguments);\n }\n return processPreScriptAndVariables;\n }()\n }, {\n key: \"replacePlaceholderValueWithVariables\",\n value: function replacePlaceholderValueWithVariables(model, originalValue, variables) {\n var mergedVariables = {};\n _.forEach(window.globals, function (value, key) {\n mergedVariables[key] = value;\n });\n if (variables) {\n _.forEach(variables, function (value, key) {\n mergedVariables[key] = value;\n });\n }\n _.forEach(mergedVariables, function (value, key) {\n var placeholder = \"{{\".concat(key, \"}}\");\n // Replace in path\n originalValue = originalValue.replace(new RegExp(placeholder, 'g'), value);\n });\n return originalValue;\n }\n }, {\n key: \"sendAPIRequest\",\n value: function () {\n var _sendAPIRequest = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(model, preProcessCallback, consoleOutput) {\n var variables, updatedModel, processedRequest, response, responseData, errorMessage, finalResponse;\n return _regeneratorRuntime().wrap(function _callee2$(_context2) {\n while (1) switch (_context2.prev = _context2.next) {\n case 0:\n _context2.prev = 0;\n variables = {};\n _context2.next = 4;\n return this.executePreRequestScript(model, variables, consoleOutput);\n case 4:\n updatedModel = _context2.sent;\n processedRequest = this.replacePlaceholdersWithVariables(updatedModel, variables);\n if (preProcessCallback) {\n preProcessCallback(processedRequest);\n }\n _context2.next = 9;\n return this.makeAjaxRequest(processedRequest, model, consoleOutput);\n case 9:\n response = _context2.sent;\n _context2.next = 12;\n return response.json();\n case 12:\n responseData = _context2.sent;\n if (response.ok) {\n _context2.next = 16;\n break;\n }\n errorMessage = responseData.error || 'Unknown error';\n throw new Error(\"API \\uD638\\uCD9C \\uC911 \\uC624\\uB958\\uAC00 \\uBC1C\\uC0DD\\uD588\\uC2B5\\uB2C8\\uB2E4. \\uC0AC\\uC720[\".concat(errorMessage, \"]\"));\n case 16:\n finalResponse = this.formatResponse(responseData);\n return _context2.abrupt(\"return\", this.executePostRequestScript(model.postRequestScript, variables, processedRequest, finalResponse, consoleOutput)[\"catch\"](function (error) {\n $('.toast-body').text(error);\n $('.toast').toast('show');\n return finalResponse; // Return the original response even if there's an error in the post-request script\n }));\n case 20:\n _context2.prev = 20;\n _context2.t0 = _context2[\"catch\"](0);\n throw _context2.t0;\n case 23:\n case \"end\":\n return _context2.stop();\n }\n }, _callee2, this, [[0, 20]]);\n }));\n function sendAPIRequest(_x4, _x5, _x6) {\n return _sendAPIRequest.apply(this, arguments);\n }\n return sendAPIRequest;\n }()\n }, {\n key: \"replacePlaceholdersWithVariables\",\n value: function replacePlaceholdersWithVariables(original, variables) {\n var request = JSON.parse(JSON.stringify(original));\n var mergedVariables = {};\n _.forEach(window.globals, function (value, key) {\n mergedVariables[key] = value;\n });\n if (variables) {\n _.forEach(variables, function (value, key) {\n mergedVariables[key] = value;\n });\n }\n _.forEach(mergedVariables, function (value, key) {\n var placeholder = \"{{\".concat(key, \"}}\");\n // Replace in path\n request.path = request.path.replace(new RegExp(placeholder, 'g'), value);\n\n // Replace in requestBody\n if (request.requestBody) {\n request.requestBody = request.requestBody.replace(new RegExp(placeholder, 'g'), value);\n }\n\n // Replace in headers\n if (request.headers) {\n var replaced = JSON.stringify(request.headers).replace(new RegExp(placeholder, 'g'), value);\n request.headers = JSON.parse(replaced);\n }\n\n // Replace in queryParams\n if (request.queryParams) {\n var _replaced = JSON.stringify(request.queryParams).replace(new RegExp(placeholder, 'g'), value);\n request.queryParams = JSON.parse(_replaced);\n }\n });\n return request;\n }\n }, {\n key: \"executePreRequestScript\",\n value: function executePreRequestScript(model, variables, consoleOutput) {\n return new Promise(function (resolve, reject) {\n var script = model.preRequestScript;\n var resultFrame = document.getElementById('preRequest');\n window.preRequestComplete = function (updatedModel, error) {\n if (error) {\n reject(error);\n } else {\n resolve(updatedModel);\n }\n };\n window.temp_variable = variables;\n window.currentRequest = model;\n window.consoleOutput = consoleOutput;\n resultFrame.srcdoc = \"\");\n });\n }\n }, {\n key: \"executePostRequestScript\",\n value: function executePostRequestScript(script, variables, request, response, consoleOutput) {\n return new Promise(function (resolve, reject) {\n var resultFrame = document.getElementById('postRequest');\n window.request = request;\n window.response = response;\n window.temp_variable = variables;\n window.postRequestComplete = function (response, error) {\n if (error) {\n reject(error);\n } else {\n resolve(response);\n }\n };\n window.consoleOutput = consoleOutput;\n resultFrame.srcdoc = \"\");\n });\n }\n }]);\n return APIClient;\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (APIClient);\n\n//# sourceURL=webpack://APITestManager/./src/APIClient.js?"); /***/ }), @@ -543,7 +543,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var monaco_editor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! monaco-editor */ \"include-loader!./node_modules/monaco-editor/esm/vs/editor/editor.main.js\");\n/* harmony import */ var _APIClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./APIClient */ \"./src/APIClient.js\");\n/* harmony import */ var _components_EditableInput__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/EditableInput */ \"./src/components/EditableInput.js\");\n/* harmony import */ var _popperjs_core_lib_popper_lite__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @popperjs/core/lib/popper-lite */ \"./node_modules/@popperjs/core/lib/popper-lite.js\");\n/* harmony import */ var _components_PropertyTable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/PropertyTable */ \"./src/components/PropertyTable.js\");\n/* harmony import */ var _components_VariableSnippet__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/VariableSnippet */ \"./src/components/VariableSnippet.js\");\nfunction ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }\nfunction _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }\nfunction _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction _iterableToArrayLimit(r, l) { var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \"prototype\", { writable: false }); return Constructor; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : String(i); }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n\n\n\n\n\n\nvar APITester = /*#__PURE__*/function () {\n function APITester(contextPath) {\n _classCallCheck(this, APITester);\n this.servers = [];\n this.apiTabTitleTarget = '#apiRequestTabTitle';\n this.apiTabContentTarget = '#apiRequestTabContent';\n this.collectionTarget = '#side_menubar';\n this.currentIndex = 0;\n this.apiRequests = []; //탭 열린 API\n this.collections = []; //API 컬렉션\n this.requestEditors = []; //API request body editor\n this.responseEditors = []; //API response body editor\n this.consoleEditors = []; //API console editor\n this.preRequestEditors = [];\n this.postRequestEditors = [];\n this.apiClient = new _APIClient__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\n this.popperContent = document.getElementById('popperContent');\n this.popperInstance = null;\n this.contextPath = contextPath || '/';\n }\n _createClass(APITester, [{\n key: \"getCollectionListURL\",\n value: function getCollectionListURL() {\n return this.contextPath + 'mgmt/collections/list.do';\n }\n }, {\n key: \"getCollectionCreateURL\",\n value: function getCollectionCreateURL() {\n return this.contextPath + 'mgmt/collections/create.do';\n }\n }, {\n key: \"getCollectionUpdateURL\",\n value: function getCollectionUpdateURL() {\n return this.contextPath + 'mgmt/collections/update.do';\n }\n }, {\n key: \"getCollectionDeleteURL\",\n value: function getCollectionDeleteURL() {\n return this.contextPath + 'mgmt/collections/delete.do';\n }\n }, {\n key: \"getAPISaveURL\",\n value: function getAPISaveURL(collectionId) {\n return this.contextPath + \"mgmt/collections/\".concat(collectionId, \"/apis/save.do\");\n }\n }, {\n key: \"getAPIDeleteURL\",\n value: function getAPIDeleteURL(collectionId) {\n return this.contextPath + \"mgmt/collections/\".concat(collectionId, \"/apis/delete.do\");\n }\n }, {\n key: \"renderServers\",\n value: function renderServers(selectedServer) {\n var optionsHtml = this.servers.map(function (server) {\n return \"\");\n }).join('');\n return \"\");\n }\n }, {\n key: \"basePath\",\n value: function basePath(serverId) {\n if (serverId === undefined || serverId === null || serverId === '') {\n return '';\n }\n return this.servers.filter(function (server) {\n return server.id == serverId;\n })[0].basePath; // == : 타입 비교 없이 값만 비교\n }\n }, {\n key: \"httpApiRequestTemplate\",\n value: function httpApiRequestTemplate(apiRequest, index) {\n return \"\\n
\\n
\").concat(apiRequest.collectionName, \" > \").concat(apiRequest.name, \"
\\n
\\n
\\n \\n \\n
\\n
\\n \").concat(this.renderServers(apiRequest.server), \"\\n \\n
\\n
\\n \\n \\n
\\n
\\n \\n
\\n \\n \\n
\\n
\\n
\\n
    \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n \\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n Response\\n \\n \\n \\n
\\n
    \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
\\n
\\n
\\n
\\n
\\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
\\uC774\\uB984\\uAC12
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n \\n \");\n }\n }, {\n key: \"tcpApiRequestTemplate\",\n value: function tcpApiRequestTemplate(apiRequest, index) {\n return \"\\n
\\n
\").concat(apiRequest.collectionName, \" > \").concat(apiRequest.name, \"
\\n
\\n
\\n \").concat(this.renderServers(apiRequest.server), \"\\n \\n
\\n \\n \\n
\\n
\\n
\\n
    \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
\\n
\\n
\\n
\\n \\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n Response\\n \\n \\n \\n
\\n
    \\n
  • \\n \\n
  • \\n
  • \\n \\n
  • \\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n
\\n \\n \");\n }\n }, {\n key: \"headerTemplate\",\n value: function headerTemplate(header, index) {\n return \"\\n \\n \\n
\\n \\n
\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \");\n }\n }, {\n key: \"responseHeaderTemplate\",\n value: function responseHeaderTemplate(key, value) {\n return \"\\n \\n \\n \\n \\n \\n \\n \\n \\n \");\n }\n }, {\n key: \"collectionTemplate\",\n value: function collectionTemplate(collection, index) {\n var _this = this;\n return \"\\n
  • \\n
    \\n \\n
    \\n \\n \\n
    \\n
    \\n
    \\n
      \\n \").concat(collection.apis.map(function (api, apiIndex) {\n return _this.collectionApiTemplate(api, apiIndex, collection.id);\n }).join(''), \"\\n
    \\n
    \\n
  • \\n \");\n }\n }, {\n key: \"collectionApiTemplate\",\n value: function collectionApiTemplate(api, apiIndex, collectionId) {\n return \"\\n
  • \\n \").concat(api.name, \"\\n
    \\n \\n \\n
    \\n
  • \\n \");\n }\n }, {\n key: \"init\",\n value: function init(servers) {\n if (servers) {\n this.servers = servers;\n if (this.servers.length === 0) {\n $('.toast-body').text('서버관리에서 서버를 등록해주세요.');\n $('.toast').toast('show');\n }\n }\n this.bindEvents();\n this.loadCollections();\n }\n }, {\n key: \"bindEvents\",\n value: function bindEvents() {\n var events = [{\n selector: '.btn_add_header',\n action: this.addHeader.bind(this)\n }, {\n selector: '.btn_remove_header',\n action: this.removeHeader.bind(this)\n }, {\n selector: '.send',\n action: this.handleSendAPIRequest.bind(this)\n }, {\n selector: '.save',\n action: this.saveAPIRequest.bind(this)\n }, {\n selector: '.save_collection',\n action: this.addCollection.bind(this)\n }, {\n selector: '#cancel-ajax',\n action: this.cancelAjaxRequest.bind(this)\n }, {\n selector: '#new_collection',\n action: this.showNewCollectionModal.bind(this)\n }, {\n selector: '#new_request',\n action: this.showNewApiRequestModal.bind(this)\n }, {\n selector: '.edit_collection',\n action: this.showCollectionEditModal.bind(this)\n }, {\n selector: '.delete_collection',\n action: this.showCollectionDeleteModal.bind(this)\n }, {\n selector: '.confirm_delete',\n action: this.removeCollection.bind(this)\n }, {\n selector: '.add_new_request',\n action: this.addAPIRequest.bind(this)\n }, {\n selector: '.edit_api_request',\n action: this.showEditNameModal.bind(this)\n }, {\n selector: '.delete_api_request',\n action: this.showDeleteApiRequestModal.bind(this)\n }, {\n selector: '.open_api_request',\n action: this.openApiRequest.bind(this)\n }, {\n selector: '.confirm_delete_api',\n action: this.deleteApiRequest.bind(this)\n }, {\n selector: '.close_tab',\n action: this.closeTab.bind(this)\n }];\n for (var _i = 0, _events = events; _i < _events.length; _i++) {\n var event = _events[_i];\n $(document).on('click', event.selector, event.action);\n }\n $(document).on('change', '.path', this.parseParam.bind(this));\n $(document).on('change', '.request_headers input', this.handleUIUpdate.bind(this));\n $(document).on('change', '.api_request_info select, .api_request_info input', this.handleUIUpdate.bind(this));\n $(document).on('change', '.api_request_info select', this.handleUpdateServer.bind(this));\n window.addEventListener('resize', this.resizeEditor.bind(this));\n }\n }, {\n key: \"resizeEditor\",\n value: function resizeEditor() {\n //FIXME: 창 크기 변경시 자동으로 editor 크기가 조정되지 않아서, 0으로 강제 변경후 다시 layout() 호출\n\n for (var i = 0; i < this.requestEditors.length; i++) {\n this.requestEditors[i].layout({\n width: 0\n });\n }\n for (var _i2 = 0; _i2 < this.responseEditors.length; _i2++) {\n this.responseEditors[_i2].layout({\n width: 0\n });\n }\n for (var _i3 = 0; _i3 < this.preRequestEditors.length; _i3++) {\n this.preRequestEditors[_i3].layout({\n width: 0\n });\n }\n for (var _i4 = 0; _i4 < this.postRequestEditors.length; _i4++) {\n this.postRequestEditors[_i4].layout({\n width: 0\n });\n }\n for (var _i5 = 0; _i5 < this.requestEditors.length; _i5++) {\n this.requestEditors[_i5].layout({});\n }\n for (var _i6 = 0; _i6 < this.responseEditors.length; _i6++) {\n this.responseEditors[_i6].layout({});\n }\n for (var _i7 = 0; _i7 < this.preRequestEditors.length; _i7++) {\n this.preRequestEditors[_i7].layout({});\n }\n for (var _i8 = 0; _i8 < this.postRequestEditors.length; _i8++) {\n this.postRequestEditors[_i8].layout({});\n }\n }\n }, {\n key: \"showCollectionDeleteModal\",\n value: function showCollectionDeleteModal(event) {\n var collectionId = $(event.currentTarget).closest('button').data('collection');\n $('#confirm_delete_modal').find('.confirm_delete').data('id', collectionId);\n $('#confirm_delete_modal').modal('show');\n }\n }, {\n key: \"getApiRequestModel\",\n value: function getApiRequestModel(apiId) {\n var foundApi = null;\n this.collections.forEach(function (collection) {\n collection.apis.forEach(function (api) {\n if (api.id === apiId) {\n foundApi = api;\n }\n });\n });\n return foundApi;\n }\n }, {\n key: \"showCollectionEditModal\",\n value: function showCollectionEditModal(event) {\n var me = this;\n var collectionId = $(event.currentTarget).closest('button').data('collection');\n var collection = this.collections.filter(function (collection) {\n return collection.id === collectionId;\n })[0];\n $('#edit_name_modal').find('input').val('');\n $('#edit_name_modal').modal('show');\n var saveBtn = $('#edit_name_modal').find('button.change_name');\n saveBtn.off('click');\n saveBtn.on('click', function () {\n collection.name = $('#edit_name_modal').find('input').val();\n me.saveCollection(collection.id, collection.name);\n me.renderCollections();\n $('#edit_name_modal').modal('hide');\n });\n }\n }, {\n key: \"showDeleteApiRequestModal\",\n value: function showDeleteApiRequestModal(event) {\n var collectionId = $(event.currentTarget).closest('li').data('collection');\n var apiId = $(event.currentTarget).closest('li').data('id');\n $('#confirm_delete_api_modal').find('.confirm_delete_api').data('id', apiId);\n $('#confirm_delete_api_modal').find('.confirm_delete_api').data('collection', collectionId);\n $('#confirm_delete_api_modal').modal('show');\n }\n }, {\n key: \"showNewApiRequestModal\",\n value: function showNewApiRequestModal(event) {\n if (this.collections.length == 0) {\n $('.toast-body').text('새로운 컬렉션을 추가해 주세요.');\n $('.toast').toast('show');\n return;\n }\n $('#new_api_request_modal').modal('show');\n }\n }, {\n key: \"showNewCollectionModal\",\n value: function showNewCollectionModal(event) {\n $('#new_collection_modal').find('input').val('');\n $('#new_collection_modal').modal('show');\n }\n }, {\n key: \"showEditNameModal\",\n value: function showEditNameModal(event) {\n var me = this;\n var apiId = $(event.currentTarget).closest('li').data('id');\n var collectionId = $(event.currentTarget).closest('li').data('collection');\n var collection = this.collections.filter(function (collection) {\n return collection.id === collectionId;\n })[0];\n var apiRequest = collection.apis.filter(function (api) {\n return api.id === apiId;\n })[0];\n apiRequest.collectionId = collectionId;\n var saveBtn = $('#edit_name_modal').find('button.change_name');\n saveBtn.off('click');\n saveBtn.on('click', function () {\n apiRequest.name = $('#edit_name_modal').find('input').val();\n me.changeAPIName(apiRequest);\n me.renderCollections();\n $('#edit_name_modal').modal('hide');\n\n //탭이 열려 있으면, 닫았다가 다시 열어야 함.\n me.renderTabHeader();\n me.renderTabContent(apiRequest.index);\n });\n $('#edit_name_modal').find('input').val('');\n $('#edit_name_modal').modal('show');\n }\n }, {\n key: \"getFieldValue\",\n value: function getFieldValue(element) {\n if ($(element).is('select') || $(element).is('input[type=\"text\"]')) {\n return $(element).val();\n }\n if ($(element).is('input[type=\"checkbox\"]')) {\n return $(element).is(':checked');\n }\n }\n }, {\n key: \"handleUIUpdate\",\n value: function handleUIUpdate(event) {\n if (event) {\n event.preventDefault();\n var element = event.currentTarget;\n var fieldName = $(element).attr('name');\n var newValue = this.getFieldValue(element);\n var tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));\n var model = this.apiRequests[tabIndex];\n if (fieldName !== '') {\n _.set(model, fieldName, newValue);\n }\n }\n }\n }, {\n key: \"handleUpdateServer\",\n value: function handleUpdateServer(event) {\n var tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));\n var model = this.apiRequests[tabIndex];\n var target = $('#api_request_' + model.id);\n target.find('input[name=\"basePath\"]').val(this.basePath(model.server));\n }\n }, {\n key: \"renderHeaders\",\n value: function renderHeaders(headers) {\n var _this2 = this;\n return headers.map(function (header, index) {\n return _this2.headerTemplate(header, index);\n }).join('');\n }\n }, {\n key: \"renderTabHeader\",\n value: function renderTabHeader() {\n var apiRequestTabTitle = $(this.apiTabTitleTarget);\n apiRequestTabTitle.empty();\n for (var idx = 0; idx < this.apiRequests.length; idx++) {\n var li = \"
  • \\n \\n
  • \");\n apiRequestTabTitle.append(li);\n }\n }\n }, {\n key: \"showPopper\",\n value: function showPopper(element, text) {\n var variable = text.replace(/{{|}}/g, '');\n this.popperContent.style.display = 'block';\n var innerDiv = this.popperContent.querySelector('.variable_popper');\n innerDiv.textContent = '{{' + variable + '}} = ' + (window.globals[variable] === undefined ? '' : window.globals[variable]);\n this.popperInstance = (0,_popperjs_core_lib_popper_lite__WEBPACK_IMPORTED_MODULE_5__.createPopper)(element, this.popperContent, {\n placement: 'bottom',\n // Popper below the element\n modifiers: [{\n name: 'offset',\n options: {\n offset: [0, 8] // Adjust the position if needed\n }\n }]\n });\n }\n }, {\n key: \"hidePopper\",\n value: function hidePopper(element) {\n if (this.popperInstance) {\n this.popperInstance.destroy();\n this.popperInstance = null;\n }\n this.popperContent.style.display = 'none';\n }\n }, {\n key: \"renderTabContent\",\n value: function renderTabContent(index) {\n var _this3 = this;\n var me = this;\n var apiRequestTabContent = $(this.apiTabContentTarget);\n var model = this.apiRequests[index];\n if (model.type === 'HTTP') {\n apiRequestTabContent.append(this.httpApiRequestTemplate(model, index));\n var editableInput = new _components_EditableInput__WEBPACK_IMPORTED_MODULE_2__[\"default\"]({\n name: 'path',\n value: model.path\n });\n var queryParamTable = new _components_PropertyTable__WEBPACK_IMPORTED_MODULE_3__[\"default\"]({\n propertyName: 'queryParams',\n properties: model.queryParams\n });\n var headerTable = new _components_PropertyTable__WEBPACK_IMPORTED_MODULE_3__[\"default\"]({\n propertyName: 'headers',\n properties: model.headers\n });\n apiRequestTabContent.find(\"#api_request_\".concat(model.id)).find('.api_request_info').find('.path').each(function () {\n editableInput.init(this, function (value) {\n model.path = value;\n model.queryParams = me.parseParam(model.path);\n queryParamTable.setProperties(model.queryParams);\n $('span.variable').off('mouseover');\n $('span.variable').off('mouseout');\n document.querySelectorAll('span.variable').forEach(function (element) {\n var text = element.innerText;\n element.addEventListener('mouseover', function () {\n return me.showPopper(element, text);\n });\n element.addEventListener('mouseout', function () {\n return me.hidePopper(element);\n });\n });\n });\n $(this).append(\"\");\n $('span.variable').off('mouseover');\n $('span.variable').off('mouseout');\n });\n queryParamTable.init(apiRequestTabContent.find(\"#api_request_\".concat(model.id)).find('.query_params')[0], function (properties) {\n model.queryParams = properties;\n console.log(model.queryParams);\n _this3.buildPath(model);\n editableInput.setValue(model.path);\n $('span.variable').off('mouseover');\n $('span.variable').off('mouseout');\n document.querySelectorAll('span.variable').forEach(function (element) {\n var text = element.innerText;\n element.addEventListener('mouseover', function () {\n return me.showPopper(element, text);\n });\n element.addEventListener('mouseout', function () {\n return me.hidePopper(element);\n });\n });\n });\n headerTable.init(apiRequestTabContent.find(\"#api_request_\".concat(model.id)).find('.request_headers')[0], function (properties) {\n model.headers = properties;\n $('span.variable').off('mouseover');\n $('span.variable').off('mouseout');\n document.querySelectorAll('span.variable').forEach(function (element) {\n var text = element.innerText;\n element.addEventListener('mouseover', function () {\n return me.showPopper(element, text);\n });\n element.addEventListener('mouseout', function () {\n return me.hidePopper(element);\n });\n });\n });\n }\n if (model.type === 'TCP') {\n apiRequestTabContent.append(this.tcpApiRequestTemplate(model, index));\n }\n document.querySelectorAll('.variable').forEach(function (element) {\n var text = element.innerText;\n element.addEventListener('mouseover', function () {\n return me.showPopper(element, text);\n });\n element.addEventListener('mouseout', function () {\n return me.hidePopper(element);\n });\n });\n this.openTab(model.id);\n var target = $('#api_request_' + model.id);\n var language = model.type === 'TCP' ? 'text' : 'json';\n var requestBodyEditor = monaco_editor__WEBPACK_IMPORTED_MODULE_0__.editor.create(target.find('.request_body')[0], {\n value: model.requestBody,\n language: language,\n automaticLayout: true\n });\n requestBodyEditor.onMouseMove(function (e) {\n var position = e.target.position;\n if (position) {\n var _model = requestBodyEditor.getModel();\n var word = _model.getWordAtPosition(position);\n var lineContent = _model.getLineContent(position.lineNumber);\n if (word) {\n if (lineContent.indexOf('{{' + word.word + '}}') > -1) {\n me.showPopper(e.target.element, word.word);\n }\n } else {\n me.hidePopper(e.target.element);\n }\n }\n });\n me.requestEditors.push(requestBodyEditor);\n target.find('.request_body')[0].addEventListener('shown.bs.tab', function () {\n me.requestEditors[index].layout();\n });\n me.requestEditors[index].onDidChangeModelContent(function (e) {\n model.requestBody = requestBodyEditor.getValue();\n });\n target.find('.request_body_type').on('change', function () {\n var model = requestBodyEditor.getModel();\n monaco_editor__WEBPACK_IMPORTED_MODULE_0__.editor.setModelLanguage(model, $(this).val());\n });\n var responseBodyEditor = monaco_editor__WEBPACK_IMPORTED_MODULE_0__.editor.create(target.find('.response_body')[0], {\n value: '',\n language: language,\n automaticLayout: true,\n quickSuggestions: false\n });\n me.responseEditors.push(responseBodyEditor);\n var consoleEditor = monaco_editor__WEBPACK_IMPORTED_MODULE_0__.editor.create(target.find('.console')[0], {\n value: '',\n automaticLayout: true,\n quickSuggestions: false\n });\n me.consoleEditors.push(consoleEditor);\n var preRequestEditor = monaco_editor__WEBPACK_IMPORTED_MODULE_0__.editor.create(target.find('.pre-request')[0], {\n value: model.preRequestScript,\n language: 'javascript',\n automaticLayout: true,\n quickSuggestions: false\n });\n var snippet1 = new _components_VariableSnippet__WEBPACK_IMPORTED_MODULE_4__[\"default\"]();\n snippet1.init(target.find('.pre-request-variable')[0], preRequestEditor);\n me.preRequestEditors.push(preRequestEditor);\n target.find('.pre-request')[0].addEventListener('shown.bs.tab', function () {\n me.preRequestEditors[index].layout();\n });\n me.preRequestEditors[index].onDidChangeModelContent(function (e) {\n model.preRequestScript = preRequestEditor.getValue();\n });\n var postRequestEditor = monaco_editor__WEBPACK_IMPORTED_MODULE_0__.editor.create(target.find('.post-request')[0], {\n value: model.postRequestScript,\n language: 'javascript',\n automaticLayout: true,\n quickSuggestions: false\n });\n var snippet2 = new _components_VariableSnippet__WEBPACK_IMPORTED_MODULE_4__[\"default\"]();\n snippet2.init(target.find('.post-request-variable')[0], postRequestEditor);\n me.postRequestEditors.push(postRequestEditor);\n target.find('.post-request')[0].addEventListener('shown.bs.tab', function () {\n me.postRequestEditors[index].layout();\n });\n me.postRequestEditors[index].onDidChangeModelContent(function (e) {\n model.postRequestScript = postRequestEditor.getValue();\n });\n }\n }, {\n key: \"renderResponse\",\n value: function renderResponse(tabIndex) {\n var _this4 = this;\n var model = this.apiRequests[tabIndex];\n var target = $('#api_request_' + model.id);\n target.find('.response_headers').empty();\n target.find('.response_status').empty();\n try {\n var parsedJson = JSON.parse(model.responseModel.body);\n var formattedJson = JSON.stringify(parsedJson, null, 2);\n this.responseEditors[tabIndex].setValue(formattedJson);\n } catch (e) {\n this.responseEditors[tabIndex].setValue(model.responseModel.body);\n }\n if (model.responseModel && model.responseModel.headers) {\n var headers = model.responseModel.headers;\n Object.entries(headers).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n key = _ref2[0],\n value = _ref2[1];\n target.find('.response_headers').append(_this4.responseHeaderTemplate(key, value));\n });\n }\n target.find('.response_status').text('status: ' + model.responseModel.status);\n target.find('.response_time').text('time: ' + model.responseModel.time + 'ms');\n target.find('.response_size').text('size: ' + model.responseModel.size + 'bytes');\n }\n }, {\n key: \"customHelper\",\n value: function customHelper(event) {\n // Create and return the custom helper element\n var name = $(event.target).closest('.api_request_sortable').find('.open_api_request').text().trim();\n var apiId = $(event.target).closest('.api_request_sortable').data('id');\n return \"
    \\n
    \").concat(name, \"
    \\n
    \");\n }\n }, {\n key: \"renderCollections\",\n value: function renderCollections() {\n var select = $('#modal_collection');\n var sidemenu = $(this.collectionTarget);\n select.empty();\n sidemenu.empty();\n for (var i = 0; i < this.collections.length; i++) {\n sidemenu.append(this.renderCollection(this.collections[i], i));\n var option = $('\");\n }).join('');\n return \"\");\n }\n }, {\n key: \"renderTcpServers\",\n value: function renderTcpServers(selectedServer) {\n var optionsHtml = this.servers.filter(function (server) {\n return server.scheme === 'tcp';\n }).map(function (server) {\n return \"\");\n }).join('');\n return \"\");\n }\n }, {\n key: \"renderHttpServers\",\n value: function renderHttpServers(selectedServer) {\n var optionsHtml = this.servers.filter(function (server) {\n return server.scheme !== 'tcp';\n }).map(function (server) {\n return \"\");\n }).join('');\n return \"\");\n }\n }]);\n return ServerManager;\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ServerManager);\n\n//# sourceURL=webpack://APITestManager/./src/components/ServerManager.js?"); + +/***/ }), + +/***/ "./src/components/TCPClientView.js": +/*!*****************************************!*\ + !*** ./src/components/TCPClientView.js ***! + \*****************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _EditableInput__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./EditableInput */ \"./src/components/EditableInput.js\");\n/* harmony import */ var _APIClient__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../APIClient */ \"./src/APIClient.js\");\nfunction _typeof(o) { \"@babel/helpers - typeof\"; return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && \"function\" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? \"symbol\" : typeof o; }, _typeof(o); }\nfunction _regeneratorRuntime() { \"use strict\"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = \"function\" == typeof Symbol ? Symbol : {}, a = i.iterator || \"@@iterator\", c = i.asyncIterator || \"@@asyncIterator\", u = i.toStringTag || \"@@toStringTag\"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, \"\"); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, \"_invoke\", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: \"normal\", arg: t.call(e, r) }; } catch (t) { return { type: \"throw\", arg: t }; } } e.wrap = wrap; var h = \"suspendedStart\", l = \"suspendedYield\", f = \"executing\", s = \"completed\", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { [\"next\", \"throw\", \"return\"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if (\"throw\" !== c.type) { var u = c.arg, h = u.value; return h && \"object\" == _typeof(h) && n.call(h, \"__await\") ? e.resolve(h.__await).then(function (t) { invoke(\"next\", t, i, a); }, function (t) { invoke(\"throw\", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke(\"throw\", t, i, a); }); } a(c.arg); } var r; o(this, \"_invoke\", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error(\"Generator is already running\"); if (o === s) { if (\"throw\" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if (\"next\" === n.method) n.sent = n._sent = n.arg;else if (\"throw\" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else \"return\" === n.method && n.abrupt(\"return\", n.arg); o = f; var p = tryCatch(e, r, n); if (\"normal\" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } \"throw\" === p.type && (o = s, n.method = \"throw\", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, \"throw\" === n && e.iterator[\"return\"] && (r.method = \"return\", r.arg = t, maybeInvokeDelegate(e, r), \"throw\" === r.method) || \"return\" !== n && (r.method = \"throw\", r.arg = new TypeError(\"The iterator does not provide a '\" + n + \"' method\")), y; var i = tryCatch(o, e.iterator, r.arg); if (\"throw\" === i.type) return r.method = \"throw\", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, \"return\" !== r.method && (r.method = \"next\", r.arg = t), r.delegate = null, y) : a : (r.method = \"throw\", r.arg = new TypeError(\"iterator result is not an object\"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = \"normal\", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: \"root\" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || \"\" === e) { var r = e[a]; if (r) return r.call(e); if (\"function\" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + \" is not iterable\"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, \"constructor\", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, \"constructor\", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, \"GeneratorFunction\"), e.isGeneratorFunction = function (t) { var e = \"function\" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || \"GeneratorFunction\" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, \"GeneratorFunction\")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, \"Generator\"), define(g, a, function () { return this; }), define(g, \"toString\", function () { return \"[object Generator]\"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = \"next\", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) \"t\" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if (\"throw\" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = \"throw\", a.arg = e, r.next = n, o && (r.method = \"next\", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if (\"root\" === i.tryLoc) return handle(\"end\"); if (i.tryLoc <= this.prev) { var c = n.call(i, \"catchLoc\"), u = n.call(i, \"finallyLoc\"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error(\"try statement without catch or finally\"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, \"finallyLoc\") && this.prev < o.finallyLoc) { var i = o; break; } } i && (\"break\" === t || \"continue\" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = \"next\", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if (\"throw\" === t.type) throw t.arg; return \"break\" === t.type || \"continue\" === t.type ? this.next = t.arg : \"return\" === t.type ? (this.rval = this.arg = t.arg, this.method = \"return\", this.next = \"end\") : \"normal\" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, \"catch\": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if (\"throw\" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error(\"illegal catch attempt\"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, \"next\" === this.method && (this.arg = t), y; } }, e; }\nfunction _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it[\"return\"] != null) it[\"return\"](); } finally { if (didErr) throw err; } } }; }\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }\nfunction asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }\nfunction _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err); } _next(undefined); }); }; }\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, \"prototype\", { writable: false }); return Constructor; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == _typeof(i) ? i : String(i); }\nfunction _toPrimitive(t, r) { if (\"object\" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != _typeof(i)) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n\n\nvar TCPClientView = /*#__PURE__*/function () {\n function TCPClientView(parent, serverManager, apiRequestTabContent, model, index) {\n _classCallCheck(this, TCPClientView);\n this.parent = parent;\n this.serverManager = serverManager;\n this.apiRequestTabContent = apiRequestTabContent;\n this.model = model;\n this.index = index;\n this.server = this.serverManager.getServer(this.model.server);\n this.apiClient = new _APIClient__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\n }\n _createClass(TCPClientView, [{\n key: \"init\",\n value: function init() {\n this.apiRequestTabContent.append(this.tcpApiRequestTemplate(this.model, this.index));\n this.renderApiLayout(this.model.layout);\n }\n }, {\n key: \"setRequestBodyEditor\",\n value: function setRequestBodyEditor(editor) {\n this.requestBodyEditor = editor;\n }\n }, {\n key: \"renderApiLayout\",\n value: function renderApiLayout(layout) {\n var _this = this;\n var requestContainer = this.apiRequestTabContent.find('.request_layout');\n requestContainer.empty();\n var headerHtml = \"\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \";\n var footerHtml = \"\\n \\n
    #\\uD56D\\uBAA9\\uBA85(\\uC601\\uBB38)\\uD56D\\uBAA9\\uC124\\uBA85\\uAE4A\\uC774\\uC544\\uC774\\uD15C \\uC720\\uD615\\uBC18\\uBCF5 \\uD69F\\uC218 \\uBC18\\uBCF5 \\uCC38\\uC870 \\uD544\\uB4DC\\uB370\\uC774\\uD130 \\uD0C0\\uC785\\uB370\\uC774\\uD130 \\uAE38\\uC774\\uAC12\\uBE44\\uACE0
    \\n \";\n var fieldsHtml = layout.layoutItems ? layout.layoutItems.map(function (item, index) {\n return _this.renderApiLayoutItem(item, index);\n }).join('') : '';\n requestContainer.append(headerHtml + fieldsHtml + footerHtml);\n requestContainer.find('.editable').each(function (index, editableElement) {\n var editableInput = new _EditableInput__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n name: editableElement.dataset.name,\n value: editableElement.dataset.value\n });\n editableInput.init(editableElement, function (value) {\n _.set(_this.model.layout, editableElement.dataset.name, value);\n _this.buildMessage();\n $('span.variable').off('mouseover');\n $('span.variable').off('mouseover');\n document.querySelectorAll('span.variable').forEach(function (element) {\n var text = element.innerText;\n element.addEventListener('mouseover', function () {\n return _this.parent.showPopper(element, text);\n });\n element.addEventListener('mouseout', function () {\n return _this.parent.hidePopper(element);\n });\n });\n });\n });\n var totalLength = 0;\n this.model.layout.layoutItems.forEach(function (item) {\n totalLength += parseInt(item.loutItemLength);\n });\n this.apiRequestTabContent.find('.total_message_length').text(totalLength);\n this.setupListeners();\n }\n }, {\n key: \"handleUIUpdate\",\n value: function handleUIUpdate(event) {\n if (event) {\n event.preventDefault();\n var element = event.currentTarget;\n var fieldName = $(element).attr('name');\n var newValue = this.getFieldValue(element);\n if (fieldName !== '') {\n _.set(this.model.layout, fieldName, newValue);\n this.buildMessage();\n }\n }\n var totalLength = 0;\n this.model.layout.layoutItems.forEach(function (item) {\n totalLength += parseInt(item.loutItemLength);\n });\n this.apiRequestTabContent.find('.total_message_length').text(totalLength);\n }\n }, {\n key: \"getFieldValue\",\n value: function getFieldValue(element) {\n if ($(element).is('select') || $(element).is('input[type=\"text\"]') || $(element).is('input[type=\"number\"]')) {\n return $(element).val();\n }\n if ($(element).is('input[type=\"checkbox\"]')) {\n return $(element).is(':checked');\n }\n }\n }, {\n key: \"renderApiLayoutItem\",\n value: function renderApiLayoutItem(item, index) {\n if (item.value === null) item.value = '';\n return \"\\n \\n \".concat(item.loutItemSerno, \"\\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n \\n
    \\n \\n \\n
    \\n \\n \\n \\n \\n
    \\n \\n \\n \");\n }\n }, {\n key: \"recalculateSerno\",\n value: function recalculateSerno() {\n // Reassign loutItemSerno sequentially based on the current order\n this.model.layout.layoutItems.forEach(function (item, index) {\n item.loutItemSerno = index + 1; // Assuming you want to start numbering from 1\n });\n }\n }, {\n key: \"setupListeners\",\n value: function setupListeners() {\n var _this2 = this;\n var table = this.apiRequestTabContent.find('.layout_table');\n table.on('change', 'select.field, input.field', this.handleUIUpdate.bind(this));\n table.on('click', '.add-layout-item', function (event) {\n var item = {\n 'parent': 0,\n 'level': 1,\n 'loutName': '',\n 'loutItemName': '',\n 'loutItemDesc': '',\n 'loutItemDepth': 1,\n 'loutItemType': 'Field',\n 'loutItemOccCnt': '',\n 'loutItemOccRef': '',\n 'loutItemDataType': 'String',\n 'loutItemLength': 1,\n 'loutItemDecimal': 0,\n 'loutItemDefault': '',\n 'loutItemMaskYn': 'N',\n 'loutItemMaskOffset': 0,\n 'loutItemMaskLength': 0,\n 'parentLoutItemIndex': 0,\n 'expanded': true,\n 'isLeaf': true,\n 'LOUTITEMPATH': '',\n 'value': ''\n };\n _this2.model.layout.layoutItems.push(item);\n _this2.recalculateSerno();\n _this2.renderApiLayout(_this2.model.layout);\n });\n table.on('click', '.move-up', function (event) {\n var index = $(event.currentTarget).data('index');\n if (index > 0) {\n var temp = _this2.model.layout.layoutItems[index];\n _this2.model.layout.layoutItems[index] = _this2.model.layout.layoutItems[index - 1];\n _this2.model.layout.layoutItems[index - 1] = temp;\n _this2.recalculateSerno();\n _this2.renderApiLayout(_this2.model.layout);\n }\n });\n table.on('click', '.move-down', function (event) {\n var index = $(event.currentTarget).data('index');\n if (index < _this2.model.layout.layoutItems.length - 1) {\n var temp = _this2.model.layout.layoutItems[index];\n _this2.model.layout.layoutItems[index] = _this2.model.layout.layoutItems[index + 1];\n _this2.model.layout.layoutItems[index + 1] = temp;\n _this2.recalculateSerno();\n _this2.renderApiLayout(_this2.model.layout);\n }\n });\n table.on('click', '.delete', function (event) {\n var index = $(event.currentTarget).data('index');\n _this2.model.layout.layoutItems.splice(index, 1);\n _this2.recalculateSerno();\n _this2.renderApiLayout(_this2.model.layout);\n });\n }\n }, {\n key: \"buildMessage\",\n value: function () {\n var _buildMessage = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {\n var message, _iterator, _step, item, duplicated, value;\n return _regeneratorRuntime().wrap(function _callee$(_context) {\n while (1) switch (_context.prev = _context.next) {\n case 0:\n message = '';\n this.requestBodyEditor.setValue(message);\n _iterator = _createForOfIteratorHelper(this.model.layout.layoutItems);\n _context.prev = 3;\n _iterator.s();\n case 5:\n if ((_step = _iterator.n()).done) {\n _context.next = 14;\n break;\n }\n item = _step.value;\n duplicated = item.value;\n _context.next = 10;\n return this.apiClient.processPreScriptAndVariables(this.model, duplicated, null);\n case 10:\n value = _context.sent;\n message += this.fillPadding(item.loutItemLength, value);\n case 12:\n _context.next = 5;\n break;\n case 14:\n _context.next = 19;\n break;\n case 16:\n _context.prev = 16;\n _context.t0 = _context[\"catch\"](3);\n _iterator.e(_context.t0);\n case 19:\n _context.prev = 19;\n _iterator.f();\n return _context.finish(19);\n case 22:\n this.requestBodyEditor.setValue(message);\n case 23:\n case \"end\":\n return _context.stop();\n }\n }, _callee, this, [[3, 16, 19, 22]]);\n }));\n function buildMessage() {\n return _buildMessage.apply(this, arguments);\n }\n return buildMessage;\n }()\n }, {\n key: \"fillPadding\",\n value: function fillPadding(dataLength, value) {\n value = String(value);\n return value.padStart(dataLength, ' ');\n }\n }, {\n key: \"tcpApiRequestTemplate\",\n value: function tcpApiRequestTemplate(apiRequest, index) {\n return \"\\n
    \\n
    \").concat(apiRequest.collectionName, \" > \").concat(apiRequest.name, \"
    \\n
    \\n
    \\n \").concat(this.serverManager.renderTcpServers(apiRequest.server), \"\\n \\n
    \\n
    \\n \\n \\n
    \\n
    \\n \\n \\n
    \\n
    \\n \\n \\n
    \\n
    \\n \\n \\n
    \\n
    \\n \\n \\n
    \\n \\n \\n
    \\n
    \\n
    \\n
      \\n
    • \\n \\n
    • \\n
    • \\n \\n
    • \\n
    • \\n \\n
    • \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n \\uC804\\uCCB4 \\uBA54\\uC2DC\\uC9C0 \\uAE38\\uC774: \\n \\n
    \\n
    \\n
    \\n
    \\n
    \\n Response\\n \\n \\n
    \\n
      \\n
    • \\n \\n
    • \\n
    • \\n \\n
    • \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n
    \\n \\n \");\n }\n }]);\n return TCPClientView;\n}();\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (TCPClientView);\n\n//# sourceURL=webpack://APITestManager/./src/components/TCPClientView.js?"); + +/***/ }), + /***/ "./src/components/VariableSnippet.js": /*!*******************************************!*\ !*** ./src/components/VariableSnippet.js ***! diff --git a/src/main/resources/templates/page/servers/serverEdit.html b/src/main/resources/templates/page/servers/serverEdit.html index c690d98..d0c3941 100644 --- a/src/main/resources/templates/page/servers/serverEdit.html +++ b/src/main/resources/templates/page/servers/serverEdit.html @@ -27,6 +27,7 @@ @@ -54,6 +55,37 @@ + +
    @@ -71,6 +103,25 @@ - \ No newline at end of file + diff --git a/src/main/resources/templates/page/servers/serverList.html b/src/main/resources/templates/page/servers/serverList.html index 8db5269..33da39c 100644 --- a/src/main/resources/templates/page/servers/serverList.html +++ b/src/main/resources/templates/page/servers/serverList.html @@ -49,9 +49,10 @@ + + - - +