pre-request script working

This commit is contained in:
Nicholas Palenchar
2019-10-29 21:28:44 -04:00
parent 0647fc3297
commit 668f99c37f
4 changed files with 100 additions and 39 deletions

View File

@@ -12,6 +12,7 @@
</li>
</ul>
<ul>
<li style="max-width: 44px"></li>
<li @click="sort_by_label()">
<label class="flex-wrap">
Label
@@ -50,6 +51,12 @@
:remain="Math.min(5, filteredHistory.length)"
>
<ul v-for="(entry, index) in filteredHistory" :key="index" class="entry">
<li style="width: 44px">
<button v-if="entry.usesScripts"
v-tooltip="'This entry used pre-request scripts.'"
class="icon"
><i class="material-icons" style="z-index: 10050;">code</i></button>
</li>
<li>
<input
aria-label="Label"

17
functions/preRequest.js Normal file
View File

@@ -0,0 +1,17 @@
export default function getEnvironmentVariablesFromScript(script) {
let _variables = {};
// the pw object is the proxy by which pre-request scripts can pass variables to the request.
// for security and control purposes, this is the only way a pre-request script should modify variables.
let pw = {
environment: {
set: (key, value) => _variables[key] = value,
},
// globals that the script is allowed to have access to.
};
// run pre-request script within this function so that it has access to the pw object.
(new Function('pw', script))(pw);
return _variables;
}

4
functions/templating.js Normal file
View File

@@ -0,0 +1,4 @@
export default function parseTemplateString(string, variables) {
const searchTerm = /\${([^}]*)}/g; // "${myVariable}"
return string.replace(searchTerm, (match, p1) => variables[p1] || '');
}

View File

@@ -38,7 +38,9 @@
</ul>
</div>
</pw-modal>
<pw-section v-if="showPreRequestScript" label="Pre-Request" ref="preRequest">
<textarea id="preRequestScript" @keydown="formatRawParams" rows="8" v-model="preRequestScript" v-textarea-auto-height="rawParams" spellcheck="false"></textarea>
</pw-section>
<pw-section class="blue" icon="cloud_upload" label="Request" ref="request">
<ul>
<li>
@@ -201,6 +203,14 @@
<i class="material-icons" v-if="isHidden">visibility</i>
<i class="material-icons" v-if="!isHidden">visibility_off</i>
</button>
<button
:class="'icon' + (showPreRequestScript ? ' info-response' : '')"
id="preRequestScriptButton"
v-tooltip.bottom="'Pre-Request Script'"
@click="showPreRequestScript = !showPreRequestScript"
>
<i class="material-icons" :class="showPreRequestScript">code</i>
</button>
</div>
<div style="text-align: center;">
<button
@@ -540,6 +550,8 @@ import saveRequestAs from "../components/collections/saveRequestAs";
import parseCurlCommand from "../assets/js/curlparser.js";
import hljs from "highlight.js";
import "highlight.js/styles/dracula.css";
import getEnvironmentVariablesFromScript from "../functions/preRequest";
import parseTemplateString from '../functions/templating'
const statusCategories = [
{
@@ -608,6 +620,8 @@ export default {
data () {
return {
showModal: false,
showPreRequestScript: false,
preRequestScript: '',
copyButton: '<i class="material-icons">file_copy</i>',
copiedButton: '<i class="material-icons">done</i>',
isHidden: true,
@@ -816,6 +830,10 @@ export default {
return findStatusGroup(this.response.status);
},
isValidURL() {
if (this.showPreRequestScript) {
// we cannot determine if a URL is valid because the full string is not known ahead of time
return true;
}
const protocol = "^(https?:\\/\\/)?";
const validIP = new RegExp(
protocol +
@@ -1017,7 +1035,13 @@ export default {
behavior: "smooth"
});
},
async makeRequest(auth, headers, requestBody) {
getVariablesFromPreRequestScript() {
if(!this.preRequestScript) {
return {};
}
return getEnvironmentVariablesFromScript(this.preRequestScript);
},
async makeRequest(auth, headers, requestBody, preRequestScript) {
const requestOptions = {
method: this.method,
url: this.url + this.pathName + this.queryString,
@@ -1025,7 +1049,14 @@ export default {
headers,
data: requestBody ? requestBody.toString() : null
};
if (preRequestScript) {
const environmentVariables = getEnvironmentVariablesFromScript(preRequestScript);
requestOptions.url = parseTemplateString(requestOptions.url, environmentVariables);
//TODO parse all other headers
}
if (typeof requestOptions.data === 'string') {
requestOptions.data = parseTemplateString(requestOptions.data);
}
const config = this.$store.state.postwoman.settings.PROXY_ENABLED
? {
method: "POST",
@@ -1114,7 +1145,7 @@ export default {
try {
const startTime = Date.now();
const payload = await this.makeRequest(auth, headers, requestBody);
const payload = await this.makeRequest(auth, headers, requestBody, this.preRequestScript);
const duration = Date.now() - startTime;
this.$toast.info(`Finished in ${duration}ms`, {
@@ -1139,7 +1170,8 @@ export default {
time,
method: this.method,
url: this.url,
path: this.path
path: this.path,
usesScripts: Boolean(this.preRequestScript)
};
this.$refs.historyComponent.addEntry(entry);
})();
@@ -1158,7 +1190,8 @@ export default {
time: new Date().toLocaleTimeString(),
method: this.method,
url: this.url,
path: this.path
path: this.path,
usesScripts: Boolean(this.preRequestScript)
};
this.$refs.historyComponent.addEntry(entry);
return;