Skip to content

Commit a54894f

Browse files
authored
Add ES module support #37 (#56)
* Add ES module support #37 * Update yarn.lock, consolidate tsconfig.cjs.json into tsconfig.json * Fix linting issues * Add createComplexityRule as named export
1 parent 33b1fbf commit a54894f

File tree

11 files changed

+865
-484
lines changed

11 files changed

+865
-484
lines changed

README.md

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
# GraphQL Query Complexity Analysis for graphql-js
22

33
[![npm](https://img.shields.io/npm/dm/graphql-query-complexity)](https://www.npmjs.com/package/graphql-query-complexity)
4-
[![npm version](https://badge.fury.io/js/graphql-query-complexity.svg)](https://badge.fury.io/js/graphql-query-complexity)
4+
[![npm version](https://badge.fury.io/js/graphql-query-complexity.svg)](https://badge.fury.io/js/graphql-query-complexity)
55
[![CircleCI](https://circleci.com/gh/slicknode/graphql-query-complexity.svg?style=shield)](https://circleci.com/gh/slicknode/graphql-query-complexity)
66
[![Twitter Follow](https://img.shields.io/twitter/follow/slicknode?style=social)](https://twitter.com/slicknode)
77

88
This library provides GraphQL query analysis to reject complex queries to your GraphQL server.
99
This can be used to protect your GraphQL servers against resource exhaustion and DoS attacks.
1010

11-
Works with [graphql-js](https://github.com/graphql/graphql-js) reference implementation.
12-
11+
Works with [graphql-js](https://github.com/graphql/graphql-js) reference implementation.
1312

1413
## Installation
1514

16-
Install the package via npm
15+
Install the package via npm
1716

1817
```bash
1918
npm install -S graphql-query-complexity
@@ -24,39 +23,40 @@ npm install -S graphql-query-complexity
2423
Create the rule with a maximum query complexity:
2524

2625
```javascript
27-
import queryComplexity, {
26+
import {
27+
createComplexityRule,
2828
simpleEstimator
2929
} from 'graphql-query-complexity';
3030

31-
const rule = queryComplexity({
31+
const rule = createComplexityRule({
3232
// The maximum allowed query complexity, queries above this threshold will be rejected
3333
maximumComplexity: 1000,
34-
34+
3535
// The query variables. This is needed because the variables are not available
3636
// in the visitor of the graphql-js library
3737
variables: {},
3838

3939
// specify operation name only when pass multi-operation documents
4040
operationName?: string,
41-
41+
4242
// Optional callback function to retrieve the determined query complexity
4343
// Will be invoked whether the query is rejected or not
4444
// This can be used for logging or to implement rate limiting
4545
onComplete: (complexity: number) => {console.log('Determined query complexity: ', complexity)},
46-
46+
4747
// Optional function to create a custom error
4848
createError: (max: number, actual: number) => {
4949
return new GraphQLError(`Query is too complex: ${actual}. Maximum allowed complexity: ${max}`);
5050
},
51-
51+
5252
// Add any number of estimators. The estimators are invoked in order, the first
5353
// numeric value that is being returned by an estimator is used as the field complexity.
54-
// If no estimator returns a value, an exception is raised.
54+
// If no estimator returns a value, an exception is raised.
5555
estimators: [
5656
// Add more estimators here...
57-
57+
5858
// This will assign each field a complexity of 1 if no other estimator
59-
// returned a value.
59+
// returned a value.
6060
simpleEstimator({
6161
defaultComplexity: 1
6262
})
@@ -68,78 +68,85 @@ const rule = queryComplexity({
6868

6969
The complexity calculation of a GraphQL query can be customized with so called complexity estimators.
7070
A complexity estimator is a simple function that calculates the complexity for a field. You can add
71-
any number of complexity estimators to the rule, which are then executed one after another.
72-
The first estimator that returns a numeric complexity value determines the complexity for that field.
71+
any number of complexity estimators to the rule, which are then executed one after another.
72+
The first estimator that returns a numeric complexity value determines the complexity for that field.
7373

7474
At least one estimator has to return a complexity value, otherwise an exception is raised. You can
7575
for example use the [simpleEstimator](./src/estimators/simple/README.md) as the last estimator
76-
in your chain to define a default value.
76+
in your chain to define a default value.
7777

7878
You can use any of the available estimators to calculate the complexity of a field
7979
or write your own:
8080

81-
* **[`simpleEstimator`](src/estimators/simple/README.md):** The simple estimator returns a fixed complexity for each field. Can be used as
82-
last estimator in the chain for a default value.
83-
* **[`directiveEstimator`](src/estimators/directive/README.md):** Set the complexity via a directive in your
84-
schema definition (for example via GraphQL SDL)
85-
* **[`fieldExtensionsEstimator`](src/estimators/fieldExtensions/README.md):** The field extensions estimator lets you set a numeric value or a custom estimator
86-
function in the field config extensions of your schema.
87-
* PRs welcome...
81+
- **[`simpleEstimator`](src/estimators/simple/README.md):** The simple estimator returns a fixed complexity for each field. Can be used as
82+
last estimator in the chain for a default value.
83+
- **[`directiveEstimator`](src/estimators/directive/README.md):** Set the complexity via a directive in your
84+
schema definition (for example via GraphQL SDL)
85+
- **[`fieldExtensionsEstimator`](src/estimators/fieldExtensions/README.md):** The field extensions estimator lets you set a numeric value or a custom estimator
86+
function in the field config extensions of your schema.
87+
- PRs welcome...
8888

89-
Consult the documentation of each estimator for information about how to use them.
89+
Consult the documentation of each estimator for information about how to use them.
9090

9191
## Creating Custom Estimators
9292

93-
An estimator has the following function signature:
93+
An estimator has the following function signature:
9494

9595
```typescript
9696
type ComplexityEstimatorArgs = {
9797
// The composite type (interface, object, union) that the evaluated field belongs to
98-
type: GraphQLCompositeType,
99-
98+
type: GraphQLCompositeType;
99+
100100
// The GraphQLField that is being evaluated
101-
field: GraphQLField<any, any>,
102-
101+
field: GraphQLField<any, any>;
102+
103103
// The GraphQL node that is being evaluated
104-
node: FieldNode,
105-
104+
node: FieldNode;
105+
106106
// The input arguments of the field
107-
args: {[key: string]: any},
108-
107+
args: { [key: string]: any };
108+
109109
// The complexity of all child selections for that field
110-
childComplexity: number
111-
}
110+
childComplexity: number;
111+
};
112112

113113
type ComplexityEstimator = (options: ComplexityEstimatorArgs) => number | void;
114114
```
115115

116-
117116
## Usage with express-graphql
118117

119118
To use the query complexity analysis validation rule with express-graphql, use something like the
120-
following:
119+
following:
121120

122121
```javascript
123-
import queryComplexity, { simpleEstimator } from 'graphql-query-complexity';
122+
import {
123+
simpleEstimator,
124+
createComplexityRule,
125+
} from 'graphql-query-complexity';
124126
import express from 'express';
125127
import graphqlHTTP from 'express-graphql';
126128
import schema from './schema';
127129

128130
const app = express();
129-
app.use('/api', graphqlHTTP(async (request, response, {variables}) => ({
130-
schema,
131-
validationRules: [
132-
queryComplexity({
133-
estimators: [
134-
// Configure your estimators
135-
simpleEstimator({defaultComplexity: 1})
136-
],
137-
maximumComplexity: 1000,
138-
variables,
139-
onComplete: (complexity: number) => {console.log('Query Complexity:', complexity);},
140-
})
141-
]
142-
})));
131+
app.use(
132+
'/api',
133+
graphqlHTTP(async (request, response, { variables }) => ({
134+
schema,
135+
validationRules: [
136+
createComplexityRule({
137+
estimators: [
138+
// Configure your estimators
139+
simpleEstimator({ defaultComplexity: 1 }),
140+
],
141+
maximumComplexity: 1000,
142+
variables,
143+
onComplete: (complexity: number) => {
144+
console.log('Query Complexity:', complexity);
145+
},
146+
}),
147+
],
148+
}))
149+
);
143150
```
144151

145152
## Calculate query complexity
@@ -165,9 +172,7 @@ const query = parse(`
165172
`);
166173

167174
const complexity = getComplexity({
168-
estimators: [
169-
simpleEstimator({defaultComplexity: 1})
170-
],
175+
estimators: [simpleEstimator({ defaultComplexity: 1 })],
171176
schema,
172177
query,
173178
variables: {
@@ -178,10 +183,9 @@ const complexity = getComplexity({
178183
console.log(complexity); // Output: 3
179184
```
180185

181-
182186
## Prior Art
183187

184-
This project is inspired by the following prior projects:
188+
This project is inspired by the following prior projects:
185189

186-
- Query complexity analysis in the [Sangria GraphQL](http://sangria-graphql.org/) implementation.
187-
- [graphql-cost-analysis](https://github.com/pa-bru/graphql-cost-analysis) - Multipliers and directiveEstimator
190+
- Query complexity analysis in the [Sangria GraphQL](http://sangria-graphql.org/) implementation.
191+
- [graphql-cost-analysis](https://github.com/pa-bru/graphql-cost-analysis) - Multipliers and directiveEstimator

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
"name": "graphql-query-complexity",
33
"version": "0.8.1",
44
"description": "Validation rule for GraphQL query complexity analysis",
5-
"main": "dist/index.js",
6-
"types": "dist/index.d.ts",
5+
"main": "dist/cjs/index.js",
6+
"types": "dist/cjs/index.d.ts",
7+
"module": "dist/esm/index.js",
78
"scripts": {
89
"lint": "eslint --ext .ts . && prettier --config .prettierrc 'src/**/*.ts' --check",
910
"lint:fix": "eslint --ext .ts . --fix && prettier --config .prettierrc 'src/**/*.ts' --write",
1011
"clean": "rimraf dist/*",
11-
"build": "tsc",
12+
"build": "npm run build:esm && npm run build:cjs",
13+
"build:esm": "tsc -p ./tsconfig.esm.json",
14+
"build:cjs": "tsc -p ./tsconfig.json",
1215
"test": "npm run lint && npm run testonly",
1316
"testonly": "mocha --check-leaks --exit --full-trace --require ts-node/register/transpile-only 'src/**/__tests__/**/*-test.{ts,tsx}'",
1417
"dist": "npm run clean && tsc && npm run build",

0 commit comments

Comments
 (0)