Skip to content

Commit 9af9acc

Browse files
authored
Merge pull request #67 from postmanlabs/IMPORT-774-github-9941-import-feature-for-graphql-broken
[IMPORT-774] Graphql data mode from curl import
2 parents b7971d8 + 7afed8b commit 9af9acc

File tree

2 files changed

+93
-5
lines changed

2 files changed

+93
-5
lines changed

src/lib.js

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ var program,
1313

1414
curlConverter = {
1515
requestUrl: '',
16-
1716
initialize: function() {
1817
/**
1918
* Collects values from the command line arguments and adds them to the memo array.
@@ -677,6 +676,75 @@ var program,
677676
}
678677
},
679678

679+
/**
680+
* Escape JSON strings before JSON.parse
681+
*
682+
* @param {string} jsonString - Input JSON string
683+
* @returns {string} - JSON string with escaped characters
684+
*/
685+
escapeJson: function (jsonString) {
686+
// eslint-disable-next-line no-implicit-globals
687+
meta = { // table of character substitutions
688+
'\t': '\\t',
689+
'\n': '\\n',
690+
'\f': '\\f',
691+
'\r': '\\r'
692+
};
693+
return jsonString.replace(/[\t\n\f\r]/g, (char) => {
694+
return meta[char];
695+
});
696+
},
697+
698+
/**
699+
* Identifies whether the input data string is a graphql query or not
700+
*
701+
* @param {string} dataString - Input data string to check if it is a graphql query
702+
* @param {string} contentType - Content type header value
703+
* @returns {Object} - { result: true, graphql: {Object} } if dataString is a graphql query else { result: false }
704+
*/
705+
identifyGraphqlRequest: function (dataString, contentType) {
706+
try {
707+
const rawDataObj = _.attempt(JSON.parse, this.escapeJson(dataString));
708+
if (contentType === 'application/json' && rawDataObj && !_.isError(rawDataObj)) {
709+
if (!_.has(rawDataObj, 'query') || !_.isString(rawDataObj.query)) {
710+
return { result: false };
711+
}
712+
if (_.has(rawDataObj, 'variables')) {
713+
if (!_.isObject(rawDataObj.variables)) {
714+
return { result: false };
715+
}
716+
}
717+
else {
718+
rawDataObj.variables = {};
719+
}
720+
if (_.has(rawDataObj, 'operationName')) {
721+
if (!_.isString(rawDataObj.operationName)) {
722+
return { result: false };
723+
}
724+
}
725+
else {
726+
rawDataObj.operationName = '';
727+
}
728+
if (_.keys(rawDataObj).length === 3) {
729+
const graphqlVariables = JSON.stringify(rawDataObj.variables, null, 2);
730+
return {
731+
result: true,
732+
graphql: {
733+
query: rawDataObj.query,
734+
operationName: rawDataObj.operationName,
735+
variables: graphqlVariables === '{}' ? '' : graphqlVariables
736+
}
737+
};
738+
}
739+
}
740+
return { result: false };
741+
}
742+
catch (e) {
743+
return { result: false };
744+
}
745+
},
746+
747+
680748
convertCurlToRequest: function(curlString, shouldRetry = true) {
681749
try {
682750
this.initialize();
@@ -748,10 +816,19 @@ var program,
748816
bodyArr.push(this.trimQuotesFromString(dataUrlencode));
749817
bodyArr.push(this.trimQuotesFromString(dataAsciiString));
750818

751-
request.body.mode = 'raw';
752-
request.body.raw = _.join(_.reject(bodyArr, (ele) => {
753-
return !ele;
754-
}), '&');
819+
const rawDataString = _.join(_.reject(bodyArr, (ele) => {
820+
return !ele;
821+
}), '&'),
822+
graphqlRequestData = this.identifyGraphqlRequest(rawDataString, content_type);
823+
824+
if (graphqlRequestData.result) {
825+
request.body.mode = 'graphql';
826+
request.body.graphql = graphqlRequestData.graphql;
827+
}
828+
else {
829+
request.body.mode = 'raw';
830+
request.body.raw = rawDataString;
831+
}
755832

756833
urlData = request.data;
757834
}

test/conversion.test.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,17 @@ describe('Curl converter should', function() {
712712
done();
713713
});
714714

715+
it('[Github #9941]: should correctly identify graphql queries', function(done) {
716+
var result = Converter.convertCurlToRequest(`curl -L 'https://countries.trevorblades.com' \\
717+
-H 'Content-Type: application/json' \\
718+
-d '{"query":"{\r\n countries {\r\n code\r\n name\r\n emoji\r\n }\r\n}","variables":{}}'`);
719+
720+
expect(result.body).to.have.property('mode', 'graphql');
721+
expect(result.body.graphql.query).to.eql('{\r\n countries {\r\n code\r\n name\r\n emoji\r\n }\r\n}');
722+
expect(result.body.graphql.variables).to.eql('');
723+
done();
724+
});
725+
715726
describe('[Github #8843]: It should recognize non-apostrophed ("...") url with multi-param', function() {
716727
it('in case where there is multiple params with & in between in the url (https)', function(done) {
717728
convert({

0 commit comments

Comments
 (0)