56 | {allMarkdown.pageInfo.hasPrevPage && (
57 |
58 |
Prev Page
59 |
60 | )}{' '}
61 | {allMarkdown.pageInfo.hasNextPage && (
62 |
63 |
Next Page
64 |
65 | )}
66 |
67 | >
68 | )
69 | }
70 |
--------------------------------------------------------------------------------
/packages/mordred-transformer-markdown/src/resolvers.ts:
--------------------------------------------------------------------------------
1 | const getValue = (obj: any, path: string) => {
2 | if (path.startsWith('frontmatter__')) {
3 | return obj.frontmatter[path.replace('frontmatter__', '')]
4 | }
5 | return obj[path]
6 | }
7 |
8 | export default ({ nodes }: { nodes: any[] }) => {
9 | return {
10 | Query: {
11 | markdownBySlug(_: any, args: any) {
12 | const node = nodes.find(
13 | (node) => node.type === 'Markdown' && node.slug === args.slug,
14 | )
15 | return node
16 | },
17 |
18 | allMarkdown(_: any, args: any) {
19 | const orderBy = args.orderBy || 'createdAt'
20 | const order = args.order || 'DESC'
21 | const skip = args.skip || 0
22 |
23 | const markdownNodes = nodes
24 | .filter((node) => {
25 | return node.type === 'Markdown'
26 | })
27 | .sort((a, b) => {
28 | const aValue = getValue(a, orderBy)
29 | const bValue = getValue(b, orderBy)
30 | if (order === 'ASC') {
31 | return aValue > bValue ? 1 : -1
32 | }
33 | return aValue > bValue ? -1 : 1
34 | })
35 | const endIndex = args.limit ? skip + args.limit : markdownNodes.length
36 | const result = markdownNodes.slice(skip, endIndex)
37 | const pageCount = args.limit
38 | ? Math.ceil(markdownNodes.length / args.limit)
39 | : 1
40 | const hasNextPage = endIndex < markdownNodes.length
41 | const hasPrevPage = skip > 0
42 | return {
43 | nodes: result,
44 | pageInfo: {
45 | hasPrevPage,
46 | hasNextPage,
47 | pageCount,
48 | },
49 | }
50 | },
51 | },
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/.github/workflows/shipjs-manual-prepare.yml:
--------------------------------------------------------------------------------
1 | name: Ship js Manual Prepare
2 | on:
3 | issue_comment:
4 | types: [created]
5 | jobs:
6 | manual_prepare:
7 | if: |
8 | github.event_name == 'issue_comment' &&
9 | (github.event.comment.author_association == 'member' || github.event.comment.author_association == 'owner') &&
10 | startsWith(github.event.comment.body, '@shipjs prepare')
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v2
14 | with:
15 | fetch-depth: 0
16 | ref: master
17 | - uses: actions/setup-node@v1
18 | - run: |
19 | if [ -f "yarn.lock" ]; then
20 | yarn install
21 | else
22 | npm install
23 | fi
24 | - run: |
25 | git config --global user.email "github-actions[bot]@users.noreply.github.com"
26 | git config --global user.name "github-actions[bot]"
27 | - run: npm run release:prepare -- --yes --no-browse
28 | env:
29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30 | SLACK_INCOMING_HOOK: ${{ secrets.SLACK_INCOMING_HOOK }}
31 |
32 | create_done_comment:
33 | if: success()
34 | needs: manual_prepare
35 | runs-on: ubuntu-latest
36 | steps:
37 | - uses: actions/github@master
38 | env:
39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40 | with:
41 | args: comment "@${{ github.actor }} `shipjs prepare` done"
42 |
43 | create_fail_comment:
44 | if: cancelled() || failure()
45 | needs: manual_prepare
46 | runs-on: ubuntu-latest
47 | steps:
48 | - uses: actions/github@master
49 | env:
50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51 | with:
52 | args: comment "@${{ github.actor }} `shipjs prepare` fail"
53 |
--------------------------------------------------------------------------------
/packages/mordred-source-filesystem/src/index.ts:
--------------------------------------------------------------------------------
1 | import { resolve, join, relative } from 'path'
2 | import glob from 'fast-glob'
3 | import { fileToNode } from './to-node'
4 | import { PluginFactory } from 'mordred'
5 |
6 | const plugin: PluginFactory = (
7 | ctx,
8 | { path = 'content', include = '**/*.md' },
9 | ) => {
10 | const gql = ctx.gql
11 | const contentDir = resolve(ctx.cwd, path)
12 | const contentGlobs = [...(Array.isArray(include) ? include : [include])]
13 |
14 | return {
15 | name: 'source-filesystem',
16 |
17 | getSchema() {
18 | return gql`
19 | type FileNode {
20 | id: ID!
21 | type: String!
22 | mime: String
23 | createdAt: String!
24 | updatedAt: String!
25 | content: String!
26 | relativePath: String
27 | absolutePath: String
28 | slug: String
29 | }
30 |
31 | type FileConnection {
32 | nodes: [FileNode!]!
33 | }
34 |
35 | extend type Query {
36 | allFile: FileConnection!
37 | }
38 | `
39 | },
40 |
41 | getResolvers: () => relative(ctx.outDir, join(__dirname, 'resolvers')),
42 |
43 | async createNodes() {
44 | const files = await glob(contentGlobs, {
45 | cwd: contentDir,
46 | })
47 |
48 | const nodes = await Promise.all(
49 | files.map((filename) => {
50 | return fileToNode(filename, contentDir, ctx.mime.getType)
51 | }),
52 | )
53 |
54 | return nodes
55 | },
56 |
57 | async onInit() {
58 | if (process.env.NODE_ENV === 'development') {
59 | const { watch } = await import('chokidar')
60 | watch(contentGlobs, {
61 | cwd: contentDir,
62 | ignoreInitial: true,
63 | }).on('all', async () => {
64 | await ctx.createNodes()
65 | await ctx.writeAll()
66 | })
67 | }
68 | },
69 | }
70 | }
71 |
72 | export default plugin
73 |
--------------------------------------------------------------------------------
/packages/mordred-transformer-markdown/README.md:
--------------------------------------------------------------------------------
1 | # mordred-transformer-markdown
2 |
3 | Parse markdown files using [markdown-it](https://github.com/markdown-it/markdown-it).
4 |
5 | ## Table of Contents
6 |
7 |
8 |
9 |
10 |
11 | - [Install](#install)
12 | - [How to use](#how-to-use)
13 | - [How to query](#how-to-query)
14 | - [Query Markdown Headings](#query-markdown-headings)
15 | - [Pagination](#pagination)
16 | - [License](#license)
17 |
18 |
19 |
20 | ## Install
21 |
22 | ```bash
23 | yarn add mordred-transformer-markdown
24 | ```
25 |
26 | ## How to use
27 |
28 | In your `mordred.config.js`:
29 |
30 | ```js
31 | module.exports = {
32 | plugins: [
33 | // Typically after `mordred-source-filesystem`
34 | {
35 | resolve: 'mordred-transformer-markdown',
36 | options: {
37 | // All markdown-it options are supported
38 | }
39 | }
40 | ]
41 | }
42 | ```
43 |
44 | ## How to query
45 |
46 | A simple query:
47 |
48 | ```graphql
49 | {
50 | allMarkdown {
51 | node {
52 | html
53 | frontmatter {
54 | # Assumes you're using title in your frontmatter.
55 | title
56 | }
57 | }
58 | }
59 | }
60 | ```
61 |
62 | ### Query Markdown Headings
63 |
64 | ```graphql
65 | {
66 | allMarkdown {
67 | nodes {
68 | headings {
69 | depth
70 | text
71 | }
72 | }
73 | }
74 | }
75 | ```
76 |
77 | ### Pagination
78 |
79 | By default markdown nodes are ordered by `createdAt` in `DESC`, but you can also order them by any frontmatter key:
80 |
81 | ```graphql
82 | {
83 | allMarkdown(orderBy: frontmatter__title, skip: 5, limit: 5) {
84 | nodes {
85 | slug
86 | }
87 | pageInfo {
88 | hasNextPage
89 | hasPrevPage
90 | pageCount
91 | }
92 | }
93 | }
94 | ```
95 |
96 | ## License
97 |
98 | MIT © [EGOIST (Kevin Titor)](https://github.com/sponsor/egoist)
99 |
--------------------------------------------------------------------------------
/packages/mordred/src/index.ts:
--------------------------------------------------------------------------------
1 | import { join, relative } from 'path'
2 | import { outputFile } from 'fs-extra'
3 | import serialize from 'serialize-javascript'
4 | import mime from 'mime'
5 | import { mergeTypeDefs } from '@graphql-tools/merge'
6 | import { print } from 'graphql'
7 | import { Parser, TreeToTS } from 'graphql-zeus'
8 | import { graphqlTemplate, graphqlDefinitionTemplate } from './templates'
9 | import { Plugin } from './plugin'
10 | import { gql } from './gql'
11 |
12 | export { PluginFactory } from './plugin'
13 |
14 | type PluginConfigObject = {
15 | resolve: string
16 | options?: any
17 | }
18 |
19 | type MordredConfigPlugins = PluginConfigObject[]
20 |
21 | export type MordredConfig = {
22 | plugins?: MordredConfigPlugins
23 | }
24 | export class Mordred {
25 | config: MordredConfig
26 | cwd: string
27 | plugins: Plugin[]
28 | outDir: string
29 |
30 | gql = gql
31 | mime = mime
32 |
33 | nodes: Map