This package generates a GraphQL API from a directory of Markdown files

Overview

Markdown To API

This package generates a GraphQL API from a directory of Markdown files. Additional metadata like tags, descriptions, or custom fields can be added to the Markdown files in the form of YAML front matter, a simple schema at the top of each file. These fields will be indexed and available to query and filter by in the GraphQL API.

Installation

npm install markdown-to-api --save
# or
yarn add markdown-to-api
# or
pnpm add markdown-to-api

Example

This example repository shows how markdown-to-api is used in conjunction with NextJS's Static Generation and Server-side Rendering features to create a searchable site with all the content residing in markdown files. The deployed example can be seen at https://markdown-to-api-example.vercel.app.

Usage

Initialize

import { MarkdownAPI } from 'markdown-to-api'

const mdapi = new MarkdownAPI({
  directory: `./markdown`,
  // In development mode a minisearch index file will be generated.
  writeIndex: process.env.NODE_ENV !== 'production',
  // In production mode, if a minisearch index file is found, it will be used.
  useIndex: process.env.NODE_ENV === 'production',
  // This field is optional, but if provided minisearch will be instantiated with these options. See [minisearch](https://github.com/lucaong/minisearch) to learn more. This is helpful to adjust how your files are indexed and searched.
  miniSearchOptions: {},
});

Content and Configuration

Markdown files

Each markdown file can contain an optional YAML front matter schema.

Below is markdown file showcasing such a schema.

---
title: About Tigers
description: The tiger (Panthera tigris) is the largest living cat species and a member of the genus Panthera.
tags:
- cat
- tiger
genus: Panthera
---

# About Tigers

The tiger (Panthera tigris) is the largest living cat species and a member of the genus Panthera.

It is most recognisable for its dark vertical stripes on orange fur with a white underside. An apex predator, it primarily preys on ungulates, such as deer and wild boar.

The following keys are special in the context of markdown-to-api. They will be indexed and available to query and filter by in the generated API.

  • id: A unique identifier for the markdown file. (Optional, if not provided it will be generated based off of the file path and title.)
  • title: The title of the markdown file. (Optional, will be generated from the filename if not provided.)
  • description: The description of the markdown file. (Optional)
  • tags: An array of tag ids for the markdown file. (Optional). If a config.yml file exists than these tag ids must correspond to the tags defined in config.yml
  • createdAt: An ISO 8601 formatted date string. (Optional)

Config file

In the root of the directory where the markdown files are located, a config.yml file can be used to define tags and other metadata such as making certain fields required.

In the example below we define a list of tags pertaining to felines, make the tags field required and define a new field genus marked as required. Now each markdown file we define must include tags field and a genus field.

tags:
  cat:
    description: Fits into any box.
  puma:
    name: cougar / puma
    description: Puma is a large cat, also known as a mountain lion.
  tiger:
    description: Tiger is a very large cat.
  lion:
    description: Lions have manes.
fields:
  tags:
    required: true
  genus:
    required: true

CLI

markdown-to-api generates an index.json file used for searching through the markdown files. During development this file will be generated automatically, however when running via CI/CD or as part of your build process it is useful to generate this file via a script.

node node_modules/markdown-to-api/dist/cli.mjs -d markdown

This command can be added to the scripts section of your package.json file. See the example repository to see how this works in action.

Searching

// Search all files for the term `cat`.
mdapi.getIndex().search('tiger');

// Search only tags field for the term `tiger`.
mdapi.getIndex().search('tiger', { fields: ['tags'] });

Additional options can be passed to the search method. This is an options object which is passed to minisearch.

GraphQL API

GraphQL Module

A GraphQL Module is included in this package which encapsulates the schema and resolvers provided by markdown-to-api. The example below shows how you can instantiate a new module which can then be consumed by your GraphQL server of choice.

import { createApplication } from 'graphql-modules';
import createMarkdownAPIModule } from 'markdown-to-api';

const markdownAPIModule = createMarkdownAPIModule({
  directory: `./markdown`,
  // In development mode a minisearch index file will be generated.
  writeIndex: process.env.NODE_ENV !== 'production',
  // In production mode, if a minisearch index file is found, it will be used.
  useIndex: process.env.NODE_ENV === 'production',
});

const app = createApplication({
  modules: [markdownAPIModule],
});

Example queries

query SearchMarkdownFiles {
  searchMarkdownFiles(text: "tigers") {
    count
    results {
      id
      title
      description
      createdAt
      tags {
        id
        name
        description
      }
      markdownFile {
        content
      }
    }
  }
}
query SearchTags {
  searchMarkdownFiles(text: "lion", options: { fields: ["tags"] }) {
    count
    results {
      id
      title
      description
      createdAt
      tags {
        id
        name
        description
      }
      markdownFile {
         content
      }
    }
  }
}
query AllFilesAndTags {
  countMarkdownFiles
  markdownFiles {
    id
    title
    content
    tags {
      id
      name
      description
    }
  }
  markdownFileTags {
    id
    name
    description
  }
}

Generate schema

type Query {
  countMarkdownFiles: Int
  markdownFile(id: ID!): MarkdownFile!
  markdownFiles(direction: MarkdownFilesSortDirection, limit: Int, offset: Int): [MarkdownFile!]!
  searchMarkdownFiles(text: String!, options: MarkdownFileSearchOptions, limit: Int, offset: Int): MarkdownFileSearchResults!
  autoSuggestMarkdownFileSearch(text: String!, options: MarkdownFileSearchOptions): MarkdownFileAutoSuggestResults!
  markdownFileTags: [MarkdownFileTag!]!
}

type MarkdownFile {
  content: String!
  strippedContent: String!
  id: ID!
  path: String!
  slug: String!
  tags: [MarkdownFileTag!]!
  title: String!
  description: String
  createdAt: String!
}

type MarkdownFileSearchResults {
  count: Int!
  results: [MarkdownFileSearchResult!]!
}

type MarkdownFileSearchResult {
  id: ID!
  description: String
  score: Float!
  terms: [String!]
  title: String!
  slug: String!
  path: String!
  tags: [MarkdownFileTag!]!
  createdAt: String!
  markdownFile: MarkdownFile!
}

type MarkdownFileTag {
  id: ID!
  name: String!
  description: String
}

input MarkdownFileSearchOptions {
  fields: [String!]
  weights: MarkdownFileSearchOptionsWeights
  prefix: Boolean
  fuzzy: Boolean
  maxFuzzy: Int
  combineWith: MarkdownFileSearchOptionsCombineWith
}

type MarkdownFileAutoSuggestResults {
  count: Int!
  results: [MarkdownFileAutoSuggestResult!]!
}

type MarkdownFileAutoSuggestResult {
  suggestion: String!
  terms: [String!]!
  score: Float!
}

enum MarkdownFileSearchOptionsCombineWith {
  AND
  OR
}

input MarkdownFileSearchOptionsWeights {
  fuzzy: Float!
  exact: Float!
}

enum MarkdownFilesSortDirection {
  asc
  desc
}

enum MarkdownFilesSortBy {
  title
  createdAt
}
You might also like...

A plugin for the Obsidian markdown note application, adding functionality to render markdown documents with multiple columns of text.

A plugin for the Obsidian markdown note application, adding functionality to render markdown documents with multiple columns of text.

Multi-Column Markdown Take your boring markdown document and add some columns to it! With Multi Column Markdown rather than limiting your document lay

Jan 2, 2023

A markdown-it plugin that process images through the eleventy-img plugin. Can be used in any projects that uses markdown-it.

markdown-it-eleventy-img A markdown-it plugin that process images through the eleventy-img plugin. Can be used in any projects that use markdown-it. F

Dec 20, 2022

An obsidian plugin for uploading local images embedded in markdown to remote store and export markdown for publishing to static site.

An obsidian plugin for uploading local images embedded in markdown to remote store and export markdown for publishing to static site.

Obsidian Publish This plugin cloud upload all local images embedded in markdown to specified remote image store (support imgur only, currently) and ex

Dec 13, 2022

NextJS with GraphQL using type-graphl and graphql-codegen adoptable dogs example code

This is a Next.js project bootstrapped with create-next-app. Getting Started First, run the development server: npm run dev # or yarn dev Open http://

Mar 31, 2022

GraphQL-first boilerplate that scales with TypeScript + Node Express + Apollo GraphQL APIs.

graphql-typescript-boilerplate A boilerplate project for quickly building Graphql APIs and with typescript 🚀 Installation Install the dependencies: y

May 15, 2022

GraphQL Hive provides all the tools the get visibility of your GraphQL architecture at all stages, from standalone APIs to composed schemas (Federation, Stitching)

GraphQL Hive GraphQL Hive provides all the tools the get visibility of your GraphQL architecture at all stages, from standalone APIs to composed schem

Dec 21, 2022

Directory of free JavaScript ebooks

JSbooks JSbooks is a showcase of the bests free ebooks about Javascript. Find here the best publications about your favourite programming language wit

Dec 30, 2022

Validate directory structure and file contents with an extension of JSON schema.

directory-schema-validator Description Validate directory structure and file contents with an extension of JSON schema. Install Install using NPM or s

Nov 1, 2022

Group and sort Eleventy’s verbose output by directory (and show file size with benchmarks)

Group and sort Eleventy’s verbose output by directory (and show file size with benchmarks)

eleventy-plugin-directory-output Group and sort Eleventy’s verbose output by directory (and show file size with benchmarks). Sample output from eleven

Oct 27, 2022
Comments
Releases(1.0.0)
Owner
Tim Mikeladze
I’m writing code to grow healthy work environments that provide people with fulfilling careers and learning opportunities.
Tim Mikeladze
Markdown Transformer. Transform markdown files to different formats

Mdtx Inspired by generative programming and weed :). So I was learning Elm language at home usually in the evening and now I am missing all this gener

Aexol 13 Jan 2, 2023
The repos includes script for uploading bulk files in a directory to ipfs using nft.storage

Uploading Foloder to IPFS using nft.storage This repository includes script for uploading bulk files in a directory to ipfs using nft.storage Acknowle

Dapp Composer 22 Dec 17, 2022
Generates markdown documentation from TypeScript source code.

tsdoc-markdown Generates markdown documentation from TypeScript source code. Useful for generating docs from code and injecting automatically the outc

David Dal Busco 23 Dec 7, 2022
Package fetcher is a bot messenger which gather npm packages by uploading either a json file (package.json) or a picture representing package.json. To continue...

package-fetcher Ce projet contient un boilerplate pour un bot messenger et l'executable Windows ngrok qui va permettre de créer un tunnel https pour c

AILI Fida Aliotti Christino 2 Mar 29, 2022
next-graphql-server is a library for building production-grade GraphQL servers using Next.js with API Routes

next-graphql-server next-graphql-server is an easy to use Next.js library for creating performant GraphQL endpoints on top of Next.js API Routes. Star

Jakub Neander 82 Nov 21, 2022
typescript-to-jsonschema generates JSON Schema files from your Typescript sources.

fast-typescript-to-jsonschema English | 简体中文 a tool generate json schema from typescript. Feature compile Typescript to get all type information conve

yunfly 21 Nov 28, 2022
A script that combines a folder of SVG files into a single sprites file and generates type definitions for safe usage.

remix-sprites-example A script that combines a folder of .svg files into a single sprites.svg file and type definitions for safe usage. Technical Over

Nicolas Kleiderer 19 Nov 9, 2022
A NPM package powered by Yeoman that generates a scaffolding boilerplate for back-end workflow with Node.js.

generator-noderplate Generate Node.js starter files with just one command! We have deployed a npm package that will generate a boilerplate for nodejs

Samarjeet 3 Jan 24, 2022
This package generates a unique ID/String for different browsers. Like chrome, Firefox and any other browsers which supports canvas and audio Fingerprinting.

Broprint.js The world's easiest, smallest and powerful visitor identifier for browsers. This package generates a unique ID/String for different browse

Rajesh Royal 68 Dec 25, 2022
A NodeJS Replit API package wrapped around GraphQL, returning JSON data for easy use.

repl-api.js A NodeJS Replit API package wrapped around GraphQL, returning JSON data for easy use. Contents: About Quickstart Pre-installation Installa

kokonut 5 May 20, 2022