diff --git a/assets/js/curlparser.js b/assets/js/curlparser.js
new file mode 100644
index 000000000..0b2c52f1f
--- /dev/null
+++ b/assets/js/curlparser.js
@@ -0,0 +1,223 @@
+import * as cookie from "cookie";
+import * as URL from "url";
+import * as querystring from "querystring";
+
+
+/**
+ * given this: [ 'msg1=value1', 'msg2=value2' ]
+ * output this: 'msg1=value1&msg2=value2'
+ * @param dataArguments
+ */
+function joinDataArguments(dataArguments) {
+ let data = '';
+ dataArguments.forEach(function(argument, i) {
+ if (i === 0) {
+ data += argument;
+ } else {
+ data += '&' + argument;
+ }
+ })
+ return data;
+}
+
+function parseCurlCommand(curlCommand) {
+ let newlineFound = /\r|\n/.exec(curlCommand);
+ if (newlineFound) {
+ // remove newlines
+ curlCommand = curlCommand.replace(/\\\r|\\\n/g, '');
+ }
+ // yargs parses -XPOST as separate arguments. just prescreen for it.
+ curlCommand = curlCommand.replace(/ -XPOST/, ' -X POST');
+ curlCommand = curlCommand.replace(/ -XGET/, ' -X GET');
+ curlCommand = curlCommand.replace(/ -XPUT/, ' -X PUT');
+ curlCommand = curlCommand.replace(/ -XPATCH/, ' -X PATCH');
+ curlCommand = curlCommand.replace(/ -XDELETE/, ' -X DELETE');
+ curlCommand = curlCommand.trim();
+ let parsedArguments = require("yargs-parser")(curlCommand);
+ let cookieString;
+ let cookies;
+ let url = parsedArguments._[1];
+ if (!url) {
+ for (let argName in parsedArguments) {
+ if (typeof parsedArguments[argName] === 'string') {
+ if (parsedArguments[argName].indexOf('http') === 0 || parsedArguments[argName].indexOf('www.') === 0) {
+ url = parsedArguments[argName];
+ }
+ }
+ }
+ }
+ let headers;
+
+ let parseHeaders = function(headerFieldName) {
+ if (parsedArguments[headerFieldName]) {
+ if (!headers) {
+ headers = {};
+ }
+ if (!Array.isArray(parsedArguments[headerFieldName])) {
+ parsedArguments[headerFieldName] = [parsedArguments[headerFieldName]];
+ }
+ parsedArguments[headerFieldName].forEach(function(header) {
+ if (header.indexOf('Cookie') !== -1) {
+ // stupid javascript tricks: closure
+ cookieString = header;
+ } else {
+ let colonIndex = header.indexOf(':');
+ let headerName = header.substring(0, colonIndex);
+ let headerValue = header.substring(colonIndex + 1).trim();
+ headers[headerName] = headerValue;
+ }
+ })
+ }
+ }
+
+ parseHeaders('H');
+ parseHeaders('header');
+ if (parsedArguments.A) {
+ if (!headers) {
+ headers = [];
+ }
+ headers['User-Agent'] = parsedArguments.A;
+ } else if (parsedArguments['user-agent']) {
+ if (!headers) {
+ headers = [];
+ }
+ headers['User-Agent'] = parsedArguments['user-agent'];
+ }
+
+ if (parsedArguments.b) {
+ cookieString = parsedArguments.b;
+ }
+ if (parsedArguments.cookie) {
+ cookieString = parsedArguments.cookie;
+ }
+ let multipartUploads;
+ if (parsedArguments.F) {
+ multipartUploads = {};
+ if (!Array.isArray(parsedArguments.F)) {
+ parsedArguments.F = [parsedArguments.F];
+ }
+ parsedArguments.F.forEach(function(multipartArgument) {
+ // input looks like key=value. value could be json or a file path prepended with an @
+ let splitArguments = multipartArgument.split('=', 2);
+ let key = splitArguments[0];
+ let value = splitArguments[1];
+ multipartUploads[key] = value;
+ })
+ }
+ if (cookieString) {
+ let cookieParseOptions = {
+ decode: function(s) { return s }
+ }
+ // separate out cookie headers into separate data structure
+ // note: cookie is case insensitive
+ cookies = cookie.parse(cookieString.replace(/^Cookie: /gi, ''), cookieParseOptions);
+ }
+ let method;
+ if (parsedArguments.X === 'POST') {
+ method = 'post';
+ } else if (parsedArguments.X === 'PUT' ||
+ parsedArguments['T']) {
+ method = 'put';
+ } else if (parsedArguments.X === 'PATCH') {
+ method = 'patch';
+ } else if (parsedArguments.X === 'DELETE') {
+ method = 'delete';
+ } else if (parsedArguments.X === 'OPTIONS') {
+ method = 'options';
+ } else if ((parsedArguments['d'] ||
+ parsedArguments['data'] ||
+ parsedArguments['data-ascii'] ||
+ parsedArguments['data-binary'] ||
+ parsedArguments['F'] ||
+ parsedArguments['form']) && !((parsedArguments['G'] || parsedArguments['get']))) {
+ method = 'post';
+ } else if (parsedArguments['I'] ||
+ parsedArguments['head']) {
+ method = 'head';
+ } else {
+ method = 'get';
+ }
+
+ let compressed = !!parsedArguments.compressed;
+ let urlObject = URL.parse(url); // eslint-disable-line
+
+ // if GET request with data, convert data to query string
+ // NB: the -G flag does not change the http verb. It just moves the data into the url.
+ if (parsedArguments['G'] || parsedArguments['get']) {
+ urlObject.query = urlObject.query ? urlObject.query : '';
+ let option = 'd' in parsedArguments ? 'd' : 'data' in parsedArguments ? 'data' : null;
+ if (option) {
+ let urlQueryString = '';
+
+ if (url.indexOf('?') < 0) {
+ url += '?';
+ } else {
+ urlQueryString += '&';
+ }
+
+ if (typeof(parsedArguments[option]) === 'object') {
+ urlQueryString += parsedArguments[option].join('&');
+ } else {
+ urlQueryString += parsedArguments[option];
+ }
+ urlObject.query += urlQueryString;
+ url += urlQueryString;
+ delete parsedArguments[option];
+ }
+ }
+ let query = querystring.parse(urlObject.query, null, null, { maxKeys: 10000 });
+
+ urlObject.search = null // Clean out the search/query portion.
+ let request = {
+ url: url,
+ urlWithoutQuery: URL.format(urlObject)
+ }
+ if (compressed) {
+ request['compressed'] = true;
+ }
+
+ if (Object.keys(query).length > 0) {
+ request.query = query;
+ }
+ if (headers) {
+ request.headers = headers;
+ }
+ request['method'] = method;
+
+ if (cookies) {
+ request.cookies = cookies;
+ request.cookieString = cookieString.replace('Cookie: ', '');
+ }
+ if (multipartUploads) {
+ request.multipartUploads = multipartUploads;
+ }
+ if (parsedArguments.data) {
+ request.data = parsedArguments.data;
+ } else if (parsedArguments['data-binary']) {
+ request.data = parsedArguments['data-binary']
+ request.isDataBinary = true;
+ } else if (parsedArguments['d']) {
+ request.data = parsedArguments['d'];
+ } else if (parsedArguments['data-ascii']) {
+ request.data = parsedArguments['data-ascii'];
+ }
+
+ if (parsedArguments['u']) {
+ request.auth = parsedArguments['u'];
+ }
+ if (parsedArguments['user']) {
+ request.auth = parsedArguments['user'];
+ }
+ if (Array.isArray(request.data)) {
+ request.dataArray = request.data
+ request.data = joinDataArguments(request.data);
+ }
+
+ if (parsedArguments['k'] || parsedArguments['insecure']) {
+ request.insecure = true;
+ }
+ return request;
+}
+
+
+export default parseCurlCommand;
\ No newline at end of file
diff --git a/components/modal.vue b/components/modal.vue
new file mode 100644
index 000000000..2edeaa518
--- /dev/null
+++ b/components/modal.vue
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+ default body
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 38aa43656..22a37ced9 100644
--- a/package.json
+++ b/package.json
@@ -1,28 +1,29 @@
{
- "name": "postwoman",
- "version": "0.1.0",
- "description": "Lightweight API request builder by Liyas Thomas",
- "author": "liyasthomas",
- "private": true,
- "scripts": {
- "predev": "node build.js --dev",
- "dev": "nuxt",
- "prebuild": "node build.js",
- "build": "nuxt build",
- "start": "nuxt start",
- "pregenerate": "node build.js",
- "generate": "nuxt generate"
- },
- "dependencies": {
- "@nuxtjs/axios": "^5.6.0",
- "@nuxtjs/pwa": "^3.0.0-0",
- "nuxt": "^2.9.2",
- "vue-virtual-scroll-list": "^1.4.2",
- "vuejs-auto-complete": "^0.9.0",
- "vuex-persist": "^2.1.0"
- },
- "devDependencies": {
- "node-sass": "^4.12.0",
- "sass-loader": "^7.3.1"
- }
-}
+ "name": "postwoman",
+ "version": "0.1.0",
+ "description": "Lightweight API request builder by Liyas Thomas",
+ "author": "liyasthomas",
+ "private": true,
+ "scripts": {
+ "predev": "node build.js --dev",
+ "dev": "nuxt",
+ "prebuild": "node build.js",
+ "build": "nuxt build",
+ "start": "nuxt start",
+ "pregenerate": "node build.js",
+ "generate": "nuxt generate"
+ },
+ "dependencies": {
+ "@nuxtjs/axios": "^5.6.0",
+ "@nuxtjs/pwa": "^3.0.0-0",
+ "nuxt": "^2.9.2",
+ "vue-virtual-scroll-list": "^1.4.2",
+ "vuejs-auto-complete": "^0.9.0",
+ "vuex-persist": "^2.1.0",
+ "yargs-parser": "^13.1.1"
+ },
+ "devDependencies": {
+ "node-sass": "^4.12.0",
+ "sass-loader": "^7.3.1"
+ }
+}
\ No newline at end of file
diff --git a/pages/index.vue b/pages/index.vue
index b43df6625..4a14af41e 100644
--- a/pages/index.vue
+++ b/pages/index.vue
@@ -1,6 +1,19 @@
+
+
+
+
Import
+
+
+
+
+
+
+
+
-
@@ -199,6 +212,8 @@
import section from "../components/section";
import textareaAutoHeight from "../directives/textareaAutoHeight";
import toggle from "../components/toggle";
+ import import_modal from "../components/modal";
+ import parseCurlCommand from '../assets/js/curlparser.js';
const statusCategories = [{
name: 'informational',
@@ -254,12 +269,13 @@
components: {
'pw-section': section,
'pw-toggle': toggle,
+ 'import-modal': import_modal,
history,
- autocomplete
+ autocomplete,
},
data() {
return {
-
+ showModal: false,
method: 'GET',
url: 'https://reqres.in',
auth: 'None',
@@ -605,6 +621,32 @@
});
observer.observe(requestElement);
+ },
+ handleImport () {
+ console.log("handleimport");
+ let textarea = document.getElementById("import-text")
+ let text = textarea.value;
+ console.log(text);
+ try {
+ let parsedCurl = parseCurlCommand(text);
+ console.log(parsedCurl);
+ this.url=parsedCurl.url.replace(/\"/g,"").replace(/\'/g,"");
+ this.url = this.url[this.url.length -1] == '/' ? this.url.slice(0, -1): this.url;
+ this.path = "";
+ this.headers
+ this.showModal = false;
+ this.headers = [];
+ for (const key of Object.keys(parsedCurl.headers)) {
+ this.headers.push({
+ key: key,
+ value: parsedCurl.headers[key]
+ })
+ }
+ this.method = parsedCurl.method.toUpperCase();
+ } catch (error) {
+ console.log(error)
+ this.showModal = false;
+ }
}
},
mounted() {