-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
118 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,156 +1,88 @@ | ||
import { request } from '@octokit/request'; | ||
import fs from 'fs'; | ||
|
||
type LabelType = { | ||
name: string; | ||
color: string; | ||
}; | ||
|
||
type IssueOriginType = { | ||
html_url: string; | ||
title: string; | ||
labels: LabelType[]; | ||
updated_at: string; | ||
comments: string; | ||
}; | ||
|
||
type IssueType = Omit<IssueOriginType, 'html_url' | 'labels'> & { | ||
url: string; | ||
tags: LabelType[]; | ||
}; | ||
|
||
const LF = '\n'; | ||
const ParagraphDividingLine = `${LF}${LF}`; | ||
|
||
const paragraph = (content: string[]) => { | ||
return content.join(ParagraphDividingLine); | ||
}; | ||
|
||
const heading = ({ title, level }: Pick<IssueType, 'title'> & { level: number }) => { | ||
return `${'#'.repeat(level)} ${title}`; | ||
}; | ||
|
||
const blockquote = (text: string) => { | ||
return `> ${text}`; | ||
}; | ||
|
||
const link = (title: IssueType['title'], url: IssueType['url']) => { | ||
return `[${title}](${url})`; | ||
}; | ||
|
||
const getColorTag = (text: string, color: string) => { | ||
// TODO add link to issue label page | ||
const baseUrl = `https://img.shields.io/badge/-${text}-${color}`; | ||
|
||
return `![${text}](${baseUrl})`; | ||
}; | ||
|
||
const tagsSplit = (tags: LabelType[]) => { | ||
return tags?.map((item) => getColorTag(item.name, item.color)).join(' '); | ||
}; | ||
|
||
const time = (timeStr: string) => { | ||
return new Date(timeStr).toLocaleDateString('zh-CN'); | ||
}; | ||
|
||
const now = () => { | ||
return `${new Date().toLocaleDateString()}`; | ||
}; | ||
|
||
const baseColumns = [ | ||
{ | ||
label: '标题', | ||
dataIndex: 'title', | ||
render: (text: string, { url }: { url: string }) => link(text, url), | ||
}, | ||
{ | ||
label: '类型', | ||
dataIndex: 'tags', | ||
render: (tags: { name: string; color: string }[]) => tagsSplit(tags), | ||
}, | ||
{ | ||
label: '更新时间', | ||
dataIndex: 'updated_at', | ||
render: (updated_at: string) => time(updated_at), | ||
}, | ||
{ | ||
label: '评论数', | ||
dataIndex: 'comments', | ||
}, | ||
]; | ||
|
||
const arr2TableRow = (data: string[]) => { | ||
return `|${data.join('|')}|`; | ||
}; | ||
|
||
const getTable = <T>( | ||
data: T[], | ||
columns: { | ||
label: string; | ||
dataIndex: string; | ||
render?: (text: any, data: T) => any; | ||
}[] | ||
) => { | ||
const header = arr2TableRow(columns?.map((item) => item.label)); | ||
const divider = arr2TableRow(Array(columns?.length).fill('---')); | ||
|
||
const renderData = data?.map((item) => | ||
arr2TableRow( | ||
columns?.map((column) => { | ||
if (column.render) { | ||
return column.render(item[column.dataIndex], item); | ||
} | ||
|
||
return item[column.dataIndex]; | ||
}) | ||
) | ||
); | ||
import { md, createMd } from '@nmsn/md-maker'; | ||
import { now, baseColumns } from './utils'; | ||
|
||
type AsyncReturnType<T extends (...args: any) => any> = T extends (...args: any) => Promise<infer R> | ||
? R | ||
: any; | ||
|
||
const formatMd = (data: AsyncReturnType<typeof requestGithubIssues>, title: string) => | ||
md([ | ||
{ | ||
type: 'h1', | ||
params: title, | ||
}, | ||
{ | ||
type: 'blockquote', | ||
params: `更新时间:${now()}`, | ||
}, | ||
{ | ||
type: 'table', | ||
params: { | ||
header: baseColumns.map((item) => item.label), | ||
content: data.map((item) => { | ||
return baseColumns?.map((column) => { | ||
if (column.render) { | ||
return column.render(item[column.dataIndex], item); | ||
} | ||
|
||
return item[column.dataIndex]; | ||
}); | ||
}), | ||
}, | ||
}, | ||
]); | ||
|
||
return [header, divider, ...renderData].join(LF); | ||
// https://docs.github.com/zh/rest/issues/issues | ||
type RequestParamsType = { | ||
owner: string; | ||
repo: string; | ||
state?: 'open' | 'closed' | 'all'; | ||
sort?: 'created' | 'updated' | 'comments'; | ||
direction?: 'asc' | 'desc'; | ||
per_page?: number; | ||
page?: number; | ||
}; | ||
|
||
const dealResult = (data = [], inputTitle: string) => { | ||
const origin = (data as IssueOriginType[]).map((item) => { | ||
const { title, html_url, labels, updated_at, comments } = item; | ||
|
||
const tags = labels?.map((item) => ({ name: item.name, color: item.color })) || []; | ||
return { title, url: html_url, tags, updated_at, comments }; | ||
const requestGithubIssues = async ({ | ||
owner, | ||
repo, | ||
state = 'open', | ||
sort = 'created', | ||
direction = 'desc', | ||
per_page = 100, | ||
page = 1, | ||
}: RequestParamsType) => { | ||
const { data = [] } = await request('GET /repos/{owner}/{repo}/issues', { | ||
owner, | ||
repo, | ||
state, | ||
sort, | ||
direction, | ||
per_page, | ||
page, | ||
}); | ||
|
||
const content = getTable(origin, baseColumns); | ||
|
||
const md = paragraph([ | ||
heading({ | ||
title: inputTitle, | ||
level: 1, | ||
}), | ||
blockquote(`更新时间:${now()}`), | ||
content, | ||
]); | ||
|
||
return md; | ||
return data; | ||
}; | ||
|
||
const script = async ({ | ||
repo, | ||
user, | ||
fileName = 'README', | ||
title: inputTitle = 'Collection', | ||
title = 'Collection', | ||
}: { | ||
repo: string; | ||
user: string; | ||
title?: string; | ||
fileName?: string; | ||
}) => { | ||
const result = await request('GET /repos/{owner}/{repo}/issues?per_page=1', { | ||
const data = await requestGithubIssues({ | ||
owner: user, | ||
repo, | ||
}); | ||
|
||
const { data = [] } = result || {}; | ||
const md = dealResult(data, inputTitle); | ||
|
||
fs.writeFileSync(`./${fileName}.md`, md); | ||
createMd(`./${fileName}.md`, formatMd(data, title)); | ||
}; | ||
|
||
export default script; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { descriptor } from '@nmsn/md-maker'; | ||
|
||
export type LabelType = { | ||
name: string; | ||
color: string; | ||
}; | ||
|
||
const createLabel = (text: string, color: string) => { | ||
const baseUrl = `https://img.shields.io/badge/-${text}-${color}`; | ||
return `![${text}](${baseUrl})`; | ||
}; | ||
|
||
const displayLabels = (tags: LabelType[]) => { | ||
return tags?.map((item) => createLabel(item.name, item.color)).join(' '); | ||
}; | ||
|
||
const time = (timeStr: string) => { | ||
return new Date(timeStr).toLocaleDateString('zh-CN'); | ||
}; | ||
|
||
export const now = () => { | ||
return `${new Date().toLocaleDateString()}`; | ||
}; | ||
|
||
export const baseColumns = [ | ||
{ | ||
label: '标题', | ||
dataIndex: 'title', | ||
render: (title: string, { html_url }: { html_url: string }) => | ||
descriptor.link({ title, url: html_url }), | ||
}, | ||
{ | ||
label: '类型', | ||
dataIndex: 'labels', | ||
render: (tags: { name: string; color: string }[]) => displayLabels(tags), | ||
}, | ||
{ | ||
label: '更新时间', | ||
dataIndex: 'updated_at', | ||
render: (updated_at: string) => time(updated_at), | ||
}, | ||
{ | ||
label: '评论数', | ||
dataIndex: 'comments', | ||
}, | ||
]; |