├── .gitignore
├── README.md
├── functions
├── graphql.js
├── package-lock.json
└── package.json
├── netlify.toml
├── package.json
└── site
├── deploy.svg
├── github.svg
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
3 |
4 | # Ignore netlify folder
5 | .netlify
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Netlify Functions + GraphQL
2 |
3 | This repo demonstrates how to use functions for a GraphQL API using `apollo-server-lambda`.
4 |
5 | See the graphQL [function code](./functions/graphql.js)
6 |
7 | For more information on functions. Checkout [functions.netlify.com](https://functions.netlify.com/) and the [Netlify functions workshop](https://github.com/DavidWells/netlify-functions-workshop#workshop-lessons)
8 |
9 | ## Setup & Deployment
10 |
11 | ### Easy mode:
12 |
13 | Simply click the deploy button:
14 |
15 |
16 |
17 |
18 |
19 | ### Manual mode:
20 |
21 | Follow the steps below to set this up via the [`netlify-cli`](https://cli.netlify.com/)
22 |
23 | 1. **Fork this repo**
24 |
25 | Fork this repo and clone it down to your local machine
26 |
27 | ```bash
28 | git clone repoURL
29 | ```
30 |
31 | 2. **Create this site in Netlify**
32 |
33 | Open your terminal and run the following command:
34 |
35 | ```bash
36 | netlify init
37 | ```
38 |
39 | Choose "create & configure a new site", then add a site name or hit enter for one to be generated for you.
40 |
41 | 3. **Install our graphQL dependencies**
42 |
43 | Change directories into our functions folder and create new package.json
44 |
45 | ```bash
46 | cd functions && npm init -y
47 | ```
48 |
49 | Now install the `apollo-server-lambda` npm package
50 |
51 | ```bash
52 | npm install apollo-server-lambda
53 | ```
54 |
55 | 4. **Require the graphQL dependencies in your function**
56 |
57 | In `functions/graphql.js`, require 'apollo-server-lambda'
58 |
59 | 5. **Define your GraphQL types**
60 |
61 | In `functions/graphql.js`, define your graphQL types
62 |
63 | 6. **Define your GraphQL resolvers**
64 |
65 | In `functions/graphql.js`, define your graphQL resolvers
66 |
67 | 7. **Create a new `ApolloServer`**
68 |
69 | In `functions/graphql.js`, create a new `ApolloServer` and pass it your typeDefs and resolves
70 |
71 | 8. **Export the Lambda compatible ApolloServer**
72 |
73 | In `functions/graphql.js`, turn your server into a lambda compatible function signature
74 |
75 | ```js
76 | server.createHandler()
77 | ```
78 |
79 | Then export the handler
80 |
81 | 9. **Deploy the site**
82 |
83 | Open your terminal and run the following command:
84 |
85 | ```bash
86 | netlify deploy -p
87 | ```
88 |
89 | Open the frontend and test your new graphQL endpoint
90 |
91 | ```
92 | netlify open:site
93 | ```
94 |
95 | 10. **You did it! 🎉**
96 |
97 | You should see a site like [https://graphql-functions.netlify.com/](https://graphql-functions.netlify.com/) where you can explore your graphQL schema.
98 |
99 | ## Additional resources
100 |
101 | - [The Fullstack Tutorial for GraphQL](https://www.howtographql.com/)
102 |
--------------------------------------------------------------------------------
/functions/graphql.js:
--------------------------------------------------------------------------------
1 | const { ApolloServer, gql } = require('apollo-server-lambda')
2 |
3 | const typeDefs = gql`
4 | type Query {
5 | hello: String
6 | }
7 | `
8 |
9 | const resolvers = {
10 | Query: {
11 | hello: (root, args, context) => {
12 | return `Hello from Netlify function. https://bit.ly/2UXh0fD`
13 | }
14 | }
15 | }
16 |
17 | const server = new ApolloServer({
18 | typeDefs,
19 | resolvers
20 | })
21 |
22 | exports.handler = server.createHandler()
23 |
--------------------------------------------------------------------------------
/functions/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "graphql",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@apollographql/apollo-tools": {
8 | "version": "0.3.5",
9 | "resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.3.5.tgz",
10 | "integrity": "sha512-5ySiiNT2EIwxGKWyoAOnibCPUXvbxKOVxiPMK4uIXmvF+qbGNleQWP+vekciiAmCCESPmGd5szscRwDm4G/NNg==",
11 | "requires": {
12 | "apollo-env": "0.4.0"
13 | }
14 | },
15 | "@apollographql/graphql-playground-html": {
16 | "version": "1.6.6",
17 | "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz",
18 | "integrity": "sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ=="
19 | },
20 | "@protobufjs/aspromise": {
21 | "version": "1.1.2",
22 | "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
23 | "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
24 | },
25 | "@protobufjs/base64": {
26 | "version": "1.1.2",
27 | "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
28 | "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
29 | },
30 | "@protobufjs/codegen": {
31 | "version": "2.0.4",
32 | "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
33 | "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
34 | },
35 | "@protobufjs/eventemitter": {
36 | "version": "1.1.0",
37 | "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
38 | "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
39 | },
40 | "@protobufjs/fetch": {
41 | "version": "1.1.0",
42 | "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
43 | "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
44 | "requires": {
45 | "@protobufjs/aspromise": "^1.1.1",
46 | "@protobufjs/inquire": "^1.1.0"
47 | }
48 | },
49 | "@protobufjs/float": {
50 | "version": "1.0.2",
51 | "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
52 | "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
53 | },
54 | "@protobufjs/inquire": {
55 | "version": "1.1.0",
56 | "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
57 | "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
58 | },
59 | "@protobufjs/path": {
60 | "version": "1.1.2",
61 | "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
62 | "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
63 | },
64 | "@protobufjs/pool": {
65 | "version": "1.1.0",
66 | "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
67 | "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
68 | },
69 | "@protobufjs/utf8": {
70 | "version": "1.1.0",
71 | "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
72 | "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
73 | },
74 | "@types/events": {
75 | "version": "3.0.0",
76 | "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
77 | "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
78 | },
79 | "@types/long": {
80 | "version": "4.0.0",
81 | "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz",
82 | "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q=="
83 | },
84 | "@types/node": {
85 | "version": "11.13.0",
86 | "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.0.tgz",
87 | "integrity": "sha512-rx29MMkRdVmzunmiA4lzBYJNnXsW/PhG4kMBy2ATsYaDjGGR75dCFEVVROKpNwlVdcUX3xxlghKQOeDPBJobng=="
88 | },
89 | "@types/ws": {
90 | "version": "6.0.1",
91 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.1.tgz",
92 | "integrity": "sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q==",
93 | "requires": {
94 | "@types/events": "*",
95 | "@types/node": "*"
96 | }
97 | },
98 | "apollo-cache-control": {
99 | "version": "0.5.2",
100 | "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.5.2.tgz",
101 | "integrity": "sha512-uehXDUrd3Qim+nzxqqN7XT1YTbNSyumW3/FY5BxbKZTI8d4oPG4eyVQKqaggooSjswKQnOoIQVes3+qg9tGAkw==",
102 | "requires": {
103 | "apollo-server-env": "2.2.0",
104 | "graphql-extensions": "0.5.4"
105 | },
106 | "dependencies": {
107 | "graphql-extensions": {
108 | "version": "0.5.4",
109 | "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.5.4.tgz",
110 | "integrity": "sha512-qLThJGVMqcItE7GDf/xX/E40m/aeqFheEKiR5bfra4q5eHxQKGjnIc20P9CVqjOn9I0FkEiU9ypOobfmIf7t6g==",
111 | "requires": {
112 | "@apollographql/apollo-tools": "^0.3.3"
113 | }
114 | }
115 | }
116 | },
117 | "apollo-datasource": {
118 | "version": "0.3.1",
119 | "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.3.1.tgz",
120 | "integrity": "sha512-qdEUeonc9pPZvYwXK36h2NZoT7Pddmy0HYOzdV0ON5pcG1YtNmUyyYi83Q60V5wTWjuaCjyJ9hOY6wr0BMvQuA==",
121 | "requires": {
122 | "apollo-server-caching": "0.3.1",
123 | "apollo-server-env": "2.2.0"
124 | }
125 | },
126 | "apollo-engine-reporting": {
127 | "version": "1.0.7",
128 | "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-1.0.7.tgz",
129 | "integrity": "sha512-mFsXvd+1/o5jSa9tI2RoXYGcvCLcwwcfLwchjSTxqUd4ViB8RbqYKynzEZ+Omji7PBRM0azioBm43f7PSsQPqA==",
130 | "requires": {
131 | "apollo-engine-reporting-protobuf": "0.2.1",
132 | "apollo-graphql": "^0.1.0",
133 | "apollo-server-core": "2.4.8",
134 | "apollo-server-env": "2.2.0",
135 | "async-retry": "^1.2.1",
136 | "graphql-extensions": "0.5.7"
137 | }
138 | },
139 | "apollo-engine-reporting-protobuf": {
140 | "version": "0.2.1",
141 | "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.2.1.tgz",
142 | "integrity": "sha512-5pYR84uWeylRS2OJowtkTczT3bWTwOErWtfnkRKccUi/wZ/AZJBP+D5HKNzM7xoFcz9XvrJyS+wBTz1oBi0Jiw==",
143 | "requires": {
144 | "protobufjs": "^6.8.6"
145 | }
146 | },
147 | "apollo-env": {
148 | "version": "0.4.0",
149 | "resolved": "https://registry.npmjs.org/apollo-env/-/apollo-env-0.4.0.tgz",
150 | "integrity": "sha512-TZpk59RTbXd8cEqwmI0KHFoRrgBRplvPAP4bbRrX4uDSxXvoiY0Y6tQYUlJ35zi398Hob45mXfrZxeRDzoFMkQ==",
151 | "requires": {
152 | "core-js": "3.0.0-beta.13",
153 | "node-fetch": "^2.2.0",
154 | "sha.js": "^2.4.11"
155 | }
156 | },
157 | "apollo-graphql": {
158 | "version": "0.1.3",
159 | "resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.1.3.tgz",
160 | "integrity": "sha512-bYgDh71jFfHKO9ioGlxnnoSYgpNp6LRl+/QHTx6tktQEN0Z+AdpkOKFNCHO/pRU/4vSqV5wuIhxhnCecxJQrMA==",
161 | "requires": {
162 | "apollo-env": "0.4.0",
163 | "lodash.sortby": "^4.7.0"
164 | }
165 | },
166 | "apollo-link": {
167 | "version": "1.2.11",
168 | "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.11.tgz",
169 | "integrity": "sha512-PQvRCg13VduLy3X/0L79M6uOpTh5iHdxnxYuo8yL7sJlWybKRJwsv4IcRBJpMFbChOOaHY7Og9wgPo6DLKDKDA==",
170 | "requires": {
171 | "apollo-utilities": "^1.2.1",
172 | "ts-invariant": "^0.3.2",
173 | "tslib": "^1.9.3",
174 | "zen-observable-ts": "^0.8.18"
175 | }
176 | },
177 | "apollo-server-caching": {
178 | "version": "0.3.1",
179 | "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.3.1.tgz",
180 | "integrity": "sha512-mfxzikYXbB/OoEms77AGYwRh7FF3Oim5v5XWAL+VL49FrkbZt5lopVa4bABi7Mz8Nt3Htl9EBJN8765s/yh8IA==",
181 | "requires": {
182 | "lru-cache": "^5.0.0"
183 | }
184 | },
185 | "apollo-server-core": {
186 | "version": "2.4.8",
187 | "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.4.8.tgz",
188 | "integrity": "sha512-N+5UOzHhMOnHizEiArJtNvEe/cGhSHQyTn5tlU4RJ36FDBJ/WlYZfPbGDMLISSUCJ6t+aP8GLL4Mnudt9d2PDQ==",
189 | "requires": {
190 | "@apollographql/apollo-tools": "^0.3.3",
191 | "@apollographql/graphql-playground-html": "^1.6.6",
192 | "@types/ws": "^6.0.0",
193 | "apollo-cache-control": "0.5.2",
194 | "apollo-datasource": "0.3.1",
195 | "apollo-engine-reporting": "1.0.7",
196 | "apollo-server-caching": "0.3.1",
197 | "apollo-server-env": "2.2.0",
198 | "apollo-server-errors": "2.2.1",
199 | "apollo-server-plugin-base": "0.3.7",
200 | "apollo-tracing": "0.5.2",
201 | "fast-json-stable-stringify": "^2.0.0",
202 | "graphql-extensions": "0.5.7",
203 | "graphql-subscriptions": "^1.0.0",
204 | "graphql-tag": "^2.9.2",
205 | "graphql-tools": "^4.0.0",
206 | "graphql-upload": "^8.0.2",
207 | "sha.js": "^2.4.11",
208 | "subscriptions-transport-ws": "^0.9.11",
209 | "ws": "^6.0.0"
210 | }
211 | },
212 | "apollo-server-env": {
213 | "version": "2.2.0",
214 | "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.2.0.tgz",
215 | "integrity": "sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA==",
216 | "requires": {
217 | "node-fetch": "^2.1.2",
218 | "util.promisify": "^1.0.0"
219 | }
220 | },
221 | "apollo-server-errors": {
222 | "version": "2.2.1",
223 | "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.2.1.tgz",
224 | "integrity": "sha512-wY/YE3iJVMYC+WYIf8QODBjIP4jhI+oc7kiYo9mrz7LdYPKAgxr/he+NteGcqn/0Ea9K5/ZFTGJDbEstSMeP8g=="
225 | },
226 | "apollo-server-lambda": {
227 | "version": "2.4.8",
228 | "resolved": "https://registry.npmjs.org/apollo-server-lambda/-/apollo-server-lambda-2.4.8.tgz",
229 | "integrity": "sha512-H85v4FohyoK0Q89iCWNOQqcIbu3E42sPpspPzccx8btsSTPXHlJRb/SrKCAb96Sk68XXMdwHGKzGSb2TY6WIFA==",
230 | "requires": {
231 | "@apollographql/graphql-playground-html": "^1.6.6",
232 | "apollo-server-core": "2.4.8",
233 | "apollo-server-env": "2.2.0",
234 | "graphql-tools": "^4.0.0"
235 | }
236 | },
237 | "apollo-server-plugin-base": {
238 | "version": "0.3.7",
239 | "resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-0.3.7.tgz",
240 | "integrity": "sha512-hW1jaLKf9qNOxMTwRq2CSqz3eqXsZuEiCc8/mmEtOciiVBq1GMtxFf19oIYM9HQuPvQU2RWpns1VrYN59L3vbg=="
241 | },
242 | "apollo-tracing": {
243 | "version": "0.5.2",
244 | "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.5.2.tgz",
245 | "integrity": "sha512-2FdwRvPIq9uuF6OzONroXep6VBGqzHOkP6LlcFQe7SdwxfRP+SD/ycHNSC1acVg2b8d+am9Kzqg2vV54UpOIKA==",
246 | "requires": {
247 | "apollo-server-env": "2.2.0",
248 | "graphql-extensions": "0.5.4"
249 | },
250 | "dependencies": {
251 | "graphql-extensions": {
252 | "version": "0.5.4",
253 | "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.5.4.tgz",
254 | "integrity": "sha512-qLThJGVMqcItE7GDf/xX/E40m/aeqFheEKiR5bfra4q5eHxQKGjnIc20P9CVqjOn9I0FkEiU9ypOobfmIf7t6g==",
255 | "requires": {
256 | "@apollographql/apollo-tools": "^0.3.3"
257 | }
258 | }
259 | }
260 | },
261 | "apollo-utilities": {
262 | "version": "1.2.1",
263 | "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.2.1.tgz",
264 | "integrity": "sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg==",
265 | "requires": {
266 | "fast-json-stable-stringify": "^2.0.0",
267 | "ts-invariant": "^0.2.1",
268 | "tslib": "^1.9.3"
269 | },
270 | "dependencies": {
271 | "ts-invariant": {
272 | "version": "0.2.1",
273 | "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.2.1.tgz",
274 | "integrity": "sha512-Z/JSxzVmhTo50I+LKagEISFJW3pvPCqsMWLamCTX8Kr3N5aMrnGOqcflbe5hLUzwjvgPfnLzQtHZv0yWQ+FIHg==",
275 | "requires": {
276 | "tslib": "^1.9.3"
277 | }
278 | }
279 | }
280 | },
281 | "async-limiter": {
282 | "version": "1.0.0",
283 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
284 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
285 | },
286 | "async-retry": {
287 | "version": "1.2.3",
288 | "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz",
289 | "integrity": "sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q==",
290 | "requires": {
291 | "retry": "0.12.0"
292 | }
293 | },
294 | "backo2": {
295 | "version": "1.0.2",
296 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
297 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
298 | },
299 | "busboy": {
300 | "version": "0.3.1",
301 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz",
302 | "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==",
303 | "requires": {
304 | "dicer": "0.3.0"
305 | }
306 | },
307 | "core-js": {
308 | "version": "3.0.0-beta.13",
309 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.0-beta.13.tgz",
310 | "integrity": "sha512-16Q43c/3LT9NyePUJKL8nRIQgYWjcBhjJSMWg96PVSxoS0PeE0NHitPI3opBrs9MGGHjte1KoEVr9W63YKlTXQ=="
311 | },
312 | "define-properties": {
313 | "version": "1.1.3",
314 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
315 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
316 | "requires": {
317 | "object-keys": "^1.0.12"
318 | }
319 | },
320 | "depd": {
321 | "version": "1.1.2",
322 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
323 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
324 | },
325 | "deprecated-decorator": {
326 | "version": "0.1.6",
327 | "resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz",
328 | "integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc="
329 | },
330 | "dicer": {
331 | "version": "0.3.0",
332 | "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz",
333 | "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==",
334 | "requires": {
335 | "streamsearch": "0.1.2"
336 | }
337 | },
338 | "es-abstract": {
339 | "version": "1.13.0",
340 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
341 | "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
342 | "requires": {
343 | "es-to-primitive": "^1.2.0",
344 | "function-bind": "^1.1.1",
345 | "has": "^1.0.3",
346 | "is-callable": "^1.1.4",
347 | "is-regex": "^1.0.4",
348 | "object-keys": "^1.0.12"
349 | }
350 | },
351 | "es-to-primitive": {
352 | "version": "1.2.0",
353 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
354 | "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
355 | "requires": {
356 | "is-callable": "^1.1.4",
357 | "is-date-object": "^1.0.1",
358 | "is-symbol": "^1.0.2"
359 | }
360 | },
361 | "eventemitter3": {
362 | "version": "3.1.0",
363 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
364 | "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA=="
365 | },
366 | "fast-json-stable-stringify": {
367 | "version": "2.0.0",
368 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
369 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
370 | },
371 | "fs-capacitor": {
372 | "version": "2.0.1",
373 | "resolved": "https://registry.npmjs.org/fs-capacitor/-/fs-capacitor-2.0.1.tgz",
374 | "integrity": "sha512-kyV2oaG1/pu9NPosfGACmBym6okgzyg6hEtA5LSUq0dGpGLe278MVfMwVnSHDA/OBcTCHkPNqWL9eIwbPN6dDg=="
375 | },
376 | "function-bind": {
377 | "version": "1.1.1",
378 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
379 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
380 | },
381 | "graphql": {
382 | "version": "14.2.1",
383 | "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.2.1.tgz",
384 | "integrity": "sha512-2PL1UbvKeSjy/lUeJqHk+eR9CvuErXoCNwJI4jm3oNFEeY+9ELqHNKO1ZuSxAkasPkpWbmT/iMRMFxd3cEL3tQ==",
385 | "requires": {
386 | "iterall": "^1.2.2"
387 | }
388 | },
389 | "graphql-extensions": {
390 | "version": "0.5.7",
391 | "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.5.7.tgz",
392 | "integrity": "sha512-HrU6APE1PiehZ46scMB3S5DezSeCATd8v+e4mmg2bqszMyCFkmAnmK6hR1b5VjHxhzt5/FX21x1WsXfqF4FwdQ==",
393 | "requires": {
394 | "@apollographql/apollo-tools": "^0.3.3"
395 | }
396 | },
397 | "graphql-subscriptions": {
398 | "version": "1.1.0",
399 | "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-1.1.0.tgz",
400 | "integrity": "sha512-6WzlBFC0lWmXJbIVE8OgFgXIP4RJi3OQgTPa0DVMsDXdpRDjTsM1K9wfl5HSYX7R87QAGlvcv2Y4BIZa/ItonA==",
401 | "requires": {
402 | "iterall": "^1.2.1"
403 | }
404 | },
405 | "graphql-tag": {
406 | "version": "2.10.1",
407 | "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.1.tgz",
408 | "integrity": "sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg=="
409 | },
410 | "graphql-tools": {
411 | "version": "4.0.4",
412 | "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.4.tgz",
413 | "integrity": "sha512-chF12etTIGVVGy3fCTJ1ivJX2KB7OSG4c6UOJQuqOHCmBQwTyNgCDuejZKvpYxNZiEx7bwIjrodDgDe9RIkjlw==",
414 | "requires": {
415 | "apollo-link": "^1.2.3",
416 | "apollo-utilities": "^1.0.1",
417 | "deprecated-decorator": "^0.1.6",
418 | "iterall": "^1.1.3",
419 | "uuid": "^3.1.0"
420 | }
421 | },
422 | "graphql-upload": {
423 | "version": "8.0.5",
424 | "resolved": "https://registry.npmjs.org/graphql-upload/-/graphql-upload-8.0.5.tgz",
425 | "integrity": "sha512-iv8R/E1b0GJ203Z2sdPgnCnU8tl9hQY+jkebiTNAjsWBT3j/I5VLBnPJdDhJSKIreWJ4/1LZjgOt60qjnH4/EQ==",
426 | "requires": {
427 | "busboy": "^0.3.0",
428 | "fs-capacitor": "^2.0.1",
429 | "http-errors": "^1.7.2",
430 | "object-path": "^0.11.4"
431 | }
432 | },
433 | "has": {
434 | "version": "1.0.3",
435 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
436 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
437 | "requires": {
438 | "function-bind": "^1.1.1"
439 | }
440 | },
441 | "has-symbols": {
442 | "version": "1.0.0",
443 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
444 | "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
445 | },
446 | "http-errors": {
447 | "version": "1.7.2",
448 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
449 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
450 | "requires": {
451 | "depd": "~1.1.2",
452 | "inherits": "2.0.3",
453 | "setprototypeof": "1.1.1",
454 | "statuses": ">= 1.5.0 < 2",
455 | "toidentifier": "1.0.0"
456 | }
457 | },
458 | "inherits": {
459 | "version": "2.0.3",
460 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
461 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
462 | },
463 | "is-callable": {
464 | "version": "1.1.4",
465 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
466 | "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
467 | },
468 | "is-date-object": {
469 | "version": "1.0.1",
470 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
471 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
472 | },
473 | "is-regex": {
474 | "version": "1.0.4",
475 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
476 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
477 | "requires": {
478 | "has": "^1.0.1"
479 | }
480 | },
481 | "is-symbol": {
482 | "version": "1.0.2",
483 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
484 | "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
485 | "requires": {
486 | "has-symbols": "^1.0.0"
487 | }
488 | },
489 | "iterall": {
490 | "version": "1.2.2",
491 | "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz",
492 | "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA=="
493 | },
494 | "lodash.sortby": {
495 | "version": "4.7.0",
496 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
497 | "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
498 | },
499 | "long": {
500 | "version": "4.0.0",
501 | "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
502 | "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
503 | },
504 | "lru-cache": {
505 | "version": "5.1.1",
506 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
507 | "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
508 | "requires": {
509 | "yallist": "^3.0.2"
510 | }
511 | },
512 | "node-fetch": {
513 | "version": "2.6.1",
514 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
515 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
516 | },
517 | "object-keys": {
518 | "version": "1.1.1",
519 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
520 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
521 | },
522 | "object-path": {
523 | "version": "0.11.4",
524 | "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz",
525 | "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk="
526 | },
527 | "object.getownpropertydescriptors": {
528 | "version": "2.0.3",
529 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
530 | "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
531 | "requires": {
532 | "define-properties": "^1.1.2",
533 | "es-abstract": "^1.5.1"
534 | }
535 | },
536 | "protobufjs": {
537 | "version": "6.8.8",
538 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz",
539 | "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==",
540 | "requires": {
541 | "@protobufjs/aspromise": "^1.1.2",
542 | "@protobufjs/base64": "^1.1.2",
543 | "@protobufjs/codegen": "^2.0.4",
544 | "@protobufjs/eventemitter": "^1.1.0",
545 | "@protobufjs/fetch": "^1.1.0",
546 | "@protobufjs/float": "^1.0.2",
547 | "@protobufjs/inquire": "^1.1.0",
548 | "@protobufjs/path": "^1.1.2",
549 | "@protobufjs/pool": "^1.1.0",
550 | "@protobufjs/utf8": "^1.1.0",
551 | "@types/long": "^4.0.0",
552 | "@types/node": "^10.1.0",
553 | "long": "^4.0.0"
554 | },
555 | "dependencies": {
556 | "@types/node": {
557 | "version": "10.14.4",
558 | "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.4.tgz",
559 | "integrity": "sha512-DT25xX/YgyPKiHFOpNuANIQIVvYEwCWXgK2jYYwqgaMrYE6+tq+DtmMwlD3drl6DJbUwtlIDnn0d7tIn/EbXBg=="
560 | }
561 | }
562 | },
563 | "retry": {
564 | "version": "0.12.0",
565 | "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
566 | "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
567 | },
568 | "safe-buffer": {
569 | "version": "5.1.2",
570 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
571 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
572 | },
573 | "setprototypeof": {
574 | "version": "1.1.1",
575 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
576 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
577 | },
578 | "sha.js": {
579 | "version": "2.4.11",
580 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
581 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
582 | "requires": {
583 | "inherits": "^2.0.1",
584 | "safe-buffer": "^5.0.1"
585 | }
586 | },
587 | "statuses": {
588 | "version": "1.5.0",
589 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
590 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
591 | },
592 | "streamsearch": {
593 | "version": "0.1.2",
594 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
595 | "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
596 | },
597 | "subscriptions-transport-ws": {
598 | "version": "0.9.16",
599 | "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.16.tgz",
600 | "integrity": "sha512-pQdoU7nC+EpStXnCfh/+ho0zE0Z+ma+i7xvj7bkXKb1dvYHSZxgRPaU6spRP+Bjzow67c/rRDoix5RT0uU9omw==",
601 | "requires": {
602 | "backo2": "^1.0.2",
603 | "eventemitter3": "^3.1.0",
604 | "iterall": "^1.2.1",
605 | "symbol-observable": "^1.0.4",
606 | "ws": "^5.2.0"
607 | },
608 | "dependencies": {
609 | "ws": {
610 | "version": "5.2.2",
611 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
612 | "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
613 | "requires": {
614 | "async-limiter": "~1.0.0"
615 | }
616 | }
617 | }
618 | },
619 | "symbol-observable": {
620 | "version": "1.2.0",
621 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
622 | "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
623 | },
624 | "toidentifier": {
625 | "version": "1.0.0",
626 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
627 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
628 | },
629 | "ts-invariant": {
630 | "version": "0.3.2",
631 | "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.3.2.tgz",
632 | "integrity": "sha512-QsY8BCaRnHiB5T6iE4DPlJMAKEG3gzMiUco9FEt1jUXQf0XP6zi0idT0i0rMTu8A326JqNSDsmlkA9dRSh1TRg==",
633 | "requires": {
634 | "tslib": "^1.9.3"
635 | }
636 | },
637 | "tslib": {
638 | "version": "1.9.3",
639 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
640 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
641 | },
642 | "util.promisify": {
643 | "version": "1.0.0",
644 | "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
645 | "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
646 | "requires": {
647 | "define-properties": "^1.1.2",
648 | "object.getownpropertydescriptors": "^2.0.3"
649 | }
650 | },
651 | "uuid": {
652 | "version": "3.3.2",
653 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
654 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
655 | },
656 | "ws": {
657 | "version": "6.2.1",
658 | "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
659 | "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
660 | "requires": {
661 | "async-limiter": "~1.0.0"
662 | }
663 | },
664 | "yallist": {
665 | "version": "3.0.3",
666 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
667 | "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
668 | },
669 | "zen-observable": {
670 | "version": "0.8.13",
671 | "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.13.tgz",
672 | "integrity": "sha512-fa+6aDUVvavYsefZw0zaZ/v3ckEtMgCFi30sn91SEZea4y/6jQp05E3omjkX91zV6RVdn15fqnFZ6RKjRGbp2g=="
673 | },
674 | "zen-observable-ts": {
675 | "version": "0.8.18",
676 | "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.18.tgz",
677 | "integrity": "sha512-q7d05s75Rn1j39U5Oapg3HI2wzriVwERVo4N7uFGpIYuHB9ff02P/E92P9B8T7QVC93jCMHpbXH7X0eVR5LA7A==",
678 | "requires": {
679 | "tslib": "^1.9.3",
680 | "zen-observable": "^0.8.0"
681 | }
682 | }
683 | }
684 | }
685 |
--------------------------------------------------------------------------------
/functions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "graphql",
3 | "version": "1.0.0",
4 | "author": "Netlify",
5 | "license": "MIT",
6 | "dependencies": {
7 | "apollo-server-lambda": "^2.4.8",
8 | "graphql": "^14.1.1"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | publish = "site"
3 | functions = "functions"
4 | command = "npm run build"
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "graphql-example",
3 | "version": "1.0.0",
4 | "description": "This repo demonstrates how to use functions for a GraphQL API using `apollo-server-lambda`.",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "cd functions && npm install"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/netlify-labs/functions-and-graphql.git"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/netlify-labs/functions-and-graphql/issues"
18 | },
19 | "homepage": "https://github.com/netlify-labs/functions-and-graphql#readme"
20 | }
21 |
--------------------------------------------------------------------------------
/site/deploy.svg:
--------------------------------------------------------------------------------
1 |
17 |
--------------------------------------------------------------------------------
/site/github.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/site/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |