netlify-cli 16.7.0 → 16.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +10 -0
  2. package/npm-shrinkwrap.json +16123 -10639
  3. package/package.json +6 -4
  4. package/src/commands/build/build.mjs +4 -2
  5. package/src/commands/deploy/deploy.mjs +11 -3
  6. package/src/commands/integration/deploy.mjs +397 -0
  7. package/src/commands/integration/index.mjs +25 -0
  8. package/src/commands/main.mjs +2 -0
  9. package/src/lib/build.mjs +3 -1
  10. package/src/lib/edge-functions/consts.mjs +1 -0
  11. package/src/lib/edge-functions/proxy.mjs +1 -2
  12. package/src/lib/edge-functions/registry.mjs +15 -19
  13. package/src/lib/functions/registry.mjs +31 -4
  14. package/src/lib/functions/server.mjs +15 -0
  15. package/src/functions-templates/javascript/apollo-graphql/.netlify-function-template.mjs +0 -5
  16. package/src/functions-templates/javascript/apollo-graphql/package.json +0 -21
  17. package/src/functions-templates/javascript/apollo-graphql/{{name}}.js +0 -42
  18. package/src/functions-templates/javascript/apollo-graphql-rest/.netlify-function-template.mjs +0 -5
  19. package/src/functions-templates/javascript/apollo-graphql-rest/package.json +0 -22
  20. package/src/functions-templates/javascript/apollo-graphql-rest/random-user.js +0 -23
  21. package/src/functions-templates/javascript/apollo-graphql-rest/{{name}}.js +0 -68
  22. package/src/functions-templates/javascript/auth-fetch/.netlify-function-template.mjs +0 -11
  23. package/src/functions-templates/javascript/auth-fetch/package-lock.json +0 -83
  24. package/src/functions-templates/javascript/auth-fetch/package.json +0 -21
  25. package/src/functions-templates/javascript/auth-fetch/{{name}}.js +0 -39
  26. package/src/functions-templates/javascript/create-user/.netlify-function-template.mjs +0 -11
  27. package/src/functions-templates/javascript/create-user/package.json +0 -21
  28. package/src/functions-templates/javascript/create-user/{{name}}.js +0 -36
  29. package/src/functions-templates/javascript/fauna-crud/.netlify-function-template.mjs +0 -17
  30. package/src/functions-templates/javascript/fauna-crud/create-schema.js +0 -36
  31. package/src/functions-templates/javascript/fauna-crud/create.js +0 -37
  32. package/src/functions-templates/javascript/fauna-crud/delete.js +0 -29
  33. package/src/functions-templates/javascript/fauna-crud/package.json +0 -20
  34. package/src/functions-templates/javascript/fauna-crud/read-all.js +0 -33
  35. package/src/functions-templates/javascript/fauna-crud/read.js +0 -30
  36. package/src/functions-templates/javascript/fauna-crud/update.js +0 -30
  37. package/src/functions-templates/javascript/fauna-crud/{{name}}.js +0 -62
  38. package/src/functions-templates/javascript/fauna-graphql/.netlify-function-template.mjs +0 -17
  39. package/src/functions-templates/javascript/fauna-graphql/package.json +0 -26
  40. package/src/functions-templates/javascript/fauna-graphql/schema.graphql +0 -8
  41. package/src/functions-templates/javascript/fauna-graphql/sync-schema.js +0 -38
  42. package/src/functions-templates/javascript/fauna-graphql/{{name}}.js +0 -46
  43. package/src/functions-templates/javascript/google-analytics/.netlify-function-template.mjs +0 -5
  44. package/src/functions-templates/javascript/google-analytics/package-lock.json +0 -100
  45. package/src/functions-templates/javascript/google-analytics/package.json +0 -25
  46. package/src/functions-templates/javascript/google-analytics/{{name}}.js +0 -114
  47. package/src/functions-templates/javascript/graphql-gateway/.netlify-function-template.mjs +0 -5
  48. package/src/functions-templates/javascript/graphql-gateway/example-sibling-function-graphql-1.js +0 -42
  49. package/src/functions-templates/javascript/graphql-gateway/example-sibling-function-graphql-2.js +0 -80
  50. package/src/functions-templates/javascript/graphql-gateway/package.json +0 -24
  51. package/src/functions-templates/javascript/graphql-gateway/{{name}}.js +0 -75
  52. package/src/functions-templates/javascript/hasura-event-triggered/.netlify-function-template.mjs +0 -5
  53. package/src/functions-templates/javascript/hasura-event-triggered/package.json +0 -21
  54. package/src/functions-templates/javascript/hasura-event-triggered/{{name}}.js +0 -40
  55. package/src/functions-templates/javascript/node-fetch/.netlify-function-template.mjs +0 -5
  56. package/src/functions-templates/javascript/node-fetch/package.json +0 -19
  57. package/src/functions-templates/javascript/node-fetch/{{name}}.js +0 -29
  58. package/src/functions-templates/javascript/oauth-passport/.netlify-function-template.mjs +0 -5
  59. package/src/functions-templates/javascript/oauth-passport/package.json +0 -25
  60. package/src/functions-templates/javascript/oauth-passport/utils/auth.js +0 -65
  61. package/src/functions-templates/javascript/oauth-passport/utils/config.js +0 -24
  62. package/src/functions-templates/javascript/oauth-passport/{{name}}.js +0 -37
  63. package/src/functions-templates/javascript/protected-function/.netlify-function-template.mjs +0 -5
  64. package/src/functions-templates/javascript/protected-function/{{name}}.js +0 -25
  65. package/src/functions-templates/javascript/send-email/.netlify-function-template.mjs +0 -5
  66. package/src/functions-templates/javascript/send-email/package.json +0 -21
  67. package/src/functions-templates/javascript/send-email/validations.js +0 -38
  68. package/src/functions-templates/javascript/send-email/{{name}}.js +0 -68
  69. package/src/functions-templates/javascript/serverless-ssr/.netlify-function-template.mjs +0 -5
  70. package/src/functions-templates/javascript/serverless-ssr/app/index.js +0 -116
  71. package/src/functions-templates/javascript/serverless-ssr/package.json +0 -24
  72. package/src/functions-templates/javascript/serverless-ssr/serverless-http.js +0 -15
  73. package/src/functions-templates/javascript/serverless-ssr/{{name}}.js +0 -15
  74. package/src/functions-templates/javascript/set-cookie/.netlify-function-template.mjs +0 -5
  75. package/src/functions-templates/javascript/set-cookie/package.json +0 -19
  76. package/src/functions-templates/javascript/set-cookie/{{name}}.js +0 -44
  77. package/src/functions-templates/javascript/slack-rate-limit/.netlify-function-template.mjs +0 -5
  78. package/src/functions-templates/javascript/slack-rate-limit/package.json +0 -20
  79. package/src/functions-templates/javascript/slack-rate-limit/{{name}}.js +0 -115
  80. package/src/functions-templates/javascript/stripe-charge/.netlify-function-template.mjs +0 -28
  81. package/src/functions-templates/javascript/stripe-charge/package-lock.json +0 -196
  82. package/src/functions-templates/javascript/stripe-charge/package.json +0 -21
  83. package/src/functions-templates/javascript/stripe-charge/{{name}}.js +0 -56
  84. package/src/functions-templates/javascript/stripe-subscription/.netlify-function-template.mjs +0 -28
  85. package/src/functions-templates/javascript/stripe-subscription/package-lock.json +0 -196
  86. package/src/functions-templates/javascript/stripe-subscription/package.json +0 -21
  87. package/src/functions-templates/javascript/stripe-subscription/{{name}}.js +0 -52
  88. package/src/functions-templates/javascript/token-hider/.netlify-function-template.mjs +0 -29
  89. package/src/functions-templates/javascript/token-hider/package-lock.json +0 -317
  90. package/src/functions-templates/javascript/token-hider/package.json +0 -21
  91. package/src/functions-templates/javascript/token-hider/{{name}}.js +0 -37
  92. package/src/functions-templates/javascript/url-shortener/.netlify-function-template.mjs +0 -29
  93. package/src/functions-templates/javascript/url-shortener/generate-route.js +0 -53
  94. package/src/functions-templates/javascript/url-shortener/get-route.js +0 -32
  95. package/src/functions-templates/javascript/url-shortener/package-lock.json +0 -126
  96. package/src/functions-templates/javascript/url-shortener/package.json +0 -22
  97. package/src/functions-templates/javascript/url-shortener/{{name}}.js +0 -30
  98. package/src/functions-templates/javascript/using-middleware/.netlify-function-template.mjs +0 -5
  99. package/src/functions-templates/javascript/using-middleware/package.json +0 -19
  100. package/src/functions-templates/javascript/using-middleware/{{name}}.js +0 -60
@@ -1,33 +0,0 @@
1
- /* Import faunaDB sdk */
2
- const process = require('process')
3
-
4
- const { Client, query } = require('faunadb')
5
-
6
- const client = new Client({
7
- secret: process.env.FAUNADB_SERVER_SECRET,
8
- })
9
-
10
- const handler = async () => {
11
- console.log('Function `read-all` invoked')
12
-
13
- try {
14
- const response = await client.query(query.Paginate(query.Match(query.Index('all_items'))))
15
- const itemRefs = response.data
16
- // create new query out of item refs. http://bit.ly/2LG3MLg
17
- const getAllItemsDataQuery = itemRefs.map((ref) => query.Get(ref))
18
- // then query the refs
19
- const ret = await client.query(getAllItemsDataQuery)
20
- return {
21
- statusCode: 200,
22
- body: JSON.stringify(ret),
23
- }
24
- } catch (error) {
25
- console.log('error', error)
26
- return {
27
- statusCode: 400,
28
- body: JSON.stringify(error),
29
- }
30
- }
31
- }
32
-
33
- module.exports = { handler }
@@ -1,30 +0,0 @@
1
- /* Import faunaDB sdk */
2
- const process = require('process')
3
-
4
- const { Client, query } = require('faunadb')
5
-
6
- const client = new Client({
7
- secret: process.env.FAUNADB_SERVER_SECRET,
8
- })
9
-
10
- const handler = async (event) => {
11
- const { id } = event
12
- console.log(`Function 'read' invoked. Read id: ${id}`)
13
-
14
- try {
15
- const response = await client.query(query.Get(query.Ref(query.Collection('items'), id)))
16
- console.log('success', response)
17
- return {
18
- statusCode: 200,
19
- body: JSON.stringify(response),
20
- }
21
- } catch (error) {
22
- console.log('error', error)
23
- return {
24
- statusCode: 400,
25
- body: JSON.stringify(error),
26
- }
27
- }
28
- }
29
-
30
- module.exports = { handler }
@@ -1,30 +0,0 @@
1
- /* Import faunaDB sdk */
2
- const process = require('process')
3
-
4
- const { Client, query } = require('faunadb')
5
-
6
- const client = new Client({
7
- secret: process.env.FAUNADB_SERVER_SECRET,
8
- })
9
-
10
- const handler = async (event) => {
11
- const data = JSON.parse(event.body)
12
- const { id } = event
13
- console.log(`Function 'update' invoked. update id: ${id}`)
14
- try {
15
- const response = await client.query(query.Update(query.Ref(query.Collection('items'), id), { data }))
16
- console.log('success', response)
17
- return {
18
- statusCode: 200,
19
- body: JSON.stringify(response),
20
- }
21
- } catch (error) {
22
- console.log('error', error)
23
- return {
24
- statusCode: 400,
25
- body: JSON.stringify(error),
26
- }
27
- }
28
- }
29
-
30
- module.exports = { handler }
@@ -1,62 +0,0 @@
1
- const createRoute = require('./create.js')
2
- const deleteRoute = require('./delete.js')
3
- const readAllRoute = require('./read-all.js')
4
- const readRoute = require('./read.js')
5
- const updateRoute = require('./update.js')
6
-
7
- const handler = async (event, context) => {
8
- const path = event.path.replace(/\.netlify\/functions\/[^/]+/, '')
9
- const segments = path.split('/').filter(Boolean)
10
-
11
- switch (event.httpMethod) {
12
- case 'GET':
13
- // e.g. GET /.netlify/functions/fauna-crud
14
- if (segments.length === 0) {
15
- return readAllRoute.handler(event, context)
16
- }
17
- // e.g. GET /.netlify/functions/fauna-crud/123456
18
- if (segments.length === 1) {
19
- const [id] = segments
20
- event.id = id
21
- return readRoute.handler(event, context)
22
- }
23
- return {
24
- statusCode: 500,
25
- body: 'too many segments in GET request, must be either /.netlify/functions/fauna-crud or /.netlify/functions/fauna-crud/123456',
26
- }
27
-
28
- case 'POST':
29
- // e.g. POST /.netlify/functions/fauna-crud with a body of key value pair objects, NOT strings
30
- return createRoute.handler(event, context)
31
- case 'PUT':
32
- // e.g. PUT /.netlify/functions/fauna-crud/123456 with a body of key value pair objects, NOT strings
33
- if (segments.length === 1) {
34
- const [id] = segments
35
- event.id = id
36
- return updateRoute.handler(event, context)
37
- }
38
- return {
39
- statusCode: 500,
40
- body: 'invalid segments in POST request, must be /.netlify/functions/fauna-crud/123456',
41
- }
42
-
43
- case 'DELETE':
44
- // e.g. DELETE /.netlify/functions/fauna-crud/123456
45
- if (segments.length === 1) {
46
- const [id] = segments
47
- event.id = id
48
- return deleteRoute.handler(event, context)
49
- }
50
- return {
51
- statusCode: 500,
52
- body: 'invalid segments in DELETE request, must be /.netlify/functions/fauna-crud/123456',
53
- }
54
- default:
55
- return {
56
- statusCode: 500,
57
- body: 'unrecognized HTTP Method, must be one of GET/POST/PUT/DELETE',
58
- }
59
- }
60
- }
61
-
62
- module.exports = { handler }
@@ -1,17 +0,0 @@
1
- import execa from 'execa'
2
-
3
- export default {
4
- name: 'fauna-graphql',
5
- description: 'GraphQL Backend using Fauna DB',
6
- functionType: 'serverless',
7
- addons: [
8
- {
9
- addonName: 'fauna',
10
- addonDidInstall(fnPath) {
11
- execa.sync(fnPath + '/sync-schema.js', undefined, {
12
- stdio: 'inherit',
13
- })
14
- },
15
- },
16
- ],
17
- }
@@ -1,26 +0,0 @@
1
- {
2
- "name": "fauna-graphql",
3
- "version": "1.0.0",
4
- "description": "netlify functions:create - set up for fauna db + apollo graphql",
5
- "main": "fauna-graphql.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [
10
- "netlify",
11
- "serverless",
12
- "js",
13
- "apollo",
14
- "fauna"
15
- ],
16
- "author": "Netlify",
17
- "license": "MIT",
18
- "dependencies": {
19
- "apollo-link-http": "^1.5.17",
20
- "apollo-link-context": "^1.0.20",
21
- "apollo-server-lambda": "^2.18.2",
22
- "graphql": "^14.1.1",
23
- "graphql-tools": "^4.0.8",
24
- "node-fetch": "^2.6.1"
25
- }
26
- }
@@ -1,8 +0,0 @@
1
- type Todo {
2
- title: String!
3
- completed: Boolean!
4
- }
5
- type Query {
6
- allTodos: [Todo!]
7
- todosByCompletedFlag(completed: Boolean!): [Todo!]
8
- }
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env node
2
- const { Buffer } = require('buffer')
3
- const fs = require('fs')
4
- const path = require('path')
5
- const process = require('process')
6
-
7
- const fetch = require('node-fetch')
8
-
9
- /* sync GraphQL schema to your FaunaDB account - use with `netlify dev:exec <path-to-this-file>` */
10
- const createFaunaGraphQL = async function () {
11
- if (!process.env.FAUNADB_SERVER_SECRET) {
12
- console.log('No FAUNADB_SERVER_SECRET in environment, skipping DB setup')
13
- }
14
- console.log('Upload GraphQL Schema!')
15
-
16
- // name of your schema file
17
- const dataString = fs.readFileSync(path.join(__dirname, 'schema.graphql')).toString()
18
-
19
- // encoded authorization header similar to https://www.npmjs.com/package/request#http-authentication
20
- const token = Buffer.from(`${process.env.FAUNADB_SERVER_SECRET}:`).toString('base64')
21
-
22
- const options = {
23
- method: 'POST',
24
- body: dataString,
25
- headers: { Authorization: `Basic ${token}` },
26
- }
27
-
28
- try {
29
- const res = await fetch('https://graphql.fauna.com/import', options)
30
- const body = await res.text()
31
- console.log('Netlify Functions:Create - `fauna-graphql/sync-schema.js` success!')
32
- console.log(body)
33
- } catch (error) {
34
- console.error('something wrong happened:', { err: error })
35
- }
36
- }
37
-
38
- createFaunaGraphQL()
@@ -1,46 +0,0 @@
1
- const { Buffer } = require('buffer')
2
- const process = require('process')
3
-
4
- const { createHttpLink } = require('apollo-link-http')
5
- const { ApolloServer } = require('apollo-server-lambda')
6
- const { introspectSchema, makeRemoteExecutableSchema } = require('graphql-tools')
7
- const fetch = require('node-fetch')
8
-
9
- const handler = async function (event, context) {
10
- /** required for Fauna GraphQL auth */
11
- if (!process.env.FAUNADB_SERVER_SECRET) {
12
- const msg = `
13
- FAUNADB_SERVER_SECRET missing.
14
- Did you forget to install the fauna addon or forgot to run inside Netlify Dev?
15
- `
16
- console.error(msg)
17
- return {
18
- statusCode: 500,
19
- body: JSON.stringify({ msg }),
20
- }
21
- }
22
- const b64encodedSecret = Buffer.from(`${process.env.FAUNADB_SERVER_SECRET}:`).toString('base64')
23
- const headers = { Authorization: `Basic ${b64encodedSecret}` }
24
-
25
- /** standard creation of apollo-server executable schema */
26
- const link = createHttpLink({
27
- // modify as you see fit
28
- uri: 'https://graphql.fauna.com/graphql',
29
- fetch,
30
- headers,
31
- })
32
- const schema = await introspectSchema(link)
33
- const executableSchema = makeRemoteExecutableSchema({
34
- schema,
35
- link,
36
- })
37
- const server = new ApolloServer({
38
- schema: executableSchema,
39
- })
40
- return new Promise((resolve, reject) => {
41
- const cb = (err, args) => (err ? reject(err) : resolve(args))
42
- server.createHandler()(event, context, cb)
43
- })
44
- }
45
-
46
- module.exports = { handler }
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'google-analytics',
3
- description: 'Google Analytics: proxy for GA on your domain to avoid adblock',
4
- functionType: 'serverless',
5
- }
@@ -1,100 +0,0 @@
1
- {
2
- "name": "google-analytics",
3
- "version": "1.0.0",
4
- "lockfileVersion": 2,
5
- "requires": true,
6
- "packages": {
7
- "": {
8
- "name": "google-analytics",
9
- "version": "1.0.0",
10
- "license": "MIT",
11
- "dependencies": {
12
- "node-fetch": "^2.6.1",
13
- "uuid": "^9.0.0"
14
- },
15
- "engines": {
16
- "node": "^14.18.0 || >=16.0.0"
17
- }
18
- },
19
- "node_modules/node-fetch": {
20
- "version": "2.6.12",
21
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
22
- "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
23
- "dependencies": {
24
- "whatwg-url": "^5.0.0"
25
- },
26
- "engines": {
27
- "node": "4.x || >=6.0.0"
28
- },
29
- "peerDependencies": {
30
- "encoding": "^0.1.0"
31
- },
32
- "peerDependenciesMeta": {
33
- "encoding": {
34
- "optional": true
35
- }
36
- }
37
- },
38
- "node_modules/tr46": {
39
- "version": "0.0.3",
40
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
41
- "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
42
- },
43
- "node_modules/uuid": {
44
- "version": "9.0.0",
45
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
46
- "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
47
- "bin": {
48
- "uuid": "dist/bin/uuid"
49
- }
50
- },
51
- "node_modules/webidl-conversions": {
52
- "version": "3.0.1",
53
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
54
- "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
55
- },
56
- "node_modules/whatwg-url": {
57
- "version": "5.0.0",
58
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
59
- "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
60
- "dependencies": {
61
- "tr46": "~0.0.3",
62
- "webidl-conversions": "^3.0.0"
63
- }
64
- }
65
- },
66
- "dependencies": {
67
- "node-fetch": {
68
- "version": "2.6.12",
69
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
70
- "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
71
- "requires": {
72
- "whatwg-url": "^5.0.0"
73
- }
74
- },
75
- "tr46": {
76
- "version": "0.0.3",
77
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
78
- "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
79
- },
80
- "uuid": {
81
- "version": "9.0.0",
82
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
83
- "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg=="
84
- },
85
- "webidl-conversions": {
86
- "version": "3.0.1",
87
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
88
- "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
89
- },
90
- "whatwg-url": {
91
- "version": "5.0.0",
92
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
93
- "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
94
- "requires": {
95
- "tr46": "~0.0.3",
96
- "webidl-conversions": "^3.0.0"
97
- }
98
- }
99
- }
100
- }
@@ -1,25 +0,0 @@
1
- {
2
- "name": "google-analytics",
3
- "version": "1.0.0",
4
- "description": "netlify functions:create - Google Analytics: proxy for GA on your domain to avoid adblock",
5
- "main": "google-analytics.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "engines": {
10
- "node": ">=16.16.0"
11
- },
12
- "keywords": [
13
- "netlify",
14
- "serverless",
15
- "apis",
16
- "email",
17
- "js"
18
- ],
19
- "author": "Netlify",
20
- "license": "MIT",
21
- "dependencies": {
22
- "node-fetch": "^2.6.1",
23
- "uuid": "^9.0.0"
24
- }
25
- }
@@ -1,114 +0,0 @@
1
- // with thanks to https://github.com/codeniko/simple-tracker/blob/master/examples/server-examples/aws-lambda/google-analytics.js
2
-
3
- const fetch = require('node-fetch')
4
- const { v4: uuidv4 } = require('uuid')
5
-
6
- const GA_ENDPOINT = `https://www.google-analytics.com/collect`
7
-
8
- const whitelistDomain = function (domain, addWww = true) {
9
- const prefixes = ['https://', 'http://']
10
- if (addWww) {
11
- prefixes.push('https://www.', 'http://www.')
12
- }
13
- prefixes.forEach((prefix) => {
14
- originWhitelist.push(prefix + domain)
15
- })
16
- }
17
-
18
- // Domains to whitelist. Replace with your own!
19
- // keep this empty and append domains to whitelist using whiteListDomain()
20
- const originWhitelist = []
21
- whitelistDomain('test.com')
22
- whitelistDomain('nfeld.com')
23
-
24
- const proxyToGoogleAnalytics = async function (event) {
25
- // get GA params whether GET or POST request
26
- const params = event.httpMethod.toUpperCase() === 'GET' ? event.queryStringParameters : JSON.parse(event.body)
27
- const headers = event.headers || {}
28
-
29
- // attach other GA params, required for IP address since client doesn't have access to it. UA and CID can be sent from client
30
- // ip override. Look into headers for clients IP address, as opposed to IP address of host running lambda function
31
- params.uip = headers['x-forwarded-for'] || headers['x-bb-ip'] || ''
32
- // user agent override
33
- params.ua = params.ua || headers['user-agent'] || ''
34
- // REQUIRED: use given cid, or generate a new one as last resort. Generating should be avoided because one user can show up in GA multiple times. If user refresh page `n` times, you'll get `n` pageviews logged into GA from "different" users. Client should generate a uuid and store in cookies, local storage, or generate a fingerprint. Check simple-tracker client example
35
- params.cid = params.cid || uuidv4()
36
-
37
- console.info('proxying params:', params)
38
- const qs = new URLSearchParams(params).toString()
39
-
40
- try {
41
- const { ok, status, statusText } = await fetch(GA_ENDPOINT, {
42
- method: 'POST',
43
- headers: { 'Content-Type': 'image/gif' },
44
- body: qs,
45
- })
46
- if (!ok) {
47
- throw new Error(`HTTP error ${status}`)
48
- }
49
- console.info('googleanalytics status code', status, statusText)
50
- } catch (error) {
51
- console.info('googleanalytics error!', error)
52
- }
53
- }
54
-
55
- const handler = async function (event) {
56
- const origin = event.headers.origin || event.headers.Origin || ''
57
- const httpMethod = event.httpMethod.toUpperCase()
58
-
59
- console.log(`Received ${httpMethod} request from, origin: ${origin}`)
60
-
61
- const isOriginWhitelisted = originWhitelist.includes(origin)
62
- console.info('is whitelisted?', isOriginWhitelisted)
63
-
64
- const headers = {
65
- // 'Access-Control-Allow-Origin': '*', // allow all domains to POST. Use for localhost development only
66
- 'Access-Control-Allow-Origin': isOriginWhitelisted ? origin : originWhitelist[0],
67
- 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
68
- 'Access-Control-Allow-Headers': 'Content-Type,Accept',
69
- }
70
-
71
- // CORS (required if you use a different subdomain to host this function, or a different domain entirely)
72
- if (httpMethod === 'OPTIONS') {
73
- return { statusCode: 200, headers, body: '' }
74
- }
75
-
76
- // allow GET or POST, but only for whitelisted domains
77
- if ((httpMethod === 'GET' || httpMethod === 'POST') && isOriginWhitelisted) {
78
- await proxyToGoogleAnalytics(event)
79
- return { statusCode: 200, headers, body: '' }
80
- }
81
-
82
- return { statusCode: 404, headers, body: 'Not found' }
83
- }
84
-
85
- module.exports = { handler }
86
-
87
- //
88
- // Docs on GA endpoint and example params
89
- //
90
- // https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
91
- //
92
- // v: 1
93
- // _v: j67
94
- // a: 751874410
95
- // t: pageview
96
- // _s: 1
97
- // dl: https://nfeld.com/contact.html
98
- // dr: https://google.com
99
- // ul: en-us
100
- // de: UTF-8
101
- // dt: Nikolay Feldman - Software Engineer
102
- // sd: 24-bit
103
- // sr: 1440x900
104
- // vp: 945x777
105
- // je: 0
106
- // _u: blabla~
107
- // jid:
108
- // gjid:
109
- // cid: 1837873423.1522911810
110
- // tid: UA-116530991-1
111
- // _gid: 1828045325.1524815793
112
- // gtm: u4d
113
- // z: 1379041260
114
- //
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'graphql-gateway',
3
- description: 'Apollo Server Lambda Gateway stitching schemas from other GraphQL Functions!',
4
- functionType: 'serverless',
5
- }
@@ -1,42 +0,0 @@
1
- // not meant to be run inside the graqhql-gateway function
2
- // but just shows a copy-pastable example sibling function
3
- // that would work with graphql-gateway
4
- const { ApolloServer, gql } = require('apollo-server-lambda')
5
-
6
- const typeDefs = gql`
7
- type Query {
8
- hello: String
9
- allAuthors: [Author!]
10
- author(id: Int!): Author
11
- authorByName(name: String!): Author
12
- }
13
- type Author {
14
- id: ID!
15
- name: String!
16
- age: Int!
17
- }
18
- `
19
-
20
- const authors = [
21
- { id: 1, name: 'Terry Pratchett', age: 67 },
22
- { id: 2, name: 'Stephen King', age: 71 },
23
- { id: 3, name: 'JK Rowling', age: 53 },
24
- ]
25
-
26
- const resolvers = {
27
- Query: {
28
- hello: () => 'Hello, world!',
29
- allAuthors: () => authors,
30
- author: () => {},
31
- authorByName: (root, args) => authors.find((author) => author.name === args.name) || 'NOTFOUND',
32
- },
33
- }
34
-
35
- const server = new ApolloServer({
36
- typeDefs,
37
- resolvers,
38
- })
39
-
40
- const handler = server.createHandler()
41
-
42
- module.exports = { handler }
@@ -1,80 +0,0 @@
1
- // not meant to be run inside the graqhql-gateway function
2
- // but just shows a copy-pastable example sibling function
3
- // that would work with graphql-gateway
4
- const { ApolloServer, gql } = require('apollo-server-lambda')
5
-
6
- const typeDefs = gql`
7
- type Query {
8
- hello: String
9
- allBooks: [Book]
10
- book(id: Int!): Book
11
- }
12
- type Book {
13
- id: ID!
14
- year: Int!
15
- title: String!
16
- authorName: String!
17
- }
18
- `
19
-
20
- const books = [
21
- {
22
- id: 1,
23
- title: "The Philosopher's Stone",
24
- year: 1997,
25
- authorName: 'JK Rowling',
26
- },
27
- {
28
- id: 2,
29
- title: 'Pet Sematary',
30
- year: 1983,
31
- authorName: 'Stephen King',
32
- },
33
- {
34
- id: 3,
35
- title: 'Going Postal',
36
- year: 2004,
37
- authorName: 'Terry Pratchett',
38
- },
39
- {
40
- id: 4,
41
- title: 'Small Gods',
42
- year: 1992,
43
- authorName: 'Terry Pratchett',
44
- },
45
- {
46
- id: 5,
47
- title: 'Night Watch',
48
- year: 2002,
49
- authorName: 'Terry Pratchett',
50
- },
51
- {
52
- id: 6,
53
- title: 'The Shining',
54
- year: 1977,
55
- authorName: 'Stephen King',
56
- },
57
- {
58
- id: 7,
59
- title: 'The Deathly Hallows',
60
- year: 2007,
61
- authorName: 'JK Rowling',
62
- },
63
- ]
64
-
65
- const resolvers = {
66
- Query: {
67
- hello: () => 'Hello, world!',
68
- allBooks: () => books,
69
- book: (root, args) => books.find((book) => book.id === args.id),
70
- },
71
- }
72
-
73
- const server = new ApolloServer({
74
- typeDefs,
75
- resolvers,
76
- })
77
-
78
- const handler = server.createHandler()
79
-
80
- module.exports = { handler }