diff --git a/src/main/resources/static/js/APIClient.js b/src/main/resources/static/js/APIClient.js new file mode 100644 index 0000000..52b5433 --- /dev/null +++ b/src/main/resources/static/js/APIClient.js @@ -0,0 +1,188 @@ +/** + * 처리 순서 + * 1. preRequestScript 실행 -> executePreRequestScript + * 2. 변수 치환 -> replacePlaceholdersWithVariables + * 3. API 호출 -> sendAPIRequest + * 4. postRequestScript 실행 -> executePostRequestScript + */ + +class APIClient { + constructor() { + window.globals = {}; + this.globalVariables = window.globals; + this.variables = {}; + this.currentAjaxRequest = null; + this.abortController = null; + } + + async sendAPIRequest(model) { + try { + const updatedModel = await this.executePreRequestScript(model); + let processedRequest = this.replacePlaceholdersWithVariables(updatedModel); + return this.makeAjaxRequest(processedRequest, model); + } catch (error) { + throw error; + } + } + + abort() { + if (this.abortController) { + this.abortController.abort(); // abort the fetch + this.abortController = null; // reset the controller + } + } + + makeAjaxRequest(processedRequest, model) { + this.abortController = new AbortController(); + const {signal} = this.abortController; + + return fetch('/mgmt/api/test.do', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-XSRF-TOKEN': $('meta[name="_csrf"]').attr('content') + }, + body: JSON.stringify(processedRequest), + signal: signal // pass the signal to the fetch + }) + .then(response => response.json()) + .then(data => { + try { + model.responseModel.status = data.status; + model.responseModel.body = data.body; + model.responseModel.headers = data.headers; + model.responseModel.size = data.size; + + let response = {}; + response.body = data.body; + response.status = data.status; + response.headers = {}; + response.size = data.size; + _.forEach(data.headers, (header) => { + response.headers[header.key] = header.value; + }); + return this.executePostRequestScript(model.postRequestScript, model.responseModel); + } catch (error) { + console.log('error1') + $('.toast-body').text(error); + $('.toast').toast('show'); + } + }) + .catch(error => { + console.log('error2') + console.log(error.name) + if (error.name === 'AbortError') { + console.log('Fetch aborted'); + } else { + // $('.toast-body').text(response.responseJSON.error); + // $('.toast').toast('show'); + } + }); + + } + + + replacePlaceholdersWithVariables(original) { + let request = JSON.parse(JSON.stringify(original)); + + let mergedVariables = {}; + _.forEach(this.globalVariables, (value, key) => { + mergedVariables[key] = value; + }); + + if (this.variables) { + _.forEach(this.variables, (value, key) => { + mergedVariables[key] = value; + }); + } + + _.forEach(mergedVariables, (value, key) => { + const placeholder = `{{${key}}}`; + // Replace in path + request.path = request.path.replace(new RegExp(placeholder, 'g'), value); + + // Replace in requestBody + if (request.requestBody) { + request.requestBody = request.requestBody.replace(new RegExp(placeholder, 'g'), value); + } + + // Replace in headers + if (request.headers) { + let replaced = JSON.stringify(request.headers).replace(new RegExp(placeholder, 'g'), value); + request.headers = JSON.parse(replaced); + } + + // Replace in queryParams + if (request.queryParams) { + let replaced = JSON.stringify(request.queryParams).replace(new RegExp(placeholder, 'g'), value); + request.queryParams = JSON.parse(replaced); + } + }); + + return request; + } + + executePreRequestScript(model) { + return new Promise((resolve, reject) => { + let script = model.preRequestScript; + let resultFrame = document.getElementById('preRequest'); + + this.variables = {}; + model.variables.forEach((item) => { + if (item.enabled) { + this.variables[item.key] = item.value; + } + }); + + window.preRequestComplete = (updatedModel, error) => { + if (error) { + reject('PreRequestScript error:', error); + } else { + resolve(updatedModel); + } + }; + + window.temp_variable = this.variables; + window.currentRequest = model; + resultFrame.srcdoc = ``; + }); + } + + executePostRequestScript(script, response) { + return new Promise((resolve, reject) => { + let resultFrame = document.getElementById('postRequest'); + window.response = response; + window.temp_variable = this.variables; + window.postRequestComplete = (updatedModel, error) => { + if (error) { + reject('PreRequestScript error:', error); + } else { + resolve(updatedModel); + } + }; + + resultFrame.srcdoc = ``; + }); + } +} \ No newline at end of file