스크립트 추가

This commit is contained in:
현성필
2023-12-27 21:09:01 +09:00
parent 8eae737de0
commit 5c938336b3
7 changed files with 396 additions and 77 deletions
+225 -42
View File
@@ -14,7 +14,11 @@ class APITester {
this.collections = []; //API 컬렉션
this.requestEditors = []; //API request body editor
this.responseEditors = []; //API response body editor
this.preRequestEditors = [];
this.postRequestEditors = [];
window.globals = {};
this.globalVariables = window.globals;
this.variables = {};
}
renderServers(selectedServer) {
@@ -36,7 +40,7 @@ class APITester {
apiRequestTemplate(apiRequest, index) {
return `
<div class="tab-pane fade mt-1 api_request" id="api_request_${apiRequest.id}" data-index="${index}">
<div class="tab-pane fade mt-1 api_request" id="api_request_${apiRequest.id}">
<div><span class="collection_name">${apiRequest.collectionName}</span> &gt; <span class="api_name">${apiRequest.name}</span></div>
<div class="d-flex align-items-center api_request_info">
<div class="form-floating col-md-1 me-1">
@@ -60,13 +64,12 @@ class APITester {
<div class="form-floating col-md-2 me-1">
<div class="form-floating col-md">
<input type="text" name="basePath" class="form-control" value="${this.basePath(apiRequest.server)}" readonly>
<label class="must">base path</label>
<label class="must">기본 경로</label>
</div>
</div>
<div class="input-group col-md me-1">
<div class="form-floating col-md">
<input type="text" name="path" class="form-control path" value="${apiRequest.path}" placeholder="호출할 경로 (/부터 입력)"
required>
<input type="text" name="path" class="form-control path" value="${apiRequest.path}" placeholder="호출할 경로 (/부터 입력)">
<label class="must">Path</label>
</div>
<button class="btn btn-primary send">Send</button>
@@ -98,6 +101,19 @@ class APITester {
aria-selected="false">Variables
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link btn_prerequest_tab" data-bs-toggle="tab"
type="button" role="tab" aria-controls="preScrit" data-bs-target="#preRequestTab_${apiRequest.id}"
aria-selected="false">Pre-Request
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link btn_postrequest_tab" data-bs-toggle="tab"
type="button" role="tab" aria-controls="postScript" data-bs-target="#postRequestTab_${apiRequest.id}"
aria-selected="false">Post-Request
</button>
</li>
</ul>
<div class="tab-content border-bottom" style="min-height: 300px;">
<div class="tab-pane fade show request_param_tab" role="tabpanel" id="requestParamTab_${apiRequest.id}"
@@ -164,6 +180,14 @@ class APITester {
</select>
<div class="request_body mt-1" style="width:100%;height:250px;border:1px solid grey;"></div>
</div>
<div class="tab-pane fade pre_script_tab" role="tabpanel" id="preRequestTab_${apiRequest.id}"
aria-labelledby="preScrit-tab">
<div class="pre-request mt-1" style="width:100%;height:250px;border:1px solid grey;"></div>
</div>
<div class="tab-pane fade post_script_tab" role="tabpanel" id="postRequestTab_${apiRequest.id}"
aria-labelledby="postScrit-tab">
<div class="post-request mt-1" style="width:100%;height:250px;border:1px solid grey;"></div>
</div>
</div>
<div class="mt-1">
<span>Response</span>
@@ -467,8 +491,7 @@ class APITester {
//console.log(fieldName);
const newValue = this.getFieldValue(element);
//console.log(newValue);
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
let model = this.apiRequests[tabIndex];
if (fieldName !== '') {
@@ -479,7 +502,7 @@ class APITester {
}
handleUpdateServer(event) {
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
let model = this.apiRequests[tabIndex];
let target = $('#api_request_' + model.id);
//console.log('model.server: ' + model.server);
@@ -505,7 +528,7 @@ class APITester {
for (let idx = 0; idx < this.apiRequests.length; idx++) {
let li = `<li class="nav-item" role="presentation">
<button class="nav-link" id="api_request_tab_${this.apiRequests[idx].id}" data-index="${idx}" data-bs-toggle="tab" type="button" role="tab" aria-controls="api_request_${this.apiRequests[idx].id}" data-bs-target="#api_request_${this.apiRequests[idx].id}" aria-selected="false">${this.apiRequests[idx].name}
<button class="nav-link" id="api_request_tab_${this.apiRequests[idx].id}" data-bs-toggle="tab" type="button" role="tab" aria-controls="api_request_${this.apiRequests[idx].id}" data-bs-target="#api_request_${this.apiRequests[idx].id}" aria-selected="false">${this.apiRequests[idx].name}
<span class="close_tab"><i class="fa fa-light fa-close"></i></span>
</button>
</li>`;
@@ -524,7 +547,7 @@ class APITester {
this.openTab(model.id);
let target = $('#api_request_' + model.id);
require(['vs/editor/editor.main'], function () {
require(['vs/editor/editor.main'], () => {
let requestBodyEditor = monaco.editor.create(target.find(".request_body")[0], {
value: model.requestBody,
language: 'json',
@@ -532,15 +555,15 @@ class APITester {
automaticLayout: true
});
me.requestEditors.push(requestBodyEditor);
target.find(".request_body")[0].addEventListener('shown.bs.tab', function () {
target.find(".request_body")[0].addEventListener('shown.bs.tab', () => {
me.requestEditors[index].layout();
});
me.requestEditors[index].onDidChangeModelContent(function (e) {
me.requestEditors[index].onDidChangeModelContent( (e) => {
model.requestBody = requestBodyEditor.getValue();
});
target.find('.request_body_type').on('change', function () {
target.find('.request_body_type').on('change', () => {
let model = requestBodyEditor.getModel();
monaco.editor.setModelLanguage(model, $(this).val());
});
@@ -552,6 +575,40 @@ class APITester {
automaticLayout: true
});
me.responseEditors.push(responseBodyEditor);
let preRequestEditor = monaco.editor.create(target.find(".pre-request")[0], {
value: model.preRequestScript,
language: 'javascript',
theme: 'vs-light',
automaticLayout: true
});
me.preRequestEditors.push(preRequestEditor);
target.find(".pre-request")[0].addEventListener('shown.bs.tab', () => {
me.preRequestEditors[index].layout();
});
me.preRequestEditors[index].onDidChangeModelContent( (e) => {
model.preRequestScript = preRequestEditor.getValue();
});
let postRequestEditor = monaco.editor.create(target.find(".post-request")[0], {
value: model.postRequestScript,
language: 'javascript',
theme: 'vs-light',
automaticLayout: true
});
me.postRequestEditors.push(postRequestEditor);
target.find(".post-request")[0].addEventListener('shown.bs.tab', () => {
me.postRequestEditors[index].layout();
});
me.postRequestEditors[index].onDidChangeModelContent( (e) => {
model.postRequestScript = postRequestEditor.getValue();
});
});
}
@@ -621,7 +678,7 @@ class APITester {
}
addHeader(event) {
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
let model = this.apiRequests[tabIndex];
model.headers.push({
enabled: true,
@@ -632,7 +689,7 @@ class APITester {
}
removeHeader(event) {
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
const index = $(event.currentTarget).closest('tr').data('index');
let model = this.apiRequests[tabIndex];
model.headers.splice(index, 1);
@@ -649,7 +706,7 @@ class APITester {
addQueryParam(event) {
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
//console.log('addQueryParam');
let model = this.apiRequests[tabIndex];
model.queryParams.push({
@@ -663,7 +720,7 @@ class APITester {
removeQueryParam(event) {
//console.log('removeQueryParam');
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
const index = $(event.currentTarget).closest('tr').data('index');
let model = this.apiRequests[tabIndex];
model.queryParams.splice(index, 1);
@@ -680,7 +737,7 @@ class APITester {
addVariable(event) {
//console.log('addVariable');
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
let model = this.apiRequests[tabIndex];
model.variables.push({
enabled: true,
@@ -692,7 +749,7 @@ class APITester {
removeVariable(event) {
//console.log('removeVariable');
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
const index = $(event.currentTarget).closest('tr').data('index');
let model = this.apiRequests[tabIndex];
model.variables.splice(index, 1);
@@ -707,7 +764,7 @@ class APITester {
target.find('.variables').append(this.renderVariables(model.variables));
}
parseParam(event) {
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
let model = this.apiRequests[tabIndex];
model.path = $(event.currentTarget).val();
//console.log(model.path);
@@ -729,7 +786,7 @@ class APITester {
}
}
buildPath(event) {
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
let model = this.apiRequests[tabIndex];
let queryString = model.path.split('?')[0];
if (model.queryParams.length > 0) {
@@ -757,41 +814,65 @@ class APITester {
}
sendApiRequest(event) {
const tabIndex = $(event.currentTarget).closest('.api_request').data('index');
const tabIndex = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
console.log(tabIndex);
const me = this;
let model = this.apiRequests[tabIndex];
if (!model.server){
$('.toast-body').text('서버를 등록해주세요.');
$('.toast').toast('show');
return;
}
let target = $('#api_request_' + model.id);
target.find('.response_headers').empty();
this.responseEditors[tabIndex].setValue('');
let startTime = new Date().getTime();
if (model.path !== '') {
this.showLoadingOverlay();
this.showLoadingOverlay();
model.responseModel = {};
let processedRequest = this.executePreRequestScript(model, tabIndex,() => {
processedRequest = this.replacePlaceholdersWithVariables(processedRequest, tabIndex);
this.currentAjaxRequest = $.ajax({
url: '/mgmt/api/test.do',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(model),
success: function (data) {
data: JSON.stringify(processedRequest),
success: (data) => {
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;
});
this.executePostRequestScript(model.postRequestScript, tabIndex, response, ()=> {
let endTime = new Date().getTime();
model.responseModel.time = endTime - startTime;
me.renderResponse(tabIndex);
me.hideLoadingOverlay();
});
},
error: function (response, textStatus, errorThrown) {
error: (response, textStatus, errorThrown) => {
me.hideLoadingOverlay();
$('.toast-body').text(response.responseJSON.error);
$('.toast').toast('show');
},
complete: function () {
let endTime = new Date().getTime();
model.responseModel.time = endTime - startTime;
me.renderResponse(tabIndex);
me.hideLoadingOverlay();
}
});
}
});
}
@@ -917,7 +998,7 @@ class APITester {
saveAPIRequest(event) {
const me = this;
const index = $(event.currentTarget).data('index');
const index = $('#apiRequestTabContent').children().index($(event.currentTarget).closest('.api_request'));
let model = this.apiRequests[index];
me.showLoadingOverlay();
@@ -946,6 +1027,11 @@ class APITester {
addAPIRequest(event) {
const collectionId = $('#modal_collection').val();
let newApiName = $('#new_api_name').val();
if (newApiName === '') {
newApiName = '새로운 API';
}
const collection = this.collections.filter(function (collection) {
return collection.id === collectionId;
})[0];
@@ -954,12 +1040,14 @@ class APITester {
id: '',
server: null,
method: 'GET',
name: 'New Request',
name: newApiName,
path: '',
headers: [],
queryParams: [],
variables: [],
requestBody: '',
preRequestScript :'',
postRequestScript :'',
collectionId: collectionId,
responseModel: {
status: 0,
@@ -991,7 +1079,7 @@ class APITester {
me.renderTabHeader();
me.renderTabContent(me.currentIndex);
$('#new_api_name').val('');
me.hideLoadingOverlay();
$('#new_api_request_modal').modal('hide');
}
@@ -1078,28 +1166,123 @@ class APITester {
me.hideLoadingOverlay();
me.loadCollections();
$('#confirm_delete_api_modal').modal('hide');
// $('#confirm_delete_api_modal').find('.confirm_delete_api').removeAttr('data-id');
// $('#confirm_delete_api_modal').find('.confirm_delete_api').removeAttr('data-collection');
}
});
}
closeTabWithApiIndex(index) {
console.log(index);
if (index !== undefined){
//console.log('closeTabWithApiIndex: ' + index);
const model = this.apiRequests[index];
console.log(model);
this.apiRequests.splice(index, 1);
let apiRequestTabTitle = $(this.apiTabTitleTarget);
apiRequestTabTitle.empty();
this.renderTabHeader();
$(`#api_request_${model.id}`).remove();
$(`#apiRequestTabTitle li:eq(${this.apiRequests.length - 1}) button`).tab('show');
// $(`#apiRequestTabTitle li:eq(${this.apiRequests.length - 1}) button`).tab('show');
$(`#apiRequestTabTitle li:eq(0) button`).tab('show');
}
}
closeTab(event) {
let index = $(event.currentTarget).closest('button').data('index');
//console.log('closeTab: ' + index);
const index = $('#apiRequestTabTitle').children().index($(event.currentTarget).closest('.nav-item'));
this.closeTabWithApiIndex(index);
}
replacePlaceholdersWithVariables(original, index) {
let request = JSON.parse(JSON.stringify(original));
let mergedVariables = {};
_.forEach(this.globalVariables, (value, key) => {
mergedVariables[key] = value;
});
if (this.variables[index]) {
_.forEach(this.variables[index], (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) {
request.headers = request.headers.map(header => {
return {
...header,
key: header.key.replace(new RegExp(placeholder, 'g'), value),
value: header.value.replace(new RegExp(placeholder, 'g'), value)
};
});
}
// Replace in queryParams
if (request.queryParams) {
request.queryParams = request.queryParams.map(queryParam => {
return {
...queryParam,
key: queryParam.key.replace(new RegExp(placeholder, 'g'), value),
value: queryParam.value.replace(new RegExp(placeholder, 'g'), value)
};
});
}
});
return request;
}
executePreRequestScript(model, index, callback) {
let script = model.preRequestScript;
let resultFrame = document.getElementById('preRequest');
let {headers, method, path, queryParams, requestBody} = model;
window.request = {headers, method, path, queryParams, requestBody};
this.variables[index] = {};
model.variables.forEach((item) =>{
if (item.enabled) {
this.variables[index][item.key] = item.value;
}
});
window.preRequestComplete = function(updatedModel) {
callback(updatedModel);
};
window.temp_variable = this.variables[index];
resultFrame.srcdoc = `<script>
window.globals = window.parent.globals;
window.variables = window.parent.temp_variable;
window.request = window.parent.request;
${script}
window.parent.preRequestComplete(window.request);
</script>`;
return model;
}
executePostRequestScript(script, index, response, callback) {
let resultFrame = document.getElementById('postRequest');
window.response = response;
window.parent.temp_variable = this.variables[index];
window.postRequestComplete = function(updatedModel) {
callback(updatedModel);
};
window.temp_variable = this.variables[index];
resultFrame.srcdoc = `<script>
window.globals = window.parent.globals;
window.variables = window.parent.temp_variable;
window.response = window.parent.response;
${script}
window.parent.postRequestComplete(window.request);
</script>`;
}
}