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,24 +0,0 @@
1
- {
2
- "name": "graphql-gateway",
3
- "version": "1.0.0",
4
- "description": "netlify functions:create - Apollo Server Lambda Gateway stitching schemas from other GraphQL Functions!",
5
- "main": "graphql-gateway.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [
10
- "netlify",
11
- "serverless",
12
- "js",
13
- "apollo"
14
- ],
15
- "author": "Netlify",
16
- "license": "MIT",
17
- "dependencies": {
18
- "apollo-link-http": "^1.5.17",
19
- "apollo-server-lambda": "^2.18.2",
20
- "graphql": "^14.2.1",
21
- "graphql-tools": "^4.0.8",
22
- "node-fetch": "^2.6.1"
23
- }
24
- }
@@ -1,75 +0,0 @@
1
- /**
2
- * This code assumes you have other graphql Netlify functions
3
- * and shows you how to stitch them together in a "gateway".
4
- *
5
- * Of course, feel free to modify this gateway to suit your needs.
6
- */
7
- const process = require('process')
8
-
9
- const { createHttpLink } = require('apollo-link-http')
10
- const { ApolloServer } = require('apollo-server-lambda')
11
- const { introspectSchema, makeRemoteExecutableSchema, mergeSchemas } = require('graphql-tools')
12
- const fetch = require('node-fetch')
13
-
14
- const handler = async function (event, context) {
15
- // other Netlify functions which are graphql lambdas
16
- const schema1 = await getSchema('graphql-1')
17
- const schema2 = await getSchema('graphql-2')
18
- const schemas = [schema1, schema2]
19
-
20
- /**
21
- * resolving -between- schemas
22
- * https://www.apollographql.com/docs/graphql-tools/schema-stitching#adding-resolvers
23
- */
24
- const linkTypeDefs = `
25
- extend type Book {
26
- author: Author
27
- }
28
- `
29
- schemas.push(linkTypeDefs)
30
- const resolvers = {
31
- Book: {
32
- author: {
33
- fragment: `... on Book { authorName }`,
34
- resolve(book, args, resolveContext, info) {
35
- return info.mergeInfo.delegateToSchema({
36
- schema: schema1,
37
- operation: 'query',
38
- // reuse what's implemented in schema1
39
- fieldName: 'authorByName',
40
- args: {
41
- name: book.authorName,
42
- },
43
- context: resolveContext,
44
- info,
45
- })
46
- },
47
- },
48
- },
49
- }
50
-
51
- // more docs https://www.apollographql.com/docs/graphql-tools/schema-stitching#api
52
- const schema = mergeSchemas({
53
- schemas,
54
- resolvers,
55
- })
56
- const server = new ApolloServer({ schema })
57
- return new Promise((resolve, reject) => {
58
- const cb = (err, args) => (err ? reject(err) : resolve(args))
59
- server.createHandler()(event, context, cb)
60
- })
61
- }
62
-
63
- const getSchema = async function (endpoint) {
64
- // you can't use relative URLs within Netlify Functions so need a base URL
65
- // process.env.URL is one of many build env variables:
66
- // https://docs.netlify.com/configure-builds/environment-variables/
67
- // Netlify Dev only supports URL and DEPLOY URL for now
68
- const uri = `${process.env.URL}/.netlify/functions/${endpoint}`
69
- const link = createHttpLink({ uri, fetch })
70
- const schema = await introspectSchema(link)
71
- const executableSchema = makeRemoteExecutableSchema({ schema, link })
72
- return executableSchema
73
- }
74
-
75
- module.exports = { handler }
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'hasura-event-triggered',
3
- description: 'Hasura Cleaning: process a Hasura event and fire off a GraphQL mutation with processed text data',
4
- functionType: 'serverless',
5
- }
@@ -1,21 +0,0 @@
1
- {
2
- "name": "hasura-event-triggered",
3
- "version": "1.0.0",
4
- "description": "netlify functions:create - Serverless function to process a Hasura event and fire off a GraphQL mutation with cleaned text data",
5
- "main": "hasura-event-triggered.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [
10
- "netlify",
11
- "serverless",
12
- "js",
13
- "hasura"
14
- ],
15
- "author": "Netlify",
16
- "license": "MIT",
17
- "dependencies": {
18
- "axios": "^1.0.0",
19
- "bad-words": "^3.0.3"
20
- }
21
- }
@@ -1,40 +0,0 @@
1
- // with thanks to https://github.com/vnovick/netlify-function-example/blob/master/functions/bad-words.js
2
- const axios = require('axios')
3
- const Filter = require('bad-words')
4
-
5
- const filter = new Filter()
6
- const hgeEndpoint = 'https://live-coding-netlify.herokuapp.com'
7
-
8
- const query = `
9
- mutation verifiedp($id: uuid!, $title: String!, $content: String!) {
10
- update_posts(_set: { verified: true, content: $content, title: $title },
11
- where:{ id: { _eq: $id } }) {
12
- returning {
13
- id
14
- }
15
- }
16
- }
17
- `
18
-
19
- const handler = async (event) => {
20
- let request
21
- try {
22
- request = JSON.parse(event.body)
23
- } catch {
24
- return { statusCode: 400, body: 'c annot parse hasura event' }
25
- }
26
-
27
- const variables = {
28
- id: request.event.data.new.id,
29
- title: filter.clean(request.event.data.new.title),
30
- content: filter.clean(request.event.data.new.content),
31
- }
32
- try {
33
- await axios.post(`${hgeEndpoint}/v1alpha1/graphql`, { query, variables })
34
- return { statusCode: 200, body: 'success' }
35
- } catch (error) {
36
- return { statusCode: 500, body: error.toString() }
37
- }
38
- }
39
-
40
- module.exports = { handler }
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'node-fetch',
3
- description: 'Fetch function: uses node-fetch to hit an external API without CORS issues',
4
- functionType: 'serverless',
5
- }
@@ -1,19 +0,0 @@
1
- {
2
- "name": "node-fetch",
3
- "version": "1.0.0",
4
- "description": "netlify functions:create - default template for node fetch function",
5
- "main": "node-fetch.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [
10
- "netlify",
11
- "serverless",
12
- "js"
13
- ],
14
- "author": "Netlify",
15
- "license": "MIT",
16
- "dependencies": {
17
- "node-fetch": "^2.6.1"
18
- }
19
- }
@@ -1,29 +0,0 @@
1
- const fetch = require('node-fetch')
2
-
3
- const handler = async function () {
4
- try {
5
- const response = await fetch('https://icanhazdadjoke.com', {
6
- headers: { Accept: 'application/json' },
7
- })
8
- if (!response.ok) {
9
- // NOT res.status >= 200 && res.status < 300
10
- return { statusCode: response.status, body: response.statusText }
11
- }
12
- const data = await response.json()
13
-
14
- return {
15
- statusCode: 200,
16
- body: JSON.stringify({ msg: data.joke }),
17
- }
18
- } catch (error) {
19
- // output to netlify function log
20
- console.log(error)
21
- return {
22
- statusCode: 500,
23
- // Could be a custom message or object i.e. JSON.stringify(err)
24
- body: JSON.stringify({ msg: error.message }),
25
- }
26
- }
27
- }
28
-
29
- module.exports = { handler }
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'oauth-passport',
3
- description: 'oauth-passport: template for Oauth workflow using Passport + Express.js',
4
- functionType: 'serverless',
5
- }
@@ -1,25 +0,0 @@
1
- {
2
- "name": "oauth-passport",
3
- "version": "1.0.0",
4
- "description": "netlify functions:create - template for Oauth workflow using Passport + Express.js",
5
- "main": "oauth-passport.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [
10
- "netlify",
11
- "serverless",
12
- "js"
13
- ],
14
- "author": "Netlify",
15
- "license": "MIT",
16
- "dependencies": {
17
- "cookie-parser": "^1.4.5",
18
- "express": "^4.17.1",
19
- "jsonwebtoken": "^9.0.0",
20
- "passport": "^0.6.0",
21
- "passport-github2": "^0.1.12",
22
- "passport-jwt": "^4.0.0",
23
- "serverless-http": "^2.0.2"
24
- }
25
- }
@@ -1,65 +0,0 @@
1
- const { sign } = require('jsonwebtoken')
2
- const passport = require('passport')
3
- const { Strategy: GitHubStrategy } = require('passport-github2')
4
- const passportJwt = require('passport-jwt')
5
-
6
- const { BASE_URL, ENDPOINT, GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, SECRET } = require('./config.js')
7
-
8
- const authJwt = function (email) {
9
- return sign({ user: { email } }, SECRET)
10
- }
11
-
12
- const applyPassportStrategies = function () {
13
- passport.use(getGitHubStrategy())
14
- passport.use(getJwtStrategy())
15
- }
16
-
17
- const getGitHubStrategy = function () {
18
- return new GitHubStrategy(
19
- {
20
- clientID: GITHUB_CLIENT_ID,
21
- clientSecret: GITHUB_CLIENT_SECRET,
22
- callbackURL: `${BASE_URL}${ENDPOINT}/auth/github/callback`,
23
- scope: ['user:email'],
24
- },
25
- async (accessToken, refreshToken, profile, done) => {
26
- try {
27
- const email = profile.emails[0].value
28
- // Here you'd typically create a new or load an existing user and
29
- // store the bare necessary informations about the user in the JWT.
30
- const jwt = authJwt(email)
31
-
32
- return done(null, { email, jwt })
33
- } catch (error) {
34
- return done(error)
35
- }
36
- },
37
- )
38
- }
39
-
40
- const getJwtStrategy = function () {
41
- return new passportJwt.Strategy(
42
- {
43
- jwtFromRequest(req) {
44
- if (!req.cookies) throw new Error('Missing cookie-parser middleware')
45
- return req.cookies.jwt
46
- },
47
- secretOrKey: SECRET,
48
- },
49
- async ({ user: { email } }, done) => {
50
- try {
51
- // Here you'd typically load an existing user
52
- // and use the data to create the JWT.
53
- const jwt = authJwt(email)
54
-
55
- return done(null, { email, jwt })
56
- } catch (error) {
57
- return done(error)
58
- }
59
- },
60
- )
61
- }
62
-
63
- module.exports = {
64
- applyPassportStrategies,
65
- }
@@ -1,24 +0,0 @@
1
- // lambda/utils/config.js
2
- // Circumvent problem with Netlify CLI.
3
- // https://github.com/netlify/netlify-dev-plugin/issues/147
4
- const process = require('process')
5
-
6
- const BASE_URL = process.env.NODE_ENV === 'development' ? 'http://localhost:8888' : process.env.BASE_URL
7
-
8
- const COOKIE_SECURE = process.env.NODE_ENV !== 'development'
9
-
10
- const ENDPOINT = process.env.NODE_ENV === 'development' ? '/.netlify/functions' : '/api'
11
-
12
- const { GITHUB_CLIENT_ID } = process.env
13
- const { GITHUB_CLIENT_SECRET } = process.env
14
-
15
- const SECRET = process.env.SECRET || 'SUPERSECRET'
16
-
17
- module.exports = {
18
- BASE_URL,
19
- COOKIE_SECURE,
20
- ENDPOINT,
21
- GITHUB_CLIENT_ID,
22
- GITHUB_CLIENT_SECRET,
23
- SECRET,
24
- }
@@ -1,37 +0,0 @@
1
- // details: https://markus.oberlehner.net/blog/implementing-an-authentication-flow-with-passport-and-netlify-functions/
2
-
3
- const cookieParser = require('cookie-parser')
4
- const express = require('express')
5
- const passport = require('passport')
6
- const serverless = require('serverless-http')
7
-
8
- const { applyPassportStrategies } = require('./utils/auth.js')
9
- const { COOKIE_SECURE, ENDPOINT } = require('./utils/config.js')
10
-
11
- applyPassportStrategies()
12
-
13
- const app = express()
14
-
15
- app.use(express.urlencoded({ extended: true }))
16
- app.use(express.json())
17
- app.use(cookieParser())
18
- app.use(passport.initialize())
19
-
20
- const handleCallback = (req, res) => {
21
- res.cookie('jwt', req.user.jwt, { httpOnly: true, COOKIE_SECURE }).redirect('/')
22
- }
23
-
24
- app.get(`${ENDPOINT}/auth/github`, passport.authenticate('github', { session: false }))
25
- app.get(
26
- `${ENDPOINT}/auth/github/callback`,
27
- passport.authenticate('github', { failureRedirect: '/', session: false }),
28
- handleCallback,
29
- )
30
-
31
- app.get(`${ENDPOINT}/auth/status`, passport.authenticate('jwt', { session: false }), (req, res) =>
32
- res.json({ email: req.user.email }),
33
- )
34
-
35
- const handler = serverless(app)
36
-
37
- module.exports = { handler }
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'protected-function',
3
- description: 'Function protected Netlify Identity authentication',
4
- functionType: 'serverless',
5
- }
@@ -1,25 +0,0 @@
1
- const handler = async (event, context) => {
2
- console.log('protected function!')
3
- // Reading the context.clientContext will give us the current user
4
- const claims = context.clientContext && context.clientContext.user
5
- console.log('user claims', claims)
6
-
7
- if (!claims) {
8
- console.log('No claims! Begone!')
9
- return {
10
- statusCode: 401,
11
- body: JSON.stringify({
12
- data: 'NOT ALLOWED',
13
- }),
14
- }
15
- }
16
-
17
- return {
18
- statusCode: 200,
19
- body: JSON.stringify({
20
- data: 'auth true',
21
- }),
22
- }
23
- }
24
-
25
- module.exports = { handler }
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'send-email',
3
- description: "Send Email: Send email with no SMTP server via 'sendmail' pkg",
4
- functionType: 'serverless',
5
- }
@@ -1,21 +0,0 @@
1
- {
2
- "name": "send-email",
3
- "version": "1.0.0",
4
- "description": "netlify functions:create - Send email with no SMTP server via 'sendmail' pkg",
5
- "main": "send-email.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [
10
- "netlify",
11
- "serverless",
12
- "apis",
13
- "email",
14
- "js"
15
- ],
16
- "author": "Netlify",
17
- "license": "MIT",
18
- "dependencies": {
19
- "sendmail": "1.6.1"
20
- }
21
- }
@@ -1,38 +0,0 @@
1
- const validateEmail = (ctx, str) => {
2
- if (typeof str !== 'string' && !(str instanceof String)) {
3
- throw new TypeError(`${ctx} must be a string`)
4
- }
5
-
6
- validateLength(ctx, str, EMAIL_MIN_LENGTH, EMAIL_MAX_LENGTH)
7
-
8
- if (!/^[\w.-]+@[\w.-]+\.\w+$/.test(str)) {
9
- throw new TypeError(`${ctx} is not an email address`)
10
- }
11
- }
12
-
13
- const EMAIL_MIN_LENGTH = 5
14
- const EMAIL_MAX_LENGTH = 30
15
-
16
- const validateLength = (ctx, str, min, max) => {
17
- if (max === undefined) {
18
- max = min
19
- min = 0
20
- }
21
-
22
- if (typeof str !== 'string' && !(str instanceof String)) {
23
- throw new TypeError(`${ctx} must be a string`)
24
- }
25
-
26
- if (str.length < min) {
27
- throw new TypeError(`${ctx} must be at least ${min} chars long`)
28
- }
29
-
30
- if (str.length > max) {
31
- throw new TypeError(`${ctx} must contain ${max} chars at most`)
32
- }
33
- }
34
-
35
- module.exports = {
36
- validateEmail,
37
- validateLength,
38
- }
@@ -1,68 +0,0 @@
1
- // with thanks to https://github.com/Urigo/graphql-modules/blob/8cb2fd7d9938a856f83e4eee2081384533771904/website/lambda/contact.js
2
- const process = require('process')
3
- const { promisify } = require('util')
4
-
5
- const sendMailLib = require('sendmail')
6
-
7
- const { validateEmail, validateLength } = require('./validations.js')
8
-
9
- const sendMail = promisify(sendMailLib())
10
-
11
- const NAME_MIN_LENGTH = 3
12
- const NAME_MAX_LENGTH = 50
13
- const DETAILS_MIN_LENGTH = 10
14
- const DETAILS_MAX_LENGTH = 1e3
15
-
16
- const handler = async (event) => {
17
- if (!process.env.CONTACT_EMAIL) {
18
- return {
19
- statusCode: 500,
20
- body: 'process.env.CONTACT_EMAIL must be defined',
21
- }
22
- }
23
-
24
- const body = JSON.parse(event.body)
25
-
26
- try {
27
- validateLength('body.name', body.name, NAME_MIN_LENGTH, NAME_MAX_LENGTH)
28
- } catch (error) {
29
- return {
30
- statusCode: 403,
31
- body: error.message,
32
- }
33
- }
34
-
35
- try {
36
- validateEmail('body.email', body.email)
37
- } catch (error) {
38
- return {
39
- statusCode: 403,
40
- body: error.message,
41
- }
42
- }
43
-
44
- try {
45
- validateLength('body.details', body.details, DETAILS_MIN_LENGTH, DETAILS_MAX_LENGTH)
46
- } catch (error) {
47
- return {
48
- statusCode: 403,
49
- body: error.message,
50
- }
51
- }
52
-
53
- const descriptor = {
54
- from: `"${body.email}" <no-reply@gql-modules.com>`,
55
- to: process.env.CONTACT_EMAIL,
56
- subject: `${body.name} sent you a message from gql-modules.com`,
57
- text: body.details,
58
- }
59
-
60
- try {
61
- await sendMail(descriptor)
62
- return { statusCode: 200, body: '' }
63
- } catch (error) {
64
- return { statusCode: 500, body: error.message }
65
- }
66
- }
67
-
68
- module.exports = { handler }
@@ -1,5 +0,0 @@
1
- export default {
2
- name: 'serverless-ssr',
3
- description: 'Dynamic serverside rendering via functions',
4
- functionType: 'serverless',
5
- }
@@ -1,116 +0,0 @@
1
- /* Express App */
2
- const process = require('process')
3
-
4
- const compression = require('compression')
5
- const cors = require('cors')
6
- const express = require('express')
7
- const morgan = require('morgan')
8
-
9
- /* My express App */
10
- module.exports = function expressApp(functionName) {
11
- const app = express()
12
- const router = express.Router()
13
-
14
- // gzip responses
15
- router.use(compression())
16
-
17
- // Set router base path for local dev
18
- const routerBasePath = process.env.NODE_ENV === 'dev' ? `/${functionName}` : `/.netlify/functions/${functionName}/`
19
-
20
- /* define routes */
21
- router.get('/', function onRequest(req, res) {
22
- const html = `
23
- <html>
24
- <head>
25
- <style>
26
- body {
27
- padding: 30px;
28
- }
29
- </style>
30
- </head>
31
- <body>
32
- <h1>Express via '${functionName}' ⊂◉‿◉つ</h1>
33
-
34
- <p>I'm using Express running via a <a href='https://docs.netlify.com/functions/overview/' target='_blank'>Netlify Function</a>.</p>
35
-
36
- <p>Choose a route:</p>
37
-
38
- <div>
39
- <a href='/.netlify/functions/${functionName}/users'>View /users route</a>
40
- </div>
41
-
42
- <div>
43
- <a href='/.netlify/functions/${functionName}/hello'>View /hello route</a>
44
- </div>
45
-
46
- <br/>
47
- <br/>
48
-
49
- <div>
50
- <a href='/'>
51
- Go back to demo homepage
52
- </a>
53
- </div>
54
-
55
- <br/>
56
- <br/>
57
-
58
- <div>
59
- <a href='https://github.com/DavidWells/netlify-functions-express' target='_blank'>
60
- See the source code on GitHub
61
- </a>
62
- </div>
63
- </body>
64
- </html>
65
- `
66
- res.send(html)
67
- })
68
-
69
- router.get('/users', function onRequest(req, res) {
70
- res.json({
71
- users: [
72
- {
73
- name: 'steve',
74
- },
75
- {
76
- name: 'joe',
77
- },
78
- ],
79
- })
80
- })
81
-
82
- router.get('/hello/', function onRequest(req, res) {
83
- res.send('hello world')
84
- })
85
-
86
- // Attach logger
87
- app.use(morgan(customLogger))
88
-
89
- // Setup routes
90
- app.use(routerBasePath, router)
91
-
92
- // Apply express middlewares
93
- router.use(cors())
94
- router.use(express.json())
95
- router.use(express.urlencoded({ extended: true }))
96
-
97
- return app
98
- }
99
-
100
- const customLogger = function (tokens, req, res) {
101
- const log = [
102
- tokens.method(req, res),
103
- tokens.url(req, res),
104
- tokens.status(req, res),
105
- tokens.res(req, res, 'content-length'),
106
- '-',
107
- tokens['response-time'](req, res),
108
- 'ms',
109
- ].join(' ')
110
-
111
- if (process.env.NODE_ENV !== 'dev') {
112
- // Log only in AWS context to get back function logs
113
- console.log(log)
114
- }
115
- return log
116
- }