Skip to content

Commit

Permalink
feat: generate js client, closes #9
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Sep 1, 2020
1 parent e029b7d commit f55f294
Show file tree
Hide file tree
Showing 10 changed files with 1,654 additions and 1,402 deletions.
84 changes: 50 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# 🤺 Mordred
# 🤺 Mordred

[![npm version](https://flat.badgen.net/npm/v/mordred?scale=1.5)](https://npm.im/mordred) [![community](https://flat.badgen.net/badge/icon/discord?icon=discord&label=community&scale=1.5)](https://chat.egoist.sh)

__Source data from anywhere, for Next.js, Nuxt.js, Eleventy and many more.__
**Source data from anywhere, for Next.js, Nuxt.js, Eleventy and many more.**

## Features

✅ Inspired by [Gatsby](https://gatsbyjs.org), you can query any data (Markdown, API, database, CMS) with GraphQL<br>
✅ Automatically generate JavaScript client for better dev experience
✅ Framework agnostic, works with any framework that has SSG support<br>
✅ Tons of plugins for popular headless CMS (not yet, we need your contribution!)

Expand All @@ -20,8 +21,8 @@ __Source data from anywhere, for Next.js, Nuxt.js, Eleventy and many more.__
- [Usage with Next.js](#usage-with-nextjs)
- [Configuration](#configuration)
- [Using Data](#using-data)
- [Execute Raw Query](#execute-raw-query)
- [Exploring Data with GraphiQL](#exploring-data-with-graphiql)
- [Usage With Nuxt.js](#usage-with-nuxtjs)
- [Plugin List](#plugin-list)
- [License](#license)

Expand All @@ -40,29 +41,27 @@ yarn add mordred
In `next.config.js`:

```js
module.exports = {
webpack(config) {
const { MordredWebpackPlugin } = require('mordred/webpack')
const { withMordred } = require('mordred/next')

const mordredPlugin = new MordredWebpackPlugin()
config.plugins.push(mordredPlugin)
return config
},
}
module.exports = withMordred({
// Extra Next.js config..
})
```

Then create a `mordred.config.js` in the same directory and use some plugins:

```js
module.exports = {
plugins: [
// Load markdown files from file system
{
resolve: 'mordred-source-filesystem',
options: {
// This is where you'll be creating Markdown files
path: __dirname + '/content',
},
},
// Transform files to markdown nodes
{
resolve: 'mordred-transformer-markdown',
},
Expand All @@ -87,40 +86,38 @@ date: 2020-04-24
---

This is my **first** post!
````
```

When you run `next` or `next build`, Mordred will generate a GraphQL client at `mordred/graphql.js`, then you can use the generated client to query data.

Now in any page, query data in `getStaticProps`:

```js
import { query, gql } from '../mordred/graphql'
import { client } from '../mordred/graphql'

export const getStaticProps = async () => {
const { data, errors } = await query(gql`
const { allMarkdown } = await client.query([
{
limit: 20
},
{
allMarkdown {
nodes {
id
slug
createdAt
updatedAt
html
allMarkdown: {
nodes: {
id: true,
slug: true,
createdAt: true,
updatedAt: true,
html: true,
frontmatter {
# ... or any frontmatter
# like:
title
title: true
}
}
}
}
`)
if (errors) {
throw errors[0]
}
])
return {
props: {
...data,
allMarkdown
},
}
}
Expand All @@ -140,6 +137,29 @@ export default ({ allMarkdown }) => {
}
```

### Execute Raw Query

If you prefer GraphQL SDL over the JavaScript client, you can execute raw query too:

```js
import { executeQuery, gql } from './path/to/mordred/graphql'

const { data, errors } = await executeQuery(
gql`
query($limit: Int!) {
allMarkdown(limit: $limit) {
id
}
}
`,
{
limit: 20,
},
)
```

Note that we use the `gql` tag here only for syntax highlighting in supported editors like VS Code, it's completely optional.

### Exploring Data with GraphiQL

You can create an API at `/api/graphql` to explore data via GraphiQL:
Expand All @@ -155,16 +175,12 @@ app.use(
graphqlHTTP({
schema,
graphiql: true,
})
}),
)

export default app
```

## Usage With Nuxt.js

We're waiting for Nuxt's full-static mode, it's already possible to use Mordred with Nuxt's `asyncData` though. We'll document this soon.

## Plugin List

- [mordred-source-filesystem](/packages/mordred-source-filesystem)
Expand Down
53 changes: 23 additions & 30 deletions example/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,37 @@
import Link from 'next/link'
import { query } from '../mordred/graphql'
import { client } from '../mordred/graphql'

export const getStaticProps = async ({ params = {} }) => {
const limit = 1
const page = Number(params.page || 1)
const skip = (page - 1) * limit
const { data, errors } = await query(
`
query ($skip: Int!, $limit: Int!){
allMarkdown(skip: $skip, limit: $limit) {
nodes {
id
html
createdAt
frontmatter {
title
}
}
pageInfo {
hasNextPage
hasPrevPage
}
}
}
`,
{
variables: {
const { allMarkdown } = await client.query({
allMarkdown: [
{
skip,
limit,
},
}
)
if (errors) {
throw errors[0]
}
{
nodes: {
id: true,
html: true,
createdAt: true,
frontmatter: {
title: true,
},
},
pageInfo: {
hasNextPage: true,
hasPrevPage: true,
},
},
],
})

return {
props: {
page,
...data,
allMarkdown,
},
}
}
Expand All @@ -63,8 +57,7 @@ export default ({ allMarkdown, page }) => {
<Link href={page === 2 ? `/` : `/page/${page - 1}`}>
<a>Prev Page</a>
</Link>
)}
{' '}
)}{' '}
{allMarkdown.pageInfo.hasNextPage && (
<Link href={`/page/${page + 1}`}>
<a>Next Page</a>
Expand Down
28 changes: 14 additions & 14 deletions example/pages/page/[page].js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { query, gql } from '../../mordred/graphql'
import { client } from '../../mordred/graphql'

export { getStaticProps, default } from '../'

export const getStaticPaths = async () => {
const { data, errors } = await query(gql`
query {
allMarkdown(limit: 1) {
pageInfo {
pageCount
}
}
}
`)
if (errors) {
throw errors[0]
}
const paths = new Array(data.allMarkdown.pageInfo.pageCount)
const { allMarkdown } = await client.query({
allMarkdown: [
{
limit: 1,
},
{
pageInfo: {
pageCount: true,
},
},
],
})
const paths = new Array(allMarkdown.pageInfo.pageCount)
.fill(null)
.map((_, i) => {
return {
Expand Down
2 changes: 1 addition & 1 deletion packages/mordred-source-filesystem/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const plugin: PluginFactory = (
{ path = 'content', include = '**/*.md' },
) => {
const gql = ctx.gql
const contentDir = resolve(process.env.__MORDRED_CONTEXT!, path)
const contentDir = resolve(ctx.cwd, path)
const contentGlobs = [...(Array.isArray(include) ? include : [include])]

return {
Expand Down
18 changes: 18 additions & 0 deletions packages/mordred/next.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export const withMordred = (config = {}) => {
const webpack = config.webpack

config.webpack = (webpackConfig, options) => {
const { MordredWebpackPlugin } = require('./webpack')

const mordredPlugin = new MordredWebpackPlugin()
webpackConfig.plugins.push(mordredPlugin)

if (webpack) {
webpackConfig = webpack(webpackConfig, options)
}

return webpackConfig
}

return config
}
7 changes: 5 additions & 2 deletions packages/mordred/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"files": [
"dist",
"/webpack.js",
"/templates"
"/templates",
"/next.js"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand All @@ -27,18 +28,20 @@
"@types/webpack": "^4.41.12",
"express": "^4.17.1",
"express-graphql": "^0.9.0",
"next": "^9.3.5",
"next": "9.5.2",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"dependencies": {
"@graphql-tools/merge": "^6.2.0",
"chokidar": "^3.3.1",
"ejs": "^3.1.2",
"fast-glob": "^3.2.2",
"fs-extra": "^9.0.0",
"graphql": "^14.0.0",
"graphql-tools": "^5.0.0",
"graphql-type-json": "^0.3.1",
"graphql-zeus": "^2.7.5",
"hash-sum": "^2.0.0",
"joycon": "^2.2.5",
"mime": "^2.4.4",
Expand Down

0 comments on commit f55f294

Please sign in to comment.