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

express-graphql

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

express-graphql - npm Package Compare versions

Comparing version 0.5.4 to 0.6.0

101

dist/index.js

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

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/**

@@ -19,2 +19,3 @@ * Copyright (c) 2015, Facebook, Inc.

exports.default = graphqlHTTP;
exports.getGraphQLParams = getGraphQLParams;

@@ -54,2 +55,7 @@ var _accepts = require('accepts');

*/
/**
* All information about a GraphQL request.
*/
function graphqlHTTP(options) {

@@ -69,4 +75,6 @@ if (!options) {

var formatErrorFn = void 0;
var extensionsFn = void 0;
var showGraphiQL = void 0;
var query = void 0;
var documentAST = void 0;
var variables = void 0;

@@ -100,2 +108,3 @@ var operationName = void 0;

formatErrorFn = optionsData.formatError;
extensionsFn = optionsData.extensions;

@@ -113,13 +122,10 @@ validationRules = _graphql.specifiedRules;

// Parse the Request body.
return (0, _parseBody.parseBody)(request);
}).then(function (bodyData) {
var urlData = request.url && _url2.default.parse(request.url, true).query || {};
showGraphiQL = graphiql && canDisplayGraphiQL(request, urlData, bodyData);
// Parse the Request to get GraphQL request parameters.
return getGraphQLParams(request);
}).then(function (params) {
// Get GraphQL params from the request and POST body data.
var params = getGraphQLParams(urlData, bodyData);
query = params.query;
variables = params.variables;
operationName = params.operationName;
showGraphiQL = graphiql && canDisplayGraphiQL(request, params);

@@ -139,3 +145,2 @@ // If there is no query, but GraphiQL will be displayed, do not produce

// Parse source to AST, reporting any syntax error.
var documentAST = void 0;
try {

@@ -182,2 +187,19 @@ documentAST = (0, _graphql.parse)(source);

}
}).then(function (result) {
// Collect and apply any metadata extensions if a function was provided.
// http://facebook.github.io/graphql/#sec-Response-Format
if (result && extensionsFn) {
return Promise.resolve(extensionsFn({
document: documentAST,
variables: variables,
operationName: operationName,
result: result
})).then(function (extensions) {
if (extensions && (typeof extensions === 'undefined' ? 'undefined' : _typeof(extensions)) === 'object') {
result.extensions = extensions;
}
return result;
});
}
return result;
}).catch(function (error) {

@@ -188,2 +210,10 @@ // If an error was caught, report the httpError status, or 500.

}).then(function (result) {
// If no data was included in the result, that indicates a runtime query
// error, indicate as such with a generic status code.
// Note: Information about the error itself will still be contained in
// the resulting JSON payload.
// http://facebook.github.io/graphql/#sec-Data
if (result && result.data === null) {
response.statusCode = 500;
}
// Format any encountered errors.

@@ -195,3 +225,3 @@ if (result && result.errors) {

if (showGraphiQL) {
var data = (0, _renderGraphiQL.renderGraphiQL)({
var payload = (0, _renderGraphiQL.renderGraphiQL)({
query: query, variables: variables,

@@ -201,8 +231,8 @@ operationName: operationName, result: result

response.setHeader('Content-Type', 'text/html; charset=utf-8');
response.end(data);
sendResponse(response, payload);
} else {
// Otherwise, present JSON directly.
var _data = JSON.stringify(result, null, pretty ? 2 : 0);
var _payload = JSON.stringify(result, null, pretty ? 2 : 0);
response.setHeader('Content-Type', 'application/json; charset=utf-8');
response.end(_data);
sendResponse(response, _payload);
}

@@ -214,11 +244,25 @@ });

/**
* Provided a "Request" provided by express or connect (typically a node style
* HTTPClientRequest), Promise the GraphQL request parameters.
*/
function getGraphQLParams(request) {
return (0, _parseBody.parseBody)(request).then(function (bodyData) {
var urlData = request.url && _url2.default.parse(request.url, true).query || {};
return parseGraphQLParams(urlData, bodyData);
});
}
/**
* Helper function to get the GraphQL params from the request.
*/
function getGraphQLParams(urlData, bodyData) {
function parseGraphQLParams(urlData, bodyData) {
// GraphQL Query string.
var query = urlData.query || bodyData.query;
if (typeof query !== 'string') {
query = null;
}
// Parse the variables if needed.
var variables = urlData.variables || bodyData.variables;
if (variables && typeof variables === 'string') {
if (typeof variables === 'string') {
try {

@@ -229,2 +273,4 @@ variables = JSON.parse(variables);

}
} else if ((typeof variables === 'undefined' ? 'undefined' : _typeof(variables)) !== 'object') {
variables = null;
}

@@ -234,4 +280,9 @@

var operationName = urlData.operationName || bodyData.operationName;
if (typeof operationName !== 'string') {
operationName = null;
}
return { query: query, variables: variables, operationName: operationName };
var raw = urlData.raw !== undefined || bodyData.raw !== undefined;
return { query: query, variables: variables, operationName: operationName, raw: raw };
}

@@ -242,9 +293,19 @@

*/
function canDisplayGraphiQL(request, urlData, bodyData) {
function canDisplayGraphiQL(request, params) {
// If `raw` exists, GraphiQL mode is not enabled.
var raw = urlData.raw !== undefined || bodyData.raw !== undefined;
// Allowed to show GraphiQL if not requested as raw and this request
// prefers HTML over JSON.
return !raw && (0, _accepts2.default)(request).types(['json', 'html']) === 'html';
return !params.raw && (0, _accepts2.default)(request).types(['json', 'html']) === 'html';
}
module.exports = exports['default'];
/**
* Helper function for sending the response data. Use response.send it method
* exists (express), otherwise use response.end (connect).
*/
function sendResponse(response, data) {
if (typeof response.send === 'function') {
response.send(data);
} else {
response.end(data);
}
}

21

dist/parseBody.js

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

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/**

@@ -42,7 +42,13 @@ * Copyright (c) 2015, Facebook, Inc.

/**
* Provided a "Request" provided by express or connect (typically a node style
* HTTPClientRequest), Promise the body data contained.
*/
function parseBody(req) {
return new Promise(function (resolve, reject) {
var body = req.body;
// If express has already parsed a body as a keyed object, use it.
if (_typeof(req.body) === 'object' && !(req.body instanceof Buffer)) {
return resolve(req.body);
if ((typeof body === 'undefined' ? 'undefined' : _typeof(body)) === 'object' && !(body instanceof Buffer)) {
return resolve(body);
}

@@ -59,8 +65,8 @@

// was application/graphql, parse the string body.
if (typeof req.body === 'string' && typeInfo.type === 'application/graphql') {
return resolve(graphqlParser(req.body));
if (typeof body === 'string' && typeInfo.type === 'application/graphql') {
return resolve(graphqlParser(body));
}
// Already parsed body we didn't recognise? Parse nothing.
if (req.body) {
if (body) {
return resolve({});

@@ -126,3 +132,4 @@ }

// Get content-encoding (e.g. gzip)
var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase();
var contentEncoding = req.headers['content-encoding'];
var encoding = typeof contentEncoding === 'string' ? contentEncoding.toLowerCase() : 'identity';
var length = encoding === 'identity' ? req.headers['content-length'] : null;

@@ -129,0 +136,0 @@ var limit = 100 * 1024; // 100kb

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

function safeSerialize(data) {
return data ? JSON.stringify(data).replace(/\//g, '\\/') : null;
return data ? JSON.stringify(data).replace(/\//g, '\\/') : 'undefined';
}

@@ -27,0 +27,0 @@

{
"name": "express-graphql",
"version": "0.5.4",
"version": "0.6.0",
"description": "Production ready GraphQL HTTP middleware.",

@@ -56,3 +56,3 @@ "contributors": [

"build": "rm -rf dist/* && babel src --ignore __tests__ --out-dir dist",
"watch": "babel --optional runtime resources/watch.js | node",
"watch": "node resources/watch.js",
"cover": "babel-node node_modules/.bin/isparta cover --root src --report html node_modules/.bin/_mocha -- $npm_package_options_mocha",

@@ -69,34 +69,36 @@ "cover:lcov": "babel-node node_modules/.bin/isparta cover --root src --report lcovonly node_modules/.bin/_mocha -- $npm_package_options_mocha",

"devDependencies": {
"babel-cli": "^6.9.0",
"babel-eslint": "6.0.4",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-async-to-generator": "6.8.0",
"babel-plugin-transform-class-properties": "6.9.0",
"babel-plugin-transform-flow-strip-types": "6.8.0",
"babel-plugin-transform-runtime": "6.9.0",
"babel-preset-es2015": "6.9.0",
"babel-register": "6.9.0",
"babel-runtime": "6.9.0",
"body-parser": "1.15.1",
"babel-cli": "6.18.0",
"babel-eslint": "7.1.0",
"babel-plugin-add-module-exports": "0.2.1",
"babel-plugin-transform-async-to-generator": "6.16.0",
"babel-plugin-transform-class-properties": "6.18.0",
"babel-plugin-transform-flow-strip-types": "6.18.0",
"babel-plugin-transform-runtime": "6.15.0",
"babel-preset-es2015": "6.18.0",
"babel-register": "6.18.0",
"babel-runtime": "6.18.0",
"body-parser": "1.15.2",
"chai": "3.5.0",
"connect": "3.4.1",
"content-type": "1.0.1",
"coveralls": "2.11.9",
"eslint": "2.10.2",
"eslint-plugin-babel": "3.2.0",
"express": "4.13.4",
"connect": "3.5.0",
"content-type": "1.0.2",
"coveralls": "2.11.15",
"eslint": "3.10.0",
"eslint-plugin-babel": "3.3.0",
"eslint-plugin-flowtype": "2.25.0",
"express": "4.14.0",
"express3": "*",
"flow-bin": "0.25.0",
"graphql": "0.7.0",
"flow-bin": "0.35.0",
"graphql": "0.8.1",
"isparta": "4.0.0",
"mocha": "2.5.3",
"multer": "1.1.0",
"raw-body": "2.1.6",
"sane": "1.3.4",
"supertest": "1.0.1",
"supertest-as-promised": "2.0.2"
"mocha": "3.1.2",
"multer": "1.2.0",
"raw-body": "2.1.7",
"sane": "1.4.1",
"sinon": "1.17.6",
"supertest": "2.0.1",
"supertest-as-promised": "4.0.2"
},
"peerDependencies": {
"graphql": "^0.5.0-b || ^0.6.0 || ^0.7.0"
"graphql": "^0.5.0-b || ^0.6.0 || ^0.7.0 || ^0.8.0-b"
}
}

@@ -35,7 +35,7 @@ GraphQL HTTP Server Middleware

* **`schema`**: A `GraphQLSchema` instance from [`graphql-js`][].
* **`schema`**: A `GraphQLSchema` instance from [`GraphQL.js`][].
A `schema` *must* be provided.
* **`graphiql`**: If `true`, presents [GraphiQL][] when the route with a
`/graphiql` appended is loaded in a browser. We recommend that you set
* **`graphiql`**: If `true`, presents [GraphiQL][] when the GraphQL endpoint is
loaded in a browser. We recommend that you set
`graphiql` to `true` when your app is in development, because it's

@@ -45,6 +45,6 @@ quite useful. You may or may not want it in production.

* **`rootValue`**: A value to pass as the `rootValue` to the `graphql()`
function from [`graphql-js`][].
function from [`GraphQL.js`][].
* **`context`**: A value to pass as the `context` to the `graphql()`
function from [`graphql-js`][]. If `context` is not provided, the
function from [`GraphQL.js`][]. If `context` is not provided, the
`request` object is passed as the context.

@@ -58,2 +58,9 @@

* **`extensions`**: An optional function for adding additional metadata to the
GraphQL response as a key-value object. The result will be added to
`"extensions"` field in the resulting JSON. This is often a useful place to
add development time metadata such as the runtime of a query or the amount
of resources consumed. This may be an async function. The function is
give one object as an argument: `{ document, variables, operationName, result }`.
* **`validationRules`**: Optional additional validation rules queries must

@@ -147,2 +154,58 @@ satisfy in addition to those defined by the GraphQL spec.

## Providing Extensions
The GraphQL response allows for adding additional information in a response to
a GraphQL query via a field in the response called `"extensions"`. This is added
by providing an `extensions` function when using `graphqlHTTP`. The function
must return a JSON-serializable Object.
When called, this is provided an argument which you can use to get information
about the GraphQL request:
`{ document, variables, operationName, result }`
This example illustrates adding the amount of time consumed by running the
provided query, which could perhaps be used by your development tools.
```js
const graphqlHTTP = require('express-graphql');
const app = express();
app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}));
app.use('/graphql', graphqlHTTP(request => {
const startTime = Date.now();
return {
schema: MyGraphQLSchema,
graphiql: true,
extensions({ document, variables, operationName, result }) {
return { runTime: Date.now() - startTime };
}
};
}));
```
When querying this endpoint, it would include this information in the result,
for example:
```js
{
"data": { ... }
"extensions": {
"runTime": 135
}
}
```
## Other Exports
**`getGraphQLParams(request: Request): Promise<GraphQLParams>`**
Given an HTTP Request, this returns a Promise for the parameters relevant to
running a GraphQL request. This function is used internally to handle the
incoming request, you may use it directly for building other similar services.
## Debugging Tips

@@ -162,3 +225,3 @@

[`graphql-js`]: https://github.com/graphql/graphql-js
[`GraphQL.js`]: https://github.com/graphql/graphql-js
[`formatError`]: https://github.com/graphql/graphql-js/blob/master/src/error/formatError.js

@@ -165,0 +228,0 @@ [GraphiQL]: https://github.com/graphql/graphiql

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