-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support for Markdown output (#90)
Co-authored-by: Lukasz Gornicki <lpgornicki@gmail.com> Co-authored-by: Aayush Kumar Sahu <aayushmau5@gmail.com>
- Loading branch information
1 parent
4e16ca1
commit 218aa5e
Showing
11 changed files
with
461 additions
and
26 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
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
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,76 @@ | ||
import {ChangeMarkdownGenerationConfig, MarkdownDropdownGenerationConfig} from '../types'; | ||
import convertToYAML from './output/convertToYAML'; | ||
|
||
/** | ||
* Groups an array of changes by their 'type' property | ||
* @param object The input object | ||
* @returns The grouped object | ||
*/ | ||
export function groupChangesByType(object: any): { string: [{ path: string, any: any }] } { | ||
return object.reduce((objectsByKeyValue: { [x: string]: any; }, obj: { [x: string]: any; }) => { | ||
const value = obj['type']; | ||
// eslint-disable-next-line security/detect-object-injection | ||
objectsByKeyValue[value] = (objectsByKeyValue[value] || []).concat(obj); | ||
return objectsByKeyValue; | ||
}, {}); | ||
} | ||
|
||
/** | ||
* Sets the first letter of a string to uppercase | ||
* @param s The input string | ||
* @returns The string with the first letter capitalised | ||
*/ | ||
export function capitaliseFirstLetter(s: string): string { | ||
return s[0].toUpperCase() + s.slice(1); | ||
} | ||
|
||
/** | ||
* Generates the Markdown list items for a single change | ||
* @param: config Configuration options for the generated markdown | ||
* @param config.change The object describing the change | ||
* @param config.markdownSubtype the format to display the dropdown data in | ||
* @returns The Markdown list describing the change | ||
*/ | ||
export function generateMarkdownForChange(config: ChangeMarkdownGenerationConfig): any { | ||
const toAppend: any[] = [`**Path**: \`${config.change.path}\``]; | ||
const listItem = {ul: [] as any[]}; | ||
|
||
for (const [label, value] of Object.entries(config.change)) { | ||
if (label !== 'path' && label !== 'type') { | ||
// if the value is an object, display within a dropdown | ||
if (typeof value === 'object') { | ||
listItem.ul.push(convertDataToDropdown({ | ||
label: capitaliseFirstLetter(label), | ||
data: value, | ||
markdownSubtype: config.markdownSubtype | ||
})); | ||
} else { | ||
listItem.ul.push(`**${capitaliseFirstLetter(label)}**: ${value}`); | ||
} | ||
} | ||
} | ||
|
||
toAppend.push(listItem); | ||
return toAppend; | ||
} | ||
|
||
/** | ||
* Converts the label and data to a markdown dropdown | ||
* @param config: Configuration options for the generated dropdown | ||
* @param config.label The summary / title | ||
* @param config.data The data to hide in dropdown | ||
* @param config.markdownSubtype the format to display the dropdown data in | ||
* @returns Markdown string with the label as a summary and the data formatted as JSON code | ||
*/ | ||
export function convertDataToDropdown(config: MarkdownDropdownGenerationConfig): string { | ||
const displayData = config.markdownSubtype === 'json' ? JSON.stringify(config.data, null, 2) : convertToYAML(config.data); | ||
|
||
return `<details> | ||
<summary> ${config.label} </summary> | ||
\`\`\`${config.markdownSubtype} | ||
${displayData} | ||
\`\`\` | ||
</details> | ||
`; | ||
} |
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,36 @@ | ||
import json2md from 'json2md'; | ||
import { | ||
capitaliseFirstLetter, | ||
generateMarkdownForChange, | ||
groupChangesByType | ||
} from '../MarkdownHelpers'; | ||
import {MarkdownSubtype} from '../../types'; | ||
|
||
/** | ||
* Converts the diff to Markdown | ||
* @param object The input object | ||
* @param markdownSubtype the format to display the dropdown data in | ||
* @returns Markdown output | ||
*/ | ||
export default function convertToMarkdown(object: any, markdownSubtype: MarkdownSubtype): string { | ||
if (Object.prototype.hasOwnProperty.call(object, 'changes')) { | ||
object = object.changes; | ||
} | ||
|
||
const changeTypeGroups = groupChangesByType(object); | ||
|
||
const markdownStructure = []; | ||
|
||
for (const [changeType, changes] of Object.entries(changeTypeGroups)) { | ||
markdownStructure.push({h2: capitaliseFirstLetter(changeType)}); | ||
const outerList = {ul: [] as any[]}; | ||
|
||
for (const change of changes) { | ||
outerList.ul.push(...generateMarkdownForChange({change, markdownSubtype})); | ||
} | ||
|
||
markdownStructure.push(outerList); | ||
} | ||
|
||
return json2md(markdownStructure); | ||
} |
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,18 +1,21 @@ | ||
import { OutputType } from '../../types'; | ||
import {FormatterConfig} from '../../types'; | ||
import convertToYAML from './convertToYAML'; | ||
import convertToMarkdown from './convertToMarkdown'; | ||
|
||
/** | ||
* Converts diff data to the specified format | ||
* @param data The diff data | ||
* @param config: Configuration options for the target format | ||
* @param config.data The diff data | ||
* @param config.outputType The intended type of the output | ||
* @param config.markdownSubtype the format to display the dropdown data in | ||
* @returns formatted diff output | ||
*/ | ||
export default function toProperFormat<T>( | ||
data: T, | ||
outputType: OutputType | ||
): T | string { | ||
if (outputType === 'yaml' || outputType === 'yml') { | ||
return convertToYAML(data); | ||
export default function toProperFormat<T>(config: FormatterConfig<T>): T | string { | ||
if (config.outputType === 'yaml' || config.outputType === 'yml') { | ||
return convertToYAML(config.data); | ||
} else if (config.outputType === 'markdown' || config.outputType === 'md') { | ||
return convertToMarkdown(config.data, config.markdownSubtype); | ||
} | ||
|
||
return data; | ||
return config.data; | ||
} |
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
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
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
Oops, something went wrong.