Skip to content

Commit 0d437ac

Browse files
committed
initial commit
0 parents  commit 0d437ac

15 files changed

+10653
-0
lines changed

.babelrc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"presets": [
3+
[
4+
"env",
5+
{
6+
"targets": {
7+
"node": "8.10"
8+
}
9+
}
10+
]
11+
],
12+
"plugins": ["transform-object-rest-spread"]
13+
}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lib/
2+
node_modules/

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Aws Apollo Tools
2+
3+
[![Node version](https://img.shields.io/badge/nodejs-8.10.0-blue.svg)](https://nodejs.org/en/blog/release/v8.10.0/)
4+
5+
6+
## Table of Contents
7+
8+
* [Prerequisites](#prerequisites)
9+
* [Getting Started](#getting-started)
10+
* [Usage](#usage)
11+
* [LambdaRequest](#lambdarequest)
12+
* [HttpRequest](#httprequest)
13+
14+
15+
16+
## Prerequisites
17+
18+
in `serverless.yml`
19+
```yml
20+
...
21+
provider:
22+
...
23+
environment:
24+
SLS_STAGE: ${self:provider.stage}
25+
iamRoleStatements:
26+
- Effect: Allow
27+
Action:
28+
- execute-api:*
29+
Resource: '*'
30+
...
31+
```
32+
33+
## Getting Started
34+
35+
* Run `yarn add @nutshelllab/aws-apollo-tools`
36+
* `import * from '@nutshelllab/aws-apollo-tools'`
37+
38+
## Usage
39+
40+
### LambdaRequest
41+
42+
`import graphqlLambdaRequest from '@nutshelllab/aws-apollo-tools/lambda-request'`
43+
44+
```js
45+
const request = gql`
46+
query getItem($id: ID!) {
47+
getItem(id: $id) {
48+
id
49+
}
50+
}
51+
`
52+
53+
const variables = {
54+
id: '110e8400-e29b-11d4-a716-446655440000'
55+
}
56+
57+
const test = await graphqlLambdaRequest({
58+
lambdaName: 'my-lambda-name',
59+
region: 'eu-west-1',
60+
request,
61+
variables
62+
})
63+
64+
```
65+
66+
#### Options
67+
68+
|name|required|type|info|
69+
|---|---|---|---|---|
70+
|lambdaName|true|string|The lambda endpoint must provide an apollo server|
71+
|region|true|string| |
72+
|request|true|string|It must be a GraphQL query [graphql-tag](https://github.com/apollographql/graphql-tag#readme)|
73+
|variables|false|object| |
74+
|headers|false|object| |
75+
76+
### HttpRequest
77+
78+
`import graphqlHttpRequest from '@nutshelllab/aws-apollo-tools/http-request'`
79+
80+
```js
81+
const request = gql`
82+
query getItem($id: ID!) {
83+
getItem(id: $id) {
84+
id
85+
}
86+
}
87+
`
88+
89+
const variables = {
90+
id: '110e8400-e29b-11d4-a716-446655440000'
91+
}
92+
93+
const test = await graphqlHttpRequest({
94+
uri: 'https://my-apollo-server-endpoint.com',
95+
region: 'eu-west-1',
96+
request,
97+
variables,
98+
signed: true
99+
})
100+
101+
```
102+
103+
#### Options
104+
105+
|name|required|type|info|
106+
|---|---|---|---|---|
107+
|uri|true|string|The http endpoint must provide an apollo server|
108+
|region|true|string| |
109+
|request|true|string|It must be a GraphQL query [graphql-tag](https://github.com/apollographql/graphql-tag#readme)|
110+
|signed|false|bool|Setting to `true` enable aws signature v4, be sure that your http endpoint as `authorizer: aws_iam`|
111+
|variables|false|object| |
112+
|headers|false|object| |

package.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "@nutshelllab/aws-appolo-tools",
3+
"version": "0.0.1",
4+
"description": "Initialize graphQl Client and Sign request for IAM authentication",
5+
"main": "lib/aws-appolo-tools.js",
6+
"scripts": {
7+
"build": "webpack --config webpack.config.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/nutshelllab/aws-appolo-tools.git"
12+
},
13+
"keywords": [
14+
"graphql",
15+
"sign",
16+
"aws"
17+
],
18+
"author": "Nutshell",
19+
"license": "GNU GENERAL PUBLIC LICENSE Version 3",
20+
"bugs": {
21+
"url": "https://github.com/nutshelllab/aws-appolo-tools/issues"
22+
},
23+
"homepage": "https://github.com/nutshelllab/aws-appolo-tools#readme",
24+
"dependencies": {
25+
"apollo-cache-inmemory": "^1.3.11",
26+
"apollo-client": "^2.4.7",
27+
"apollo-link": "^1.2.4",
28+
"apollo-link-http": "^1.5.7",
29+
"aws-sdk": "^2.363.0",
30+
"aws4": "^1.8.0",
31+
"graphql": "^14.0.2",
32+
"node-fetch": "^2.3.0",
33+
"url": "^0.11.0"
34+
},
35+
"devDependencies": {
36+
"babel-loader": "^7.1.4",
37+
"babel-plugin-transform-object-rest-spread": "^6.26.0",
38+
"babel-polyfill": "^6.26.0",
39+
"babel-preset-env": "^1.7.0",
40+
"webpack": "^4.8.2",
41+
"webpack-cli": "^2.1.3",
42+
"webpack-node-externals": "^1.7.2"
43+
}
44+
}

src/aws4-signer.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import urlNode from 'url'
2+
import aws4 from 'aws4'
3+
import fetch from 'node-fetch'
4+
import AWS from 'aws-sdk'
5+
6+
const sign = ({ method, url, headers: { region, ...headers }, body }) => {
7+
const { path, host } = urlNode.parse(url)
8+
return aws4.sign(
9+
{
10+
body,
11+
headers,
12+
method,
13+
url,
14+
service: 'execute-api',
15+
path,
16+
host,
17+
region
18+
},
19+
{
20+
accessKeyId: AWS.config.credentials.accessKeyId,
21+
secretAccessKey: AWS.config.credentials.secretAccessKey,
22+
sessionToken: AWS.config.credentials.sessionToken
23+
}
24+
)
25+
}
26+
27+
export default async (url, options) => {
28+
const { method, headers, body } = options
29+
const signedRequest = await sign({ method, url, headers, body })
30+
return fetch(signedRequest.url, signedRequest)
31+
}

src/core/graphql-request.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { InMemoryCache } from 'apollo-cache-inmemory'
2+
import ApolloClient from 'apollo-client'
3+
4+
const cache = new InMemoryCache()
5+
6+
const operate = (graphqlClient, operation) => (request, variables) =>
7+
operation === 'query'
8+
? query(graphqlClient, request, variables)
9+
: mutate(graphqlClient, request, variables)
10+
const query = (graphqlClient, request, variables) =>
11+
graphqlClient.query({
12+
query: request,
13+
variables,
14+
fetchPolicy: 'network-only'
15+
})
16+
const mutate = (graphqlClient, request, variables) =>
17+
graphqlClient.mutate({
18+
mutation: request,
19+
variables,
20+
fetchPolicy: 'no-cache'
21+
})
22+
23+
export const graphqlRequest = async ({
24+
name,
25+
link,
26+
request,
27+
variables = {}
28+
}) => {
29+
const graphqlClient = new ApolloClient({
30+
link,
31+
cache
32+
})
33+
if (!request.definitions)
34+
throw new Error(
35+
`[Apollo Tools] - GraphQL request does not contain any operation`
36+
)
37+
const { operation = 'query' } = request.definitions[0] || {}
38+
const { data } = await operate(graphqlClient, operation)(
39+
request,
40+
variables
41+
).catch(error => {
42+
throw new Error(`(from ${name}) - ${error.message}`)
43+
})
44+
const key = Object.keys(data)[0]
45+
return data[key]
46+
}

src/format-error.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default options => error => {
2+
console.log(JSON.stringify(error))
3+
if (options.noExtensions) delete error.extensions
4+
return error
5+
}

src/http-request.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { createHttpLink } from 'apollo-link-http'
2+
import fetch from 'node-fetch'
3+
import hmacfetch from './aws4-signer'
4+
import { graphqlRequest } from './core/graphql-request'
5+
6+
export default ({
7+
uri,
8+
region,
9+
request,
10+
signed = true,
11+
variables,
12+
headers = {}
13+
}) => {
14+
const link = createHttpLink({
15+
uri,
16+
headers: {
17+
...headers,
18+
region
19+
},
20+
fetch: signed ? hmacfetch : fetch
21+
})
22+
return graphqlRequest({ name: uri, link, request, variables })
23+
}

src/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export { default as graphqlHttpRequest } from './http-request'
2+
export { default as graphqlLambdaRequest } from './lambda-request'
3+
export { default as createLambdaLink } from './lambda-link'
4+
export { default as hmacfetch } from './aws4-signer'
5+
export { default as formatError } from './format-error'

0 commit comments

Comments
 (0)