{"id":14976129,"url":"https://github.com/okgrow/graphql-markdown","last_synced_at":"2025-10-27T18:30:40.807Z","repository":{"id":57132938,"uuid":"99857129","full_name":"okgrow/graphql-markdown","owner":"okgrow","description":"UNMAINTAINED! - Write markdown/frontmatter, generate GraphQL TypesDefs \u0026 Resolvers, query via GraphQL, and serve as html.🔥","archived":true,"fork":false,"pushed_at":"2019-01-22T22:07:54.000Z","size":2151,"stargazers_count":39,"open_issues_count":1,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-20T05:58:44.752Z","etag":null,"topics":["frontmatter","graphql","graphql-schema","markdown","yaml"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/okgrow.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-09T22:15:46.000Z","updated_at":"2024-11-05T16:35:05.000Z","dependencies_parsed_at":"2022-09-03T10:23:24.912Z","dependency_job_id":null,"html_url":"https://github.com/okgrow/graphql-markdown","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okgrow%2Fgraphql-markdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okgrow%2Fgraphql-markdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okgrow%2Fgraphql-markdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okgrow%2Fgraphql-markdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/okgrow","download_url":"https://codeload.github.com/okgrow/graphql-markdown/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238536103,"owners_count":19488655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["frontmatter","graphql","graphql-schema","markdown","yaml"],"created_at":"2024-09-24T13:53:21.712Z","updated_at":"2025-10-27T18:30:35.323Z","avatar_url":"https://github.com/okgrow.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GraphQL Markdown\n\n[![Build Status](https://semaphoreci.com/api/v1/okgrow/graphql-markdown/branches/master/shields_badge.svg)](https://semaphoreci.com/okgrow/graphql-markdown)\n[![NPM Version](https://img.shields.io/npm/v/%40okgrow%2Fgraphql-markdown.svg?style=flat-square)](https://www.npmjs.com/package/@okgrow/graphql-markdown)\n[![NPM Downloads](https://img.shields.io/npm/dm/%40okgrow%2F.svg?style=flat-square)](https://www.npmjs.com/package/@okgrow/graphql-markdown)\n\n**NOTE:** This pkg is **no longer being actively maintained**, if you'd like to maintain this pkg please express interest by opening an issue.\n\n\u003e Write markdown, generate GraphQL TypesDefs \u0026 Resolvers, query via GraphQL, and serve as html.🔥\n\n\u003cp align=\"center\"\u003e\n  \u003cimg  height=\"300\" src=\"https://raw.githubusercontent.com/okgrow/graphql-markdown/master/happy-mascot.png\"\u003e\n\u003c/p\u003e\n\nGraphQL Markdown is a simple library that parses and converts your `.md` files into `html` and automatically generates `GraphQL FieldDefinitions` from its [frontMatter](https://github.com/jonschlinkert/gray-matter) content which can then be queried via a GraphQL server.🔥\n\nAfter generating the `FieldDefinitions`, we save the processed data to an in-memory db. We export the generated `TypeDefs` and `Resolvers` to enable you to have complete control over creating your own GraphQL Schema.🎉\n\nA simple GraphQL API for querying your processed content is provided. Which includes a way to `sort`, `limit`, and `skip` your results enabling a basic form of pagination. 🍾\n\n**NOTE:** We are looking for feedback \u0026 suggestions on how to improve and further develop this pkg.\n\nPlease feel free to open an issue!\n\n## Table of Contents\n\n* [Quick Start](#quick-start)\n  * [Basic Example](#basic-example)\n  * [Querying Your Data](#querying-your-data)\n  * [Detailed Example](#detailed-exmaple)\n  * [Markdown Files](#markdown-files)\n    * [FrontMatter section](#frontmatter-section)\n    * [Markdown section](#markdown-section)\n    * [Putting it all together](#putting-it-all-together)\n    * [Seeing it in Action](#seeing-it-in-action)\n* [Advanced Example](#advanced-example)\n* [Testing](#testing)\n* [Examples](#examples)\n* [Maintainers](#maintainers)\n* [Contributing](#contributing)\n* [License](#license)\n\n## Quick Start\n\n```sh\n# With npm\nnpm install --save https://github.com/okgrow/graphql-markdown\n# With Yarn\nyarn add https://github.com/okgrow/graphql-markdown\n```\n\n### Basic example\n\n```md\n---\nid: myFirstMdFile\ngroupId: homePage\n---\n\n# Hello World!\n\nWelcome to this pale blue dot!\n```\n\n```js\nimport express from 'express';\nimport graphqlHTTP from 'express-graphql';\nimport { makeExecutableSchema } from 'graphql-tools';\n\nimport { runGraphqlMarkdown } from '@okgrow/graphql-markdown';\n\n// Create our options for processing the markdown \u0026 images.\nconst options = {\n  contentRoot: `${__dirname}/content`,\n};\n\nconst app = express();\n\n(async () =\u003e {\n  try {\n    const {\n      typeDefs,\n      resolvers,\n      fileCount, // num of files processed\n    } = await runGraphqlMarkdown(options);\n\n    console.log(\n      `Loaded \\n${fileCount} ContentItems into our in memory DB!`,\n    );\n\n    const schema = makeExecutableSchema({\n      typeDefs: typeDefs,\n      resolvers: resolvers,\n    });\n\n    app.use(\n      '/graphiql',\n      graphqlHTTP({\n        schema,\n        graphiql: true,\n      }),\n    );\n\n    // Start the server after all data has loaded.\n    app.listen(4000);\n    console.log('Server Started! http://localhost:4000/graphiql');\n  } catch (error) {\n    console.error('[runGraphqlMarkdown]', error);\n  }\n})();\n```\n\n### Options\n\nBelow are all the options you may pass to `runGraphqlMarkdown`.\n\n```js\nconst options = {\n  contentRoot: `fullpath/to/root/of/content`,               // required\n  imageResolver: ({ imgPath, contentRoot }) =\u003e {...},       // optional\n  replaceContents: ({ contentRoot, rawContents }) =\u003e {...}, // optional\n  imageFormats: '(png|svg)',                                // optional\n  debugMode: true,                                          // optional\n  syntaxHighlighter: (code) =\u003e {...},                       // optional\n};\n```\n\n#### contentRoot (Required)\n\nThe fullpath of where your `.md` content is located.\n\n#### imageResolver (Optional)\n\n`imageResolver` expects a function that will return the URI for the image. By default images are converted to base64 if no function is assigned to imageResolver.\n\n**NOTE:** You shouldn't use base64 in production as it increases the size of images significantly.\n\n```js\n// Simple example of a imageResolver function.\nconst serveImagesFromServer = ({ imgPath, contentRoot }) =\u003e\n  `/images${imgPath.slice(contentRoot.length)}`;\n```\n\n#### replaceContents (Optional)\n\n`replaceContents` is an optional function that if provided will be called against your `.md` content in order to replace the static content at run time. See below example for usage \u0026 signature.\n\n```js\nconst replaceWords = ({ contentRoot, rawContents }) =\u003e\n  rawContents.replace(new RegExp('deployment-server', 'g'), `${isProduction ? 'production' : 'development'}`);\n```\n\n#### imageFormats (Optional)\n\nImage formats that we should process. If not provided we will use the `DEFAULT_SUPPORTED_IMAGE_FORMATS`.\n\n`imageFormats` expects a string in the following format '(ext|ext|ext|..etc)', e.g `'(png|svg)'`.\n\n#### debugMode (Optional)\n\nTo enable additional logging during development. Default is `false`.\n\n#### syntaxHighlighter (Optional)\n\n`syntaxHighlighter` can be used to provide `runGraphqlMarkdown` with a function to syntax highlight your content. Simple example below using `highlight.js`.\n\n```js\nimport hljs from 'highlight.js'; // Only install/use if you want to highlight code.\n\nconst yourCodeHighlighter = (code) =\u003e hljs.highlightAuto(code).value;\n```\n\n### Querying Your Data\n\nGraphQL Markdown provides a few different approaches to querying the data extracted from your `.md` files.\n\n* 💪\u0026nbsp; A powerful \u0026 all purpose query: Search by logical `AND`, `OR` conditions on any fields!!! 🎉\n\n```graphql\n contentItems(filter: FilterFields!, pagination: Pagination): [ContentItem!]\n```\n\n* 🎁\u0026nbsp; Simplified helper queries: providing a clean \u0026 crisp syntax for common querying patterns. 🎊\n\n```graphql\ncontentItemById(id: ID!): ContentItem\ncontentItemsByIds(ids: [ID!]!, pagination: Pagination): [ContentItem!]\ncontentItemsByGroupId(groupId: ID!, pagination: Pagination): [ContentItem!]\n```\n\n* 🎀\u0026nbsp; Organise the query results: Simple syntax to `sort`, `skip`, and `limit` your results. 🎈\n\n```graphql\nenum OrderBy {\n  ASCENDING\n  DESCENDING\n}\n\n# Sort results by a specific field and order in Ascending or Descending order.\n# e.g -\u003e { sortBy: \"date\", orderBy: \"DESCENDING\" }\ninput Sort {\n  sortBy: String!   # Field to sort by. e.g -\u003e \"date\"\n  orderBy: OrderBy! # ASCENDING or DESCENDING order. e.g -\u003e \"DESCENDING\"\n}\n\ninput Pagination {\n  sort: Sort # Sort and order elements by a specific field in a specific order.\n  skip: Int  # Do not return the first x elements.\n  limit: Int # Limit the number of elements to return.\n}\n```\n\n\n\n## Markdown files\n\nA markdown file contains two distinct sections, the FrontMatter section and the Markdown section.\n\n```\n---\nFrontMatter Section\n---\n\nMarkdown Section\n```\n\n#### FrontMatter section\n\nThe FrontMatter section contains `key`:`value` pairs. Every Markdown file is required to contain a FrontMatter section and must contain an `id` and an `groupId` key-value pair. You can add as many additional `key`:`value` pairs as you like, we will generate `GraphQL Field Definitions` from these additional `key`:`value` at runtime. Check out the [typeDefs.graphql](./src/graphql/typeDefs.graphql) file to see where we inject these `Field Definitions`.\n\n```md\n---\nid: myFirstMdFile\ngroupId: homePage\n---\n```\n\n#### Markdown section\n\nThe Markdown section is placed after the FrontMatter section and contains your markdown content. The markdown content will be converted into valid HTML when we process all markdown files and store them in memory.\n\n```md\n# My First Markdown file\n\nHello World!\n```\n\n#### Putting it all together\n\n```md\n---\nid: home-content-section-1\ngroupId: homePage\ntype: pageContent\ntitle: Wonder Website\ndescription: Wonder Website - Home Page\ndate: \"2017-12-25\"\ntags: [Happy, Learnings]\n---\n\n# Welcome to this wonderful website!\n\nHello world!\nThanks for dropping by to say hello! 🔥🔥🔥\n```\n\n#### Seeing it in Action!\n\nRun the simple-example found in `examples/simple`, and copy/paste the below snippet into GraphiQL to see the response yourself!🔥\n\n```graphql\n{\n  # Simplified helper query to search for a single ContentItem.\n  # Returns a ContentItem, else null if not found.\n  contentItemById(id: \"homePage\") {\n    html\n    description\n  }\n\n  # Simplified helper query to search for ContentItems by ids.\n  # Returns a List of contentItems, else empty List if none found.\n  # Supports Pagination (sort, skip, limit).\n  contentItemsByIds(ids: [\"graphqlIntro\", \"homePage\"]) {\n    id\n    tags\n    order\n  }\n\n  # Simplified helper query to search for ContentItems by groupId.\n  # Return a List of contentItems, else empty List if none found.\n  # Supports Pagination (sort, skip, limit).\n  contentItemsByGroupId(\n    groupId: \"simple-example\"\n    pagination: {\n      sort: {\n        sortBy: \"order\",\n        orderBy: DESCENDING\n      }\n      skip: 0\n      limit: 0\n    }\n  ) {\n    id\n    order\n    groupId\n  }\n\n  # Full powered query to search for ContentItems by any field!!!\n  # Supports searching by logical AND, OR conditions on any fields.\n  # Return a List of contentItems, else empty List if none found.\n  # Supports Pagination (sort, skip, limit).\n  contentItems(\n    filter: {\n      AND: {\n        order: 2,\n        groupId: \"simple-example\"\n        }\n      }\n    pagination: {\n      sort: {\n        sortBy: \"order\",\n        orderBy: ASCENDING\n        }\n      }\n  ) {\n    id\n    type\n    date\n    groupId\n    description\n  }\n}\n```\n## Advanced Example\n\nThis example will be showing all the possible options and features of this package.\n\n```js\n// server/index.js\nimport hljs from 'highlight.js'; // Only install/use if you want to highlight code.\nimport { makeExecutableSchema } from 'graphql-tools';\nimport { runGraphqlMarkdown } from '@okgrow/graphql-markdown';\n\nconst isProduction = process.env.NODE_ENV === 'production';\n\n// Simple example of imageResolver.\nconst serveImagesFromServer = ({ imgPath, contentRoot }) =\u003e\n  `/images${imgPath.slice(contentRoot.length)}`;\n\nconst replaceWords = ({ contentRoot, rawContents }) =\u003e\n  rawContents.replace(new RegExp('deployment-server', 'g'), `${isProduction ? 'production' : 'development'}`);\n\n// NOTE: Simple example of highlighting code by using highlight.js. You can use\n// any highlighter you like that conforms to the below function signature.\nconst yourCodeHighlighter = (code) =\u003e hljs.highlightAuto(code).value;\n\n// Create our options for loading the markdown into our in memory db.\n// NOTE: By default images are converted to base64 if no function is passed to imageResolver.\n// NOTE: You shouldn't use base64 in production as it increases the size of images significantly.\n// NOTE: imageFormats is optional, if not provided it will use the DEFAULT_SUPPORTED_IMAGE_FORMATS.\n// imageFormats expects a string in the following format '(ext|ext|ext|..etc)'\nconst options = {\n  contentRoot: `fullpath/to/root/of/content`,             // required\n  imageResolver: isProduction ? serveImagesFromServer : null, // optional\n  replaceContents: replaceWords,                          // optional\n  imageFormats: '(png|svg)',                              // optional\n  debugMode: true,                                        // optional\n  syntaxHighlighter: yourCodeHighlighter,                   // optional\n  },\n};\n\n(async () =\u003e {\n  try {\n    // Find all markdown files, process and load them into memory and\n    // return the TypeDefs \u0026 Resolvers for the graphql-markdown pkg.\n    const {\n      typeDefs,\n      resolvers,\n      fileCount,\n    } = await runGraphqlMarkdown(options);\n    console.log(`DB ready!\\n${fileCount} ContentItems loaded!`);\n\n    const schema = makeExecutableSchema({\n      typeDefs,\n      resolvers,\n    });\n\n    // Now start your GraphQL Server using the schema you just created.\n    // If your unsure how to do this check out the examples dir.\n\n  } catch (error) {\n    console.error('[runGraphqlMarkdown]', error);\n  }\n})();\n```\n\n## Testing\n\n```sh\n# clone the repo\ngit clone git@github.com:okgrow/graphql-markdown.git\n# Don't forget to install\nnpm install\n# Run all tests (We use Jest)\nnpm test\n```\n\n## Examples\n\nCheck out the examples folder to see how it all works. Please note:\n\n* Node version 8+ is required.\n* You must run `npm install` on the main package first as the examples import the `/dist` files.\n* Examples contain detailed instructions \u0026 example queries to copy paste into Graphiql.\n\n## Maintainers\n\nThis is an open source package. We hope to deal with contributions in a timely manner, but that's not always the case. The main maintainers are:\n\n[@cfnelson](https://github.com/cfnelson)\n\n[@okgrow](https://github.com/okgrow)\n\nFeel free to ping if there are open issues or pull requests which are taking a while to be dealt with!\n\n## Contributing\n\nIssues and Pull Requests are always welcome.\n\nPlease read our [contribution guidelines](https://github.com/okgrow/guides/blob/master/open-source/contributing.md).\n\nIf you are interested in becoming a maintainer, get in touch with us by sending an email or opening an issue. You should already have code merged into the project. Active contributors are encouraged to get in touch.\n\nPlease note that all interactions in @okgrow's repos should follow our [Code of Conduct](https://github.com/okgrow/guides/blob/master/open-source/CODE_OF_CONDUCT.md).\n\n## License\n\nReleased under the [MIT license](https://github.com/okgrow/graphql-markdown/blob/master/LICENCE) © 2017 OK GROW!.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokgrow%2Fgraphql-markdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fokgrow%2Fgraphql-markdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokgrow%2Fgraphql-markdown/lists"}