Skip to content

Commit

Permalink
feat: add mordred-source-github-issues
Browse files Browse the repository at this point in the history
  • Loading branch information
egoist committed Sep 2, 2020
1 parent 4fa56b8 commit 959132d
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 43 deletions.
8 changes: 4 additions & 4 deletions packages/mordred-source-filesystem/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ const plugin: PluginFactory = (
getSchema() {
return gql`
type FileNode {
id: String!
id: ID!
type: String!
mime: String
createdAt: String!
updatedAt: String!
content: String!
relativePath: String!
absolutePath: String!
slug: String!
relativePath: String
absolutePath: String
slug: String
}
type FileConnection {
Expand Down
20 changes: 20 additions & 0 deletions packages/mordred-source-github-issues/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"version": "0.2.0",
"name": "mordred-source-github-issues",
"files": [
"dist"
],
"main": "dist/index.js",
"license": "MIT",
"scripts": {
"build": "tsc",
"watch": "tsc --watch",
"prepublishOnly": "yarn build"
},
"dependencies": {
"axios": "0.20.0"
},
"peerDependencies": {
"mordred": "^0.1.0"
}
}
33 changes: 33 additions & 0 deletions packages/mordred-source-github-issues/src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import axios from 'axios'

export const GithubIssueNodeType = 'GithubIssue'

export const fetchIssues = async ({
token,
user,
repo,
}: {
token?: string
user: string
repo: string
}) => {
const { data } = await axios.get(
`https://api.github.com/repos/${user}/${repo}/issues?per_page=100`,
{
headers: {
Authorization: token ? `Bearer ${token}` : null,
},
},
)
return data.map((item: any) => ({
id: item.id,
type: GithubIssueNodeType,
mime: 'text/markdown',
title: item.title,
content: item.body,
createdAt: item.created_at,
updatedAt: item.updated_at,
comments: item.comments,
labels: item.labels,
}))
}
51 changes: 51 additions & 0 deletions packages/mordred-source-github-issues/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { relative, join } from 'path'
import { PluginFactory } from 'mordred'
import { fetchIssues } from './api'

const plugin: PluginFactory<{ token?: string; user: string; repo: string }> = (
ctx,
{ token, user, repo },
) => {
const gql = ctx.gql
return {
name: 'source-github-issues',

getSchema() {
return gql`
type GithubIssueNode {
id: ID!
mime: String!
title: String
content: String!
createdAt: String!
updatedAt: String!
comments: Int
labels: [GithubIssueNodeLabel!]
}
type GithubIssueNodeLabel {
id: ID!
name: String!
color: String!
description: String
}
type GithubIssueConnection {
nodes: [GithubIssueNode!]!
}
extend type Query {
allGithubIssue: GithubIssueConnection
}
`
},

createNodes() {
return fetchIssues({ token, user, repo })
},

getResolvers: () => relative(ctx.outDir, join(__dirname, 'resolvers')),
}
}

export default plugin
14 changes: 14 additions & 0 deletions packages/mordred-source-github-issues/src/resolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { GithubIssueNodeType } from './api'

export default ({ nodes }: { nodes: any[] }) => {
return {
Query: {
allGithubIssue() {
const result = nodes.filter((node) => node.type === GithubIssueNodeType)
return {
nodes: result,
}
},
},
}
}
7 changes: 7 additions & 0 deletions packages/mordred-source-github-issues/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist"
},
"include": ["src/**/*"]
}
38 changes: 32 additions & 6 deletions packages/mordred-transformer-markdown/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,30 @@ import { PluginFactory } from 'mordred'
import grayMatter from 'gray-matter'
import { markdownPluginHeadings } from './markdown-plugin-headings'

const plugin: PluginFactory = (ctx, options) => {
const plugin: PluginFactory<{
inputNodeTypes?: string[]
[k: string]: any
}> = (ctx, options) => {
const frontmatterKeys: Set<string> = new Set()
const inputNodeTypes: Set<string> = new Set()
const gql = ctx.gql

return {
name: 'transformer-markdown',

getSchema() {
const fileSchema = ctx.getPluginSchema('source-filesystem')
const matched = /type\s+FileNode\s+{([^}]+)}/.exec(fileSchema)
const FileNode = matched && matched[1]
getSchema(typeDefs) {
const types = typeDefs.join('\n')
const extraNodeFields: Array<string | null> = []

for (const type of inputNodeTypes) {
const re = new RegExp(`type\\s+${type}\\s+{([^}]+)}`)
const m = re.exec(types)
if (m) {
extraNodeFields.push(m[1])
} else {
extraNodeFields.push(null)
}
}

const MarkdownFrontMatter =
frontmatterKeys.size === 0
Expand Down Expand Up @@ -48,14 +61,23 @@ const plugin: PluginFactory = (ctx, options) => {
}
type MarkdownNode {
${FileNode}
html: String!
headings: [MarkdownNodeHeading!]!
frontmatter: ${
frontmatterKeys.size === 0 ? 'JSON' : 'MarkdownFrontMatter'
}
}
${extraNodeFields
.map((fields) => {
return `
extend type MarkdownNode {
${fields}
}`
})
.join('\n')}
type MarkdownPageInfo {
hasPrevPage: Boolean!
hasNextPage: Boolean!
Expand All @@ -78,6 +100,9 @@ const plugin: PluginFactory = (ctx, options) => {
getResolvers: () => relative(ctx.outDir, join(__dirname, 'resolvers')),

createNodes() {
frontmatterKeys.clear()
inputNodeTypes.clear()

const nodes = [...ctx.nodes.values()]
.filter((node) => {
return node.mime === 'text/markdown'
Expand All @@ -87,6 +112,7 @@ const plugin: PluginFactory = (ctx, options) => {
for (const key of Object.keys(data)) {
frontmatterKeys.add(key)
}
inputNodeTypes.add(`${node.type}Node`)
const Markdown = require('markdown-it')
const md = new Markdown({
html: options.html !== false,
Expand Down
45 changes: 25 additions & 20 deletions packages/mordred/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class Mordred {
async writeGraphQL() {
try {
const outContent = graphqlTemplate({
typeDefs: this.typeDefs,
plugins: this.plugins,
})

Expand All @@ -76,21 +77,31 @@ export class Mordred {
await outputFile(outPath, outContent, 'utf8')
}

get typeDefs() {
const types: string[] = this.plugins
.filter((plugin) => plugin.getSchema)
.reduce(
(result, plugin) => {
result.push(plugin.getSchema ? plugin.getSchema(result) : '')
return result
},
[
`
scalar JSON
type Query {
hello: String
}
`,
],
)

const typeDefs = print(mergeTypeDefs(types))
return typeDefs
}

async writeZeus() {
const types: string[] = [
`
scalar JSON
type Query {
hello: String
}
`,
...this.plugins
.filter((plugin) => plugin.getSchema)
.map((plugin) => (plugin.getSchema ? plugin.getSchema() : '')),
]
const typeDefs = mergeTypeDefs(types)
const tree = Parser.parse(print(typeDefs))
const tree = Parser.parse(this.typeDefs)
const jsDefinition = TreeToTS.javascript(tree)
await Promise.all([
outputFile(
Expand All @@ -116,12 +127,6 @@ export class Mordred {
])
}

getPluginSchema(name: string) {
const plugin = this.plugins.find((plugin) => plugin.name === name)

return plugin && plugin.getSchema ? plugin.getSchema() : ''
}

async init() {
for (const plugin of this.plugins) {
if (plugin.onInit) {
Expand Down
4 changes: 2 additions & 2 deletions packages/mordred/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type Plugin = {

onInit?: () => void | Promise<void>

getSchema?: () => string
getSchema?: (typeDefs: string[]) => string

getResolvers?: () => string

Expand All @@ -14,5 +14,5 @@ export type Plugin = {

export type PluginFactory<TOptions = any> = (
context: Mordred,
options: TOptions
options: TOptions,
) => Plugin
12 changes: 1 addition & 11 deletions packages/mordred/templates/graphql.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,7 @@ import { GraphQLJSON } from 'graphql-type-json'
import { Thunder } from './zeus'
import nodes from './nodes'

export const typeDefs = [`
scalar JSON

type Query {
hello: String
}
`]
export const typeDefs = `<%= typeDefs %>`

export const resolvers = [{
JSON: GraphQLJSON
Expand All @@ -27,10 +21,6 @@ const resolverArgs = {

<% plugins.forEach(function (plugin, index) { %>
<% if (plugin.getSchema) { %>
typeDefs.push(`<%- plugin.getSchema() %>`)
<% } %>
<% if (plugin.getResolvers) { %>
import getResolvers_<%= index %> from '<%= plugin.getResolvers().replace(/\\/g, '') %>'
resolvers.push(getResolvers_<%= index %>(resolverArgs))
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3082,6 +3082,13 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==

axios@0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd"
integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==
dependencies:
follow-redirects "^1.10.0"

axios@^0.19.0:
version "0.19.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
Expand Down Expand Up @@ -5306,6 +5313,11 @@ follow-redirects@1.5.10:
dependencies:
debug "=3.1.0"

follow-redirects@^1.10.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==

for-in@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
Expand Down

0 comments on commit 959132d

Please sign in to comment.