├── .babelrc ├── .gitignore ├── .npmignore ├── README.md ├── example-data.png ├── index.js ├── package.json └── src └── gatsby-node.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["babel-preset-gatsby-package"] 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /gatsby-node.js 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src 3 | .babelrc 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gatsby-source-faunadb 2 | 3 | ## Install the source plugin 4 | 5 | Enter the following into your terminal in the root directory of your Gatsby project: 6 | ``` 7 | npm install gatsby-source-faunadb 8 | ``` 9 | 10 | or, if you are using Yarn: 11 | ``` 12 | yarn add gatsby-source-faunadb 13 | ``` 14 | 15 | ## Configure your project 16 | To connect your Gatsby project to your Fauna database, add the following to the `/gatsby-config.js` file in your project directory: 17 | ```js 18 | module.exports = { 19 | //... 20 | plugins: [ 21 | //... 22 | { 23 | resolve: `gatsby-source-faunadb`, 24 | options: { 25 | // The secret for the key you're using to connect to your Fauna database. 26 | // You can generate on of these in the "Security" tab of your Fauna Console. 27 | secret: "___YOUR_FAUNADB_SECRET___", 28 | // The name of the index you want to query 29 | // You can create an index in the "Indexes" tab of your Fauna Console. 30 | index: `animalsByType`, 31 | // If your index requires arguments, you can specify them like this. 32 | // You can omit this property if your index doesn't need any. 33 | arguments: ["bird"], 34 | // This is the name under which your data will appear in Gatsby GraphQL queries 35 | // The following will create queries called `allBird` and `bird`. 36 | type: "bird", 37 | // If you need to limit the number of documents returned, you can specify a 38 | // maximum number to read. 39 | size: 100 40 | }, 41 | }, 42 | //... 43 | ], 44 | } 45 | ``` 46 | If you'd like to include multiple indexes in your Gatsby project you can add the above section many times, once for each index. 47 | You can also include the same index multiple times with different arguments and types. 48 | 49 | ## Query the data 50 | Your data will appear in your Gatesby project under the `type` name that you gave in `./gatsby-config.js`. 51 | For example, for the config above you can query: 52 | 53 | ```graphql 54 | query MyQuery { 55 | allBird { 56 | nodes { 57 | name 58 | type 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | or, to fetch a single document: 65 | ```graphql 66 | query MyQuery { 67 | bird(name: {eq: "Flamingo"}) { 68 | name 69 | type 70 | _id 71 | _ts 72 | } 73 | } 74 | ``` 75 | Note the Fauna document ID and timestamp are also available in the returned type, as `_id` and `_ts` respectively. 76 | 77 | 78 | ## Example 79 | Given the following data in a Fauna collection: 80 | ```json 81 | [ 82 | { "name": "Pallas's cat", "type": "cat" }, 83 | { "name": "Capybara", "type": "rodent" }, 84 | { "name": "Flamingo", "type": "bird" }, 85 | { "name": "Snow leopard", "type": "cat" }, 86 | { "name": "Penguin", "type": "bird" } 87 | ] 88 | ``` 89 | 90 | ...and an index called `allAnimals`, that return all documents: 91 | 92 | ![Screenshot of index and results in the Fauna Console](./example-data.png) 93 | 94 | We can use the following configuration in `/gatsby-config.js`: 95 | ```js 96 | module.exports = { 97 | plugins: [ 98 | { 99 | resolve: `gatsby-source-faunadb`, 100 | options: { 101 | secret: "___YOUR_FAUNADB_SECRET___", 102 | index: `allAnimals`, 103 | type: "animal", 104 | }, 105 | }, 106 | ], 107 | } 108 | ``` 109 | 110 | This will make our data available to query as `allAnimal` in Gatesby GraphQL: 111 | ```graphql 112 | query MyQuery { 113 | allAnimal { 114 | nodes { 115 | name 116 | type 117 | } 118 | } 119 | } 120 | ``` 121 | 122 | Result: 123 | ```json 124 | { 125 | "data": { 126 | "allAnimal": { 127 | "nodes": [ 128 | { 129 | "name": "Pallas's cat", 130 | "type": "cat" 131 | }, 132 | { 133 | "name": "Capybara", 134 | "type": "rodent" 135 | }, 136 | { 137 | "name": "Flamingo", 138 | "type": "bird" 139 | }, 140 | { 141 | "name": "Snow leopard", 142 | "type": "cat" 143 | }, 144 | { 145 | "name": "Penguin", 146 | "type": "bird" 147 | } 148 | ] 149 | } 150 | } 151 | } 152 | ``` 153 | 154 | 155 | ## Troubleshooting 156 | 157 | A common issue may be that the key secret you're using doesn't have enough access to return the data. If this is the case, you'll see the following message when running `gatsby develop`: 158 | 159 | ``` 160 | ERROR 161 | 162 | [PermissionDenied: permission denied] { 163 | name: 'PermissionDenied', 164 | message: 'permission denied', 165 | requestResult: RequestResult { 166 | method: 'POST', 167 | ... 168 | } 169 | } 170 | ``` 171 | 172 | If you see this, make sure you're using the correct secret and that the associated key has the correct permissions. **Your key will need permission to read all indexes that you're using _and_ all the collections that those indexes use.** 173 | 174 | 175 | ## Get involved 176 | 177 | Thank you for using `gatsby-source-fauna` and I hope you find it useful. If you stumble upon any issues, please consider logging the issue or opening a pull request. All contributions very welcome. 178 | 179 | 💛paulcuth. -------------------------------------------------------------------------------- /example-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/paulcuth/gatsby-source-faunadb/fa83e1f87e405c8a01374efc9e3781ad78e165ec/example-data.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // noop 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-source-faunadb", 3 | "description": "A Gatsby source plugin to fetch documents from Fauna DB.", 4 | "version": "1.0.0", 5 | "author": "Paul Cuthbertson ", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/paulcuth/gatsby-source-faunadb.git" 9 | }, 10 | "bugs": { 11 | "url": "https://github.com/paulcuth/gatsby-source-faunadb/issues" 12 | }, 13 | "keywords": [ 14 | "gatsby", 15 | "gatsby-plugin", 16 | "fauna", 17 | "faunadb" 18 | ], 19 | "license": "MIT", 20 | "dependencies": { 21 | "faunadb": "^2.13.1", 22 | "@babel/runtime": "^7.8.7" 23 | }, 24 | "devDependencies": { 25 | "@babel/cli": "^7.8.4", 26 | "@babel/core": "^7.8.7", 27 | "babel-preset-gatsby-package": "^0.3.1", 28 | "cross-env": "^5.2.1" 29 | }, 30 | "peerDependencies": { 31 | "gatsby": "^2.0.15" 32 | }, 33 | "scripts": { 34 | "build": "babel src --out-dir .", 35 | "prepare": "cross-env NODE_ENV=production npm run build" 36 | }, 37 | "engines": { 38 | "node": ">=10.13.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/gatsby-node.js: -------------------------------------------------------------------------------- 1 | const faunadb = require("faunadb"); 2 | const q = faunadb.query; 3 | 4 | exports.sourceNodes = async ( 5 | { actions, createNodeId, createContentDigest }, 6 | options 7 | ) => { 8 | const { createNode } = actions; 9 | const { secret, type, index, arguments: args = [] } = options; 10 | 11 | const client = new faunadb.Client({ secret }); 12 | 13 | try { 14 | const size = 15 | options.size != null ? options.size + 1 : q.Count(q.Var("result")); 16 | 17 | const documents = await client.query( 18 | q.Let( 19 | { result: q.Match(q.Index(index), ...args) }, 20 | q.Map( 21 | q.Select("data", q.Paginate(q.Var("result"), { size })), 22 | q.Lambda("ref", q.Get(q.Var("ref"))) 23 | ) 24 | ) 25 | ); 26 | 27 | documents.forEach(document => { 28 | const id = document.ref.id || document.ref["@ref"].id; 29 | if (document.data == null) { 30 | return; 31 | } 32 | 33 | createNode({ 34 | ...document.data, 35 | id: createNodeId(`faunadb-${type}-${id}`), 36 | _id: document.ref.id, 37 | _ts: document.ts, 38 | parent: null, 39 | children: [], 40 | internal: { 41 | type: type, 42 | content: JSON.stringify(document.data), 43 | contentDigest: createContentDigest(document.data) 44 | } 45 | }); 46 | }); 47 | } catch (err) { 48 | console.error(err); 49 | } 50 | }; 51 | --------------------------------------------------------------------------------