New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

fetch-multipart-graphql

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fetch-multipart-graphql - npm Package Compare versions

Comparing version 1.0.5 to 1.0.6

src/parseMultipartHttp.js

136

dist/parseMultipartHTTP.js

@@ -6,67 +6,81 @@ 'use strict';

});
exports.parseMultipartHTTP = parseMultipartHTTP;
// borrowed mostly from apollo-link
function parseMultipartHTTP(plaintext) {
var results = [];
// Split plaintext using encapsulation boundary
var boundary = '\r\n---\r\n';
var terminatingBoundary = '\r\n-----\r\n';
var parts = plaintext.split(boundary);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = parts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var part = _step.value;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
// Split part into header and body
if (part.length) {
var partArr = part.split('\r\n\r\n');
// Read the Content-Length header, which must be included in the response
var headers = partArr[0];
var headersArr = headers.split('\r\n');
var contentLengthHeader = headersArr.find(function (headerLine) {
return headerLine.toLowerCase().indexOf('content-length:') >= 0;
});
if (contentLengthHeader === undefined) {
return null;
}
var contentLengthArr = contentLengthHeader.split(':');
var contentLength = void 0;
if (contentLengthArr.length === 2 && !isNaN(parseInt(contentLengthArr[1]))) {
contentLength = parseInt(contentLengthArr[1]);
} else {
return null;
}
var body = partArr[1];
if (body && body.length) {
// Strip out the terminating boundary
body = body.replace(terminatingBoundary, '');
// Check that length of body matches the Content-Length
if (body.length !== contentLength) {
return null;
}
results.push(JSON.parse(body));
} else {
return null;
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
exports.parseMultipartHttp = parseMultipartHttp;
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var boundary = '\r\n---\r\n';
var terminatingBoundary = '\r\n-----\r\n';
function splitWithRest(string, delim) {
var index = string.indexOf(delim);
if (index < 0) {
return [string];
}
return [string.substring(0, index), string.substring(index + delim.length)];
}
return results;
function parseMultipartHttp(buffer) {
var previousParts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
var _splitWithRest = splitWithRest(buffer, boundary),
_splitWithRest2 = _slicedToArray(_splitWithRest, 2),
rest = _splitWithRest2[1];
if (!(rest && rest.length)) {
// we did not finish receiving the initial boundary
return {
newBuffer: buffer,
parts: previousParts
};
}
var parts = splitWithRest(rest, '\r\n\r\n');
var headers = parts[0];
rest = parts[1];
if (!(rest && rest.length)) {
// we did not finish receiving the headers
return {
newBuffer: buffer,
parts: previousParts
};
}
var headersArr = headers.split('\r\n');
var contentLengthHeader = headersArr.find(function (headerLine) {
return headerLine.toLowerCase().indexOf('content-length:') >= 0;
});
if (contentLengthHeader === undefined) {
throw new Error('Invalid MultiPart Response, no content-length header');
}
var contentLengthArr = contentLengthHeader.split(':');
var contentLength = void 0;
if (contentLengthArr.length === 2 && !isNaN(parseInt(contentLengthArr[1]))) {
contentLength = parseInt(contentLengthArr[1]);
} else {
throw new Error('Invalid MultiPart Response, could not parse content-length');
}
// Strip out the terminating boundary
rest = rest.replace(terminatingBoundary, '');
if (rest.length < contentLength) {
// still waiting for more body to be sent;
return {
newBuffer: buffer,
parts: previousParts
};
}
var body = rest.substring(0, contentLength);
var nextBuffer = rest.substring(contentLength);
var part = JSON.parse(body);
var newParts = [].concat(_toConsumableArray(previousParts), [part]);
if (nextBuffer.length) {
return parseMultipartHttp(nextBuffer, newParts);
}
return { parts: newParts, newBuffer: '' };
}

@@ -8,3 +8,3 @@ 'use strict';

var _parseMultipartHTTP = require('./parseMultipartHTTP');
var _parseMultipartHttp2 = require('./parseMultipartHttp');

@@ -43,50 +43,49 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

this.previousResponse = null;
this.processedChunks = 0;
this.chunkBuffer = '';
this.processedChunks = 0;
}
PatchResolver.prototype.handleChunk = function (data) {
var results = (0, _parseMultipartHTTP.parseMultipartHTTP)(this.chunkBuffer + data);
if (results === null) {
// The part is not complete yet, add it to the buffer
// and wait for the next chunk to arrive
this.chunkBuffer += data;
} else {
this.chunkBuffer = ''; // Reset
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
this.chunkBuffer += data;
try {
for (var _iterator = results[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var part = _step.value;
var _parseMultipartHttp = (0, _parseMultipartHttp2.parseMultipartHttp)(this.chunkBuffer),
newBuffer = _parseMultipartHttp.newBuffer,
parts = _parseMultipartHttp.parts;
if (this.processedChunks === 0) {
this.previousResponse = part;
this.onResponse(this.previousResponse);
} else {
if (!(Array.isArray(part.path) && typeof part.data !== 'undefined')) {
throw new Error('invalid patch format ' + JSON.stringify(part, null, 2));
}
this.previousResponse = Object.assign({}, this.previousResponse, {
data: applyPatch(this.previousResponse.data, part.path, part.data),
errors: mergeErrors(this.previousResponse.errors, part.errors)
});
this.chunkBuffer = newBuffer;
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
this.onResponse(this.previousResponse);
try {
for (var _iterator = parts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var part = _step.value;
if (this.processedChunks === 0) {
this.previousResponse = part;
this.onResponse(this.previousResponse);
} else {
if (!(Array.isArray(part.path) && typeof part.data !== 'undefined')) {
throw new Error('invalid patch format ' + JSON.stringify(part, null, 2));
}
this.processedChunks += 1;
this.previousResponse = Object.assign({}, this.previousResponse, {
data: applyPatch(this.previousResponse.data, part.path, part.data),
errors: mergeErrors(this.previousResponse.errors, part.errors)
});
this.onResponse(this.previousResponse);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
this.processedChunks += 1;
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
if (_didIteratorError) {
throw _iteratorError;
}

@@ -93,0 +92,0 @@ }

{
"name": "fetch-multipart-graphql",
"version": "1.0.5",
"version": "1.0.6",
"description": "Cross browser function to fetch and parse streaming multipart graphql responses.",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -47,3 +47,3 @@ import { PatchResolver } from '../PatchResolver';

'',
'-----',
'-----\r\n',
].join('\r\n');

@@ -90,4 +90,7 @@

console.log('chunk1.length', chunk1.length);
const chunk1a = chunk1.substr(0, 35);
const chunk1b = chunk1.substr(36);
const chunk1b = chunk1.substr(35, 80);
const chunk1c = chunk1.substr(35 + 80);

@@ -97,2 +100,4 @@ resolver.handleChunk(chunk1a);

resolver.handleChunk(chunk1b);
expect(onResponse).not.toHaveBeenCalled();
resolver.handleChunk(chunk1c);
expect(onResponse).toHaveBeenCalledWith({

@@ -104,3 +109,3 @@ data: { viewer: { currencies: null, user: { profile: null } } },

const chunk2a = chunk2.substr(0, 35);
const chunk2b = chunk2.substr(36);
const chunk2b = chunk2.substr(35);

@@ -122,3 +127,3 @@ resolver.handleChunk(chunk2a);

const chunk3b = chunk3.substr(11, 20);
const chunk3c = chunk3.substr(21);
const chunk3c = chunk3.substr(11 + 20);

@@ -140,2 +145,85 @@ resolver.handleChunk(chunk3a);

it('should work when chunks are combined', function() {
const onResponse = jest.fn();
const resolver = new PatchResolver({
onResponse,
});
resolver.handleChunk(chunk1 + chunk2);
expect(onResponse.mock.calls[0][0]).toEqual({
data: { viewer: { currencies: null, user: { profile: null } } },
});
expect(onResponse.mock.calls[1][0]).toEqual({
data: {
viewer: {
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', 'MXN'],
user: { profile: null },
},
},
});
});
it('should work when chunks are combined and split', function() {
const onResponse = jest.fn();
const resolver = new PatchResolver({
onResponse,
});
const chunk3a = chunk3.substr(0, 10);
const chunk3b = chunk3.substr(11, 20);
const chunk3c = chunk3.substr(11 + 20);
resolver.handleChunk(chunk1 + chunk2 + chunk3a);
expect(onResponse.mock.calls[0][0]).toEqual({
data: { viewer: { currencies: null, user: { profile: null } } },
});
expect(onResponse.mock.calls[1][0]).toEqual({
data: {
viewer: {
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', 'MXN'],
user: { profile: null },
},
},
});
onResponse.mockClear();
resolver.handleChunk(chunk3b);
expect(onResponse).not.toHaveBeenCalled();
resolver.handleChunk(chunk3c);
expect(onResponse).toHaveBeenCalledWith({
data: {
viewer: {
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', 'MXN'],
user: { profile: { displayName: 'Steven Seagal' } },
},
},
});
});
it('should work when chunks are combined across boundaries', function() {
const onResponse = jest.fn();
const resolver = new PatchResolver({
onResponse,
});
const chunk2a = chunk2.substring(0, 35);
const chunk2b = chunk2.substring(35);
resolver.handleChunk(chunk1 + chunk2a);
expect(onResponse).toHaveBeenCalledWith({
data: { viewer: { currencies: null, user: { profile: null } } },
});
onResponse.mockClear();
resolver.handleChunk(chunk2b);
expect(onResponse).toHaveBeenCalledWith({
data: {
viewer: {
currencies: ['USD', 'GBP', 'EUR', 'CAD', 'AUD', 'CHF', 'MXN'],
user: { profile: null },
},
},
});
});
it('should merge errors', function() {

@@ -175,2 +263,3 @@ const onResponse = jest.fn();

});
it('should work', function() {});
});

@@ -1,2 +0,2 @@

import { parseMultipartHTTP } from './parseMultipartHTTP';
import { parseMultipartHttp } from './parseMultipartHttp';

@@ -32,33 +32,28 @@ // recursive function to apply the patch to the previous response

this.previousResponse = null;
this.processedChunks = 0;
this.chunkBuffer = '';
this.processedChunks = 0;
}
PatchResolver.prototype.handleChunk = function(data) {
const results = parseMultipartHTTP(this.chunkBuffer + data);
if (results === null) {
// The part is not complete yet, add it to the buffer
// and wait for the next chunk to arrive
this.chunkBuffer += data;
} else {
this.chunkBuffer = ''; // Reset
for (const part of results) {
if (this.processedChunks === 0) {
this.previousResponse = part;
this.onResponse(this.previousResponse);
} else {
if (!(Array.isArray(part.path) && typeof part.data !== 'undefined')) {
throw new Error('invalid patch format ' + JSON.stringify(part, null, 2));
}
this.previousResponse = {
...this.previousResponse,
data: applyPatch(this.previousResponse.data, part.path, part.data),
errors: mergeErrors(this.previousResponse.errors, part.errors),
};
this.chunkBuffer += data;
const { newBuffer, parts } = parseMultipartHttp(this.chunkBuffer);
this.chunkBuffer = newBuffer;
for (const part of parts) {
if (this.processedChunks === 0) {
this.previousResponse = part;
this.onResponse(this.previousResponse);
} else {
if (!(Array.isArray(part.path) && typeof part.data !== 'undefined')) {
throw new Error('invalid patch format ' + JSON.stringify(part, null, 2));
}
this.previousResponse = {
...this.previousResponse,
data: applyPatch(this.previousResponse.data, part.path, part.data),
errors: mergeErrors(this.previousResponse.errors, part.errors),
};
this.onResponse(this.previousResponse);
}
this.processedChunks += 1;
this.onResponse(this.previousResponse);
}
this.processedChunks += 1;
}
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc