Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

apollo-upload-client

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apollo-upload-client - npm Package Compare versions

Comparing version 2.0.2 to 3.0.0

src/batch-network-interface.js

202

dist/apollo-upload-client.js

@@ -11,2 +11,67 @@ 'use strict';

/**
* Extracts files from an Apollo Client Request, remembering positions in variables.
* @see {@link http://dev.apollodata.com/core/apollo-client-api.html#Request}
* @param {Object} request - Apollo GraphQL request to be sent to the server.
* @param {Object} request.variables - GraphQL variables map.
* @param {string} request.operationName - Name of the GraphQL query or mutation.
* @returns {Object} - Request with files extracted to a list with their original object paths.
*/
function extractRequestFiles(request) {
var files = [];
var variablesPath = void 0;
// Recursively search GraphQL input variables for FileList or File objects
for (var _iterator = new RecursiveIterator(request.variables), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref2;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref2 = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref2 = _i.value;
}
var _ref = _ref2;
var node = _ref.node,
path = _ref.path;
var isFileList = node instanceof window.FileList;
var isFile = node instanceof window.File;
if (isFileList || isFile) {
// Only populate when necessary
if (!variablesPath) variablesPath = objectPath(request.variables);
var pathString = path.join('.');
if (isFileList) {
// Convert to FileList to File array. This is
// necessary so items can be manipulated correctly
// by object-path. Either format may be used when
// populating GraphQL variables on the client.
variablesPath.set(pathString, Array.from(node));
} else if (isFile) {
// Move the File object to a multipart form field
// with the field name holding the original path
// to the file in the GraphQL input variables.
files.push({
variablesPath: 'variables.' + pathString,
file: node
});
variablesPath.del(pathString);
}
}
}
request.query = apolloClient.printAST(request.query);
return {
operation: request,
files: files
};
}
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

@@ -35,86 +100,89 @@

var hasFile = false;
var variables = void 0;
var formData = void 0;
var formData = new window.FormData();
// Recursively search GraphQL input variables for FileList or File objects
for (var _iterator = new RecursiveIterator(request.variables), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref3;
var _extractRequestFiles = extractRequestFiles(request),
operation = _extractRequestFiles.operation,
files = _extractRequestFiles.files;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref3 = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref3 = _i.value;
}
formData.append('operations', JSON.stringify(operation));
files.forEach(function (_ref2) {
var variablesPath = _ref2.variablesPath,
file = _ref2.file;
return formData.append(variablesPath, file);
});
return window.fetch(this._uri, _extends({
method: 'POST',
body: formData
}, options));
};
var _ref2 = _ref3;
var node = _ref2.node,
path = _ref2.path;
return HTTPUploadNetworkInterface;
}(apolloClient.HTTPFetchNetworkInterface);
var isFileList = node instanceof window.FileList;
var isFile = node instanceof window.File;
function createNetworkInterface(_ref3) {
var uri = _ref3.uri,
options = _objectWithoutProperties(_ref3, ['uri']);
// Only populate certain variables when nessesary
if (isFileList || isFile) {
if (!variables) variables = objectPath(request.variables);
var pathString = path.join('.');
}
return new HTTPUploadNetworkInterface(uri, options);
}
if (isFileList) {
// Convert to FileList to File array. This is
// nessesary so items can be manipulated correctly
// by object-path. Either format may be used when
// populating GraphQL variables on the client.
variables.set(pathString, Array.from(node));
} else if (isFile) {
// Check if this is the first file found
if (!hasFile) {
hasFile = true;
formData = new window.FormData();
}
var _extends$1 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
// Move the File object to a multipart form field
// with the field name holding the original path
// to the file in the GraphQL input variables.
formData.append(pathString, node);
variables.del(pathString);
}
}
function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
if (hasFile) {
// Add Apollo fields to the form
formData.append('operationName', request.operationName);
formData.append('query', apolloClient.printAST(request.query));
formData.append('variables', JSON.stringify(request.variables));
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// Send the multipart form
return window.fetch(this._uri, _extends({
body: formData,
method: 'POST'
}, options, {
headers: _extends({
Accept: '*/*'
}, options.headers)
}));
} else {
// No uploads, use the standard method
return _HTTPFetchNetworkInte.prototype.fetchFromRemoteEndpoint.call(this, { request: request, options: options });
}
function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var HTTPUploadBatchNetworkInterface = function (_HTTPBatchedNetworkIn) {
_inherits$1(HTTPUploadBatchNetworkInterface, _HTTPBatchedNetworkIn);
function HTTPUploadBatchNetworkInterface() {
_classCallCheck$1(this, HTTPUploadBatchNetworkInterface);
return _possibleConstructorReturn$1(this, _HTTPBatchedNetworkIn.apply(this, arguments));
}
HTTPUploadBatchNetworkInterface.prototype.batchedFetchFromRemoteEndpoint = function batchedFetchFromRemoteEndpoint(_ref) {
var requests = _ref.requests,
options = _ref.options;
var formData = new window.FormData();
var operations = requests.map(function (request, index) {
var _extractRequestFiles = extractRequestFiles(request),
operation = _extractRequestFiles.operation,
files = _extractRequestFiles.files;
files.forEach(function (_ref2) {
var variablesPath = _ref2.variablesPath,
file = _ref2.file;
return formData.append(index + '.' + variablesPath, file);
});
return operation;
});
formData.append('operations', JSON.stringify(operations));
return window.fetch(this._uri, _extends$1({
method: 'POST',
body: formData
}, options));
};
return HTTPUploadNetworkInterface;
}(apolloClient.HTTPFetchNetworkInterface);
return HTTPUploadBatchNetworkInterface;
}(apolloClient.HTTPBatchedNetworkInterface);
function createNetworkInterface(_ref4) {
var uri = _ref4.uri,
options = _objectWithoutProperties(_ref4, ['uri']);
function createBatchNetworkInterface(_ref3) {
var uri = _ref3.uri,
batchInterval = _ref3.batchInterval,
options = _objectWithoutProperties$1(_ref3, ['uri', 'batchInterval']);
return new HTTPUploadNetworkInterface(uri, options);
return new HTTPUploadBatchNetworkInterface(uri, batchInterval, options);
}
exports.extractRequestFiles = extractRequestFiles;
exports.HTTPUploadNetworkInterface = HTTPUploadNetworkInterface;
exports.createNetworkInterface = createNetworkInterface;
exports.HTTPUploadBatchNetworkInterface = HTTPUploadBatchNetworkInterface;
exports.createBatchNetworkInterface = createBatchNetworkInterface;
//# sourceMappingURL=apollo-upload-client.js.map

@@ -1,5 +0,70 @@

import { HTTPFetchNetworkInterface, printAST } from 'apollo-client';
import { HTTPBatchedNetworkInterface, HTTPFetchNetworkInterface, printAST } from 'apollo-client';
import RecursiveIterator from 'recursive-iterator';
import objectPath from 'object-path';
/**
* Extracts files from an Apollo Client Request, remembering positions in variables.
* @see {@link http://dev.apollodata.com/core/apollo-client-api.html#Request}
* @param {Object} request - Apollo GraphQL request to be sent to the server.
* @param {Object} request.variables - GraphQL variables map.
* @param {string} request.operationName - Name of the GraphQL query or mutation.
* @returns {Object} - Request with files extracted to a list with their original object paths.
*/
function extractRequestFiles(request) {
var files = [];
var variablesPath = void 0;
// Recursively search GraphQL input variables for FileList or File objects
for (var _iterator = new RecursiveIterator(request.variables), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref2;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref2 = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref2 = _i.value;
}
var _ref = _ref2;
var node = _ref.node,
path = _ref.path;
var isFileList = node instanceof window.FileList;
var isFile = node instanceof window.File;
if (isFileList || isFile) {
// Only populate when necessary
if (!variablesPath) variablesPath = objectPath(request.variables);
var pathString = path.join('.');
if (isFileList) {
// Convert to FileList to File array. This is
// necessary so items can be manipulated correctly
// by object-path. Either format may be used when
// populating GraphQL variables on the client.
variablesPath.set(pathString, Array.from(node));
} else if (isFile) {
// Move the File object to a multipart form field
// with the field name holding the original path
// to the file in the GraphQL input variables.
files.push({
variablesPath: 'variables.' + pathString,
file: node
});
variablesPath.del(pathString);
}
}
}
request.query = printAST(request.query);
return {
operation: request,
files: files
};
}
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

@@ -28,85 +93,85 @@

var hasFile = false;
var variables = void 0;
var formData = void 0;
var formData = new window.FormData();
// Recursively search GraphQL input variables for FileList or File objects
for (var _iterator = new RecursiveIterator(request.variables), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref3;
var _extractRequestFiles = extractRequestFiles(request),
operation = _extractRequestFiles.operation,
files = _extractRequestFiles.files;
if (_isArray) {
if (_i >= _iterator.length) break;
_ref3 = _iterator[_i++];
} else {
_i = _iterator.next();
if (_i.done) break;
_ref3 = _i.value;
}
formData.append('operations', JSON.stringify(operation));
files.forEach(function (_ref2) {
var variablesPath = _ref2.variablesPath,
file = _ref2.file;
return formData.append(variablesPath, file);
});
return window.fetch(this._uri, _extends({
method: 'POST',
body: formData
}, options));
};
var _ref2 = _ref3;
var node = _ref2.node,
path = _ref2.path;
return HTTPUploadNetworkInterface;
}(HTTPFetchNetworkInterface);
var isFileList = node instanceof window.FileList;
var isFile = node instanceof window.File;
function createNetworkInterface(_ref3) {
var uri = _ref3.uri,
options = _objectWithoutProperties(_ref3, ['uri']);
// Only populate certain variables when nessesary
if (isFileList || isFile) {
if (!variables) variables = objectPath(request.variables);
var pathString = path.join('.');
}
return new HTTPUploadNetworkInterface(uri, options);
}
if (isFileList) {
// Convert to FileList to File array. This is
// nessesary so items can be manipulated correctly
// by object-path. Either format may be used when
// populating GraphQL variables on the client.
variables.set(pathString, Array.from(node));
} else if (isFile) {
// Check if this is the first file found
if (!hasFile) {
hasFile = true;
formData = new window.FormData();
}
var _extends$1 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
// Move the File object to a multipart form field
// with the field name holding the original path
// to the file in the GraphQL input variables.
formData.append(pathString, node);
variables.del(pathString);
}
}
function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
if (hasFile) {
// Add Apollo fields to the form
formData.append('operationName', request.operationName);
formData.append('query', printAST(request.query));
formData.append('variables', JSON.stringify(request.variables));
function _classCallCheck$1(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
// Send the multipart form
return window.fetch(this._uri, _extends({
body: formData,
method: 'POST'
}, options, {
headers: _extends({
Accept: '*/*'
}, options.headers)
}));
} else {
// No uploads, use the standard method
return _HTTPFetchNetworkInte.prototype.fetchFromRemoteEndpoint.call(this, { request: request, options: options });
}
function _possibleConstructorReturn$1(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits$1(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var HTTPUploadBatchNetworkInterface = function (_HTTPBatchedNetworkIn) {
_inherits$1(HTTPUploadBatchNetworkInterface, _HTTPBatchedNetworkIn);
function HTTPUploadBatchNetworkInterface() {
_classCallCheck$1(this, HTTPUploadBatchNetworkInterface);
return _possibleConstructorReturn$1(this, _HTTPBatchedNetworkIn.apply(this, arguments));
}
HTTPUploadBatchNetworkInterface.prototype.batchedFetchFromRemoteEndpoint = function batchedFetchFromRemoteEndpoint(_ref) {
var requests = _ref.requests,
options = _ref.options;
var formData = new window.FormData();
var operations = requests.map(function (request, index) {
var _extractRequestFiles = extractRequestFiles(request),
operation = _extractRequestFiles.operation,
files = _extractRequestFiles.files;
files.forEach(function (_ref2) {
var variablesPath = _ref2.variablesPath,
file = _ref2.file;
return formData.append(index + '.' + variablesPath, file);
});
return operation;
});
formData.append('operations', JSON.stringify(operations));
return window.fetch(this._uri, _extends$1({
method: 'POST',
body: formData
}, options));
};
return HTTPUploadNetworkInterface;
}(HTTPFetchNetworkInterface);
return HTTPUploadBatchNetworkInterface;
}(HTTPBatchedNetworkInterface);
function createNetworkInterface(_ref4) {
var uri = _ref4.uri,
options = _objectWithoutProperties(_ref4, ['uri']);
function createBatchNetworkInterface(_ref3) {
var uri = _ref3.uri,
batchInterval = _ref3.batchInterval,
options = _objectWithoutProperties$1(_ref3, ['uri', 'batchInterval']);
return new HTTPUploadNetworkInterface(uri, options);
return new HTTPUploadBatchNetworkInterface(uri, batchInterval, options);
}
export { HTTPUploadNetworkInterface, createNetworkInterface };
export { extractRequestFiles, HTTPUploadNetworkInterface, createNetworkInterface, HTTPUploadBatchNetworkInterface, createBatchNetworkInterface };
//# sourceMappingURL=apollo-upload-client.module.js.map
{
"name": "apollo-upload-client",
"version": "2.0.2",
"description": "Enhances Apollo for intuitive file uploads via GraphQL mutations.",
"version": "3.0.0",
"description": "Enhances Apollo Client for intuitive file uploads via GraphQL mutations.",
"license": "MIT",

@@ -6,0 +6,0 @@ "author": {

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

# ![Apollo upload client](https://cdn.rawgit.com/jaydenseric/apollo-upload-client/v2.0.2/apollo-upload-logo.svg)
# ![Apollo upload client](https://cdn.rawgit.com/jaydenseric/apollo-upload-client/v3.0.0/apollo-upload-logo.svg)

@@ -18,3 +18,3 @@ ![NPM version](https://img.shields.io/npm/v/apollo-upload-client.svg?style=flat-square) ![Github issues](https://img.shields.io/github/issues/jaydenseric/apollo-upload-client.svg?style=flat-square) ![Github stars](https://img.shields.io/github/stars/jaydenseric/apollo-upload-client.svg?style=flat-square)

Create the Apollo client with the special network interface:
Setup Apollo client with a special network interface:

@@ -32,2 +32,16 @@ ```js

Alternatively enable [query batching](http://dev.apollodata.com/core/network.html#query-batching):
```js
import ApolloClient from 'apollo-client'
import {createBatchNetworkInterface} from 'apollo-upload-client'
const client = new ApolloClient({
networkInterface: createBatchNetworkInterface({
uri: '/graphql',
batchInterval: 10
})
})
```
Also setup [Apollo upload server](https://github.com/jaydenseric/apollo-upload-server).

@@ -123,6 +137,2 @@

## Caveats
- Batching is not compatible as only the standard Apollo network interface has been extended yet.
## Inspiration

@@ -129,0 +139,0 @@

@@ -1,68 +0,3 @@

import {HTTPFetchNetworkInterface, printAST} from 'apollo-client'
import RecursiveIterator from 'recursive-iterator'
import objectPath from 'object-path'
export class HTTPUploadNetworkInterface extends HTTPFetchNetworkInterface {
fetchFromRemoteEndpoint ({request, options}) {
let hasFile = false
let variables
let formData
// Recursively search GraphQL input variables for FileList or File objects
for (let {node, path} of new RecursiveIterator(request.variables)) {
const isFileList = node instanceof window.FileList
const isFile = node instanceof window.File
// Only populate certain variables when nessesary
if (isFileList || isFile) {
if (!variables) variables = objectPath(request.variables)
var pathString = path.join('.')
}
if (isFileList) {
// Convert to FileList to File array. This is
// nessesary so items can be manipulated correctly
// by object-path. Either format may be used when
// populating GraphQL variables on the client.
variables.set(pathString, Array.from(node))
} else if (isFile) {
// Check if this is the first file found
if (!hasFile) {
hasFile = true
formData = new window.FormData()
}
// Move the File object to a multipart form field
// with the field name holding the original path
// to the file in the GraphQL input variables.
formData.append(pathString, node)
variables.del(pathString)
}
}
if (hasFile) {
// Add Apollo fields to the form
formData.append('operationName', request.operationName)
formData.append('query', printAST(request.query))
formData.append('variables', JSON.stringify(request.variables))
// Send the multipart form
return window.fetch(this._uri, {
body: formData,
method: 'POST',
...options,
headers: {
Accept: '*/*',
...options.headers
}
})
} else {
// No uploads, use the standard method
return super.fetchFromRemoteEndpoint({request, options})
}
}
}
export function createNetworkInterface ({uri, ...options}) {
return new HTTPUploadNetworkInterface(uri, options)
}
export * from './helpers'
export * from './network-interface'
export * from './batch-network-interface'

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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