docs: add util to generate clean markdown for a file (#11303)
This commit is contained in:
1 parent
3c51709daf
commit
604f46f8bc
23 files changed
+832
-37
No files matched your search
@@ -0,0 +1,20 @@
|
||||
import { UnistNode, UnistTree } from "types"
|
||||
import { Transformer } from "unified"
|
||||
|
||||
type Options = {
|
||||
url: string
|
||||
}
|
||||
|
||||
export function addUrlToRelativeLink(options: Options): Transformer {
|
||||
return async (tree) => {
|
||||
const { visit } = await import("unist-util-visit")
|
||||
|
||||
visit(tree as UnistTree, "link", (node: UnistNode) => {
|
||||
if (!node.url || !node.url.startsWith("/")) {
|
||||
return
|
||||
}
|
||||
|
||||
node.url = `${options.url}${node.url}`
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@ import type {
|
||||
UnistNode,
|
||||
UnistNodeWithData,
|
||||
UnistTree,
|
||||
} from "./types/index.js"
|
||||
} from "types"
|
||||
import type { VFile } from "vfile"
|
||||
import { parseCrossProjectLink } from "./utils/cross-project-link-utils.js"
|
||||
import { SlugChange } from "types"
|
||||
import getAttribute from "./utils/get-attribute.js"
|
||||
import { estreeToJs } from "./utils/estree-to-js.js"
|
||||
import { estreeToJs } from "docs-utils"
|
||||
import { performActionOnLiteral } from "./utils/perform-action-on-literal.js"
|
||||
import { MD_LINK_REGEX } from "./constants.js"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Transformer } from "unified"
|
||||
import type { CloudinaryConfig, UnistNode, UnistTree } from "./types/index.js"
|
||||
import type { CloudinaryConfig, UnistNode, UnistTree } from "types"
|
||||
|
||||
const cloudinaryImageRegex =
|
||||
/^https:\/\/res.cloudinary.com\/.*\/upload\/v[0-9]+\/(?<imageId>.*)$/
|
||||
|
||||
@@ -4,8 +4,8 @@ import type {
|
||||
UnistNode,
|
||||
UnistNodeWithData,
|
||||
UnistTree,
|
||||
} from "./types/index.js"
|
||||
import { estreeToJs } from "./utils/estree-to-js.js"
|
||||
} from "types"
|
||||
import { estreeToJs } from "docs-utils"
|
||||
import getAttribute from "./utils/get-attribute.js"
|
||||
import { performActionOnLiteral } from "./utils/perform-action-on-literal.js"
|
||||
|
||||
@@ -48,6 +48,14 @@ function linkElmFixer(node: UnistNode, options: CrossProjectLinksOptions) {
|
||||
node.properties.href = matchAndFixLinks(node.properties.href, options)
|
||||
}
|
||||
|
||||
function linkNodeFixer(node: UnistNode, options: CrossProjectLinksOptions) {
|
||||
if (!node.url) {
|
||||
return
|
||||
}
|
||||
|
||||
node.url = matchAndFixLinks(node.url, options)
|
||||
}
|
||||
|
||||
function componentFixer(
|
||||
node: UnistNodeWithData,
|
||||
options: CrossProjectLinksOptions
|
||||
@@ -128,20 +136,23 @@ export function crossProjectLinksPlugin(
|
||||
|
||||
visit(
|
||||
tree as UnistTree,
|
||||
["element", "mdxJsxFlowElement"],
|
||||
["element", "mdxJsxFlowElement", "link"],
|
||||
(node: UnistNode) => {
|
||||
const isComponent =
|
||||
node.name && allowedComponentNames.includes(node.name)
|
||||
const isLink = node.tagName === "a" && node.properties?.href
|
||||
if (!isComponent && !isLink) {
|
||||
const isLinkElm = node.tagName === "a" && node.properties?.href
|
||||
const isLinkNode = node.type === "link" && node.url
|
||||
if (!isComponent && !isLinkElm && !isLinkNode) {
|
||||
return
|
||||
}
|
||||
|
||||
if (isComponent) {
|
||||
componentFixer(node as UnistNodeWithData, options)
|
||||
} else if (isLinkElm) {
|
||||
linkElmFixer(node, options)
|
||||
} else {
|
||||
linkNodeFixer(node, options)
|
||||
}
|
||||
|
||||
linkElmFixer(node, options)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
export * from "./add-url-to-relative-link.js"
|
||||
export * from "./broken-link-checker.js"
|
||||
export * from "./cloudinary-img.js"
|
||||
export * from "./cross-project-links.js"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from "path"
|
||||
import type { Transformer } from "unified"
|
||||
import type { LocalLinkOptions, UnistNode, UnistTree } from "./types/index.js"
|
||||
import type { LocalLinkOptions, UnistNode, UnistTree } from "types"
|
||||
import { fixLinkUtil } from "./index.js"
|
||||
|
||||
export function localLinksRehypePlugin(options: LocalLinkOptions): Transformer {
|
||||
@@ -25,16 +25,28 @@ export function localLinksRehypePlugin(options: LocalLinkOptions): Transformer {
|
||||
""
|
||||
)
|
||||
const appsPath = basePath || path.join(file.cwd, "app")
|
||||
visit(tree as UnistTree, "element", (node: UnistNode) => {
|
||||
if (node.tagName !== "a" || !node.properties?.href?.match(/page\.mdx?/)) {
|
||||
return
|
||||
}
|
||||
visit(tree as UnistTree, ["element", "link"], (node: UnistNode) => {
|
||||
if (node.tagName === "a") {
|
||||
if (!node.properties?.href?.match(/page\.mdx?/)) {
|
||||
return
|
||||
}
|
||||
|
||||
node.properties.href = fixLinkUtil({
|
||||
currentPageFilePath,
|
||||
linkedPath: node.properties.href,
|
||||
appsPath,
|
||||
})
|
||||
node.properties.href = fixLinkUtil({
|
||||
currentPageFilePath,
|
||||
linkedPath: node.properties.href,
|
||||
appsPath,
|
||||
})
|
||||
} else if (node.type === "link") {
|
||||
if (!node.url?.match(/page\.mdx?/)) {
|
||||
return
|
||||
}
|
||||
|
||||
node.url = fixLinkUtil({
|
||||
currentPageFilePath,
|
||||
linkedPath: node.url,
|
||||
appsPath,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from "path"
|
||||
import type { Transformer } from "unified"
|
||||
import type { RawSidebarItem } from "types"
|
||||
import type { UnistTree } from "./types/index.js"
|
||||
import type { UnistTree } from "types"
|
||||
|
||||
export function pageNumberRehypePlugin({
|
||||
sidebar,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Transformer } from "unified"
|
||||
import { ComponentLinkFixerOptions } from "./types/index.js"
|
||||
import { ComponentLinkFixerOptions } from "types"
|
||||
import { componentLinkFixer } from "./utils/component-link-fixer.js"
|
||||
|
||||
export function prerequisitesLinkFixerPlugin(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Transformer } from "unified"
|
||||
import { UnistNode } from "./types/index.js"
|
||||
import { UnistNode } from "types"
|
||||
|
||||
const ALLOWED_NODE_NAMES = ["note", "tip", "info", "warning"]
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Transformer } from "unified"
|
||||
import { ComponentLinkFixerOptions } from "./types/index.js"
|
||||
import { ComponentLinkFixerOptions } from "types"
|
||||
import { componentLinkFixer } from "./utils/component-link-fixer.js"
|
||||
|
||||
export function typeListLinkFixerPlugin(
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
import { Node } from "unist-builder"
|
||||
|
||||
export interface UnistNode extends Node {
|
||||
type: string
|
||||
name?: string
|
||||
tagName?: string
|
||||
value?: string
|
||||
properties?: {
|
||||
[key: string]: string
|
||||
}
|
||||
attributes?: {
|
||||
name: string
|
||||
value: unknown
|
||||
type?: string
|
||||
}[]
|
||||
children?: UnistNode[]
|
||||
}
|
||||
|
||||
export type ArrayExpression = {
|
||||
type: "ArrayExpression"
|
||||
elements: Expression[]
|
||||
}
|
||||
|
||||
export type ObjectExpression = {
|
||||
type: "ObjectExpression"
|
||||
properties: AttributeProperty[]
|
||||
}
|
||||
|
||||
export type LiteralExpression = {
|
||||
type: "Literal"
|
||||
value: unknown
|
||||
raw: string
|
||||
}
|
||||
|
||||
export type Expression =
|
||||
| {
|
||||
type: string
|
||||
}
|
||||
| ArrayExpression
|
||||
| ObjectExpression
|
||||
| LiteralExpression
|
||||
|
||||
export interface Estree {
|
||||
body?: {
|
||||
type?: string
|
||||
expression?: Expression
|
||||
}[]
|
||||
}
|
||||
|
||||
export interface UnistNodeWithData extends UnistNode {
|
||||
attributes: {
|
||||
name: string
|
||||
value:
|
||||
| {
|
||||
data?: {
|
||||
estree?: Estree
|
||||
}
|
||||
value?: string
|
||||
}
|
||||
| string
|
||||
type?: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export interface AttributeProperty {
|
||||
key: {
|
||||
name?: string
|
||||
value?: string
|
||||
raw: string
|
||||
}
|
||||
value:
|
||||
| {
|
||||
type: "Literal"
|
||||
value: unknown
|
||||
raw: string
|
||||
}
|
||||
| {
|
||||
type: "JSXElement"
|
||||
// TODO add correct type if necessary
|
||||
openingElement: unknown
|
||||
}
|
||||
| ArrayExpression
|
||||
}
|
||||
|
||||
export interface UnistTree extends Node {
|
||||
children: UnistNode[]
|
||||
}
|
||||
|
||||
export declare type CloudinaryConfig = {
|
||||
cloudName?: string
|
||||
flags?: string[]
|
||||
resize?: {
|
||||
action: string
|
||||
width?: number
|
||||
height?: number
|
||||
aspectRatio?: string
|
||||
}
|
||||
roundCorners?: number
|
||||
}
|
||||
|
||||
export declare type CrossProjectLinksOptions = {
|
||||
baseUrl: string
|
||||
projectUrls?: {
|
||||
[k: string]: {
|
||||
url: string
|
||||
path?: string
|
||||
}
|
||||
}
|
||||
useBaseUrl?: boolean
|
||||
}
|
||||
|
||||
export declare type BrokenLinkCheckerOptions = {
|
||||
crossProjects: {
|
||||
[k: string]: {
|
||||
projectPath: string
|
||||
contentPath?: string
|
||||
hasGeneratedSlugs?: boolean
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export declare type ComponentLinkFixerLinkType = "md" | "value"
|
||||
|
||||
export declare type ComponentLinkFixerOptions = {
|
||||
filePath?: string
|
||||
basePath?: string
|
||||
checkLinksType: ComponentLinkFixerLinkType
|
||||
}
|
||||
|
||||
export declare type LocalLinkOptions = {
|
||||
filePath?: string
|
||||
basePath?: string
|
||||
}
|
||||
|
||||
export type ExpressionJsVarItem = {
|
||||
original: AttributeProperty
|
||||
data?: unknown
|
||||
}
|
||||
|
||||
export type ExpressionJsVarLiteral = {
|
||||
original: {
|
||||
type: "Literal"
|
||||
value: unknown
|
||||
raw: string
|
||||
}
|
||||
data?: unknown
|
||||
}
|
||||
|
||||
export type ExpressionJsVarObj = {
|
||||
[k: string]: ExpressionJsVarItem | ExpressionJsVar | ExpressionJsVar[]
|
||||
}
|
||||
|
||||
export type ExpressionJsVar = ExpressionJsVarObj | ExpressionJsVarLiteral
|
||||
@@ -1,10 +1,9 @@
|
||||
import path from "path"
|
||||
import { Transformer } from "unified"
|
||||
import { UnistNodeWithData, UnistTree } from "../types/index.js"
|
||||
import { UnistNodeWithData, UnistTree, ComponentLinkFixerOptions } from "types"
|
||||
import { FixLinkOptions, fixLinkUtil } from "../index.js"
|
||||
import getAttribute from "../utils/get-attribute.js"
|
||||
import { estreeToJs } from "../utils/estree-to-js.js"
|
||||
import { ComponentLinkFixerOptions } from "../types/index.js"
|
||||
import { estreeToJs } from "docs-utils"
|
||||
import { performActionOnLiteral } from "./perform-action-on-literal.js"
|
||||
import { MD_LINK_REGEX } from "../constants.js"
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/* eslint-disable no-case-declarations */
|
||||
import {
|
||||
ArrayExpression,
|
||||
Estree,
|
||||
Expression,
|
||||
ExpressionJsVar,
|
||||
ExpressionJsVarLiteral,
|
||||
LiteralExpression,
|
||||
ObjectExpression,
|
||||
} from "../types/index.js"
|
||||
|
||||
export function estreeToJs(estree: Estree) {
|
||||
// TODO improve on this utility. Currently it's implemented to work
|
||||
// for specific use cases as we don't have a lot of info on other
|
||||
// use cases.
|
||||
if (
|
||||
!estree.body?.length ||
|
||||
estree.body[0].type !== "ExpressionStatement" ||
|
||||
!estree.body[0].expression
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
return expressionToJs(estree.body[0].expression)
|
||||
}
|
||||
|
||||
function expressionToJs(
|
||||
expression: Expression
|
||||
): ExpressionJsVar | ExpressionJsVar[] | undefined {
|
||||
switch (expression.type) {
|
||||
case "ArrayExpression":
|
||||
const arrVar: ExpressionJsVar[] = []
|
||||
;(expression as ArrayExpression).elements.forEach((elm) => {
|
||||
const elmJsVar = expressionToJs(elm)
|
||||
if (!elmJsVar) {
|
||||
return
|
||||
}
|
||||
if (Array.isArray(elmJsVar)) {
|
||||
arrVar.push(...elmJsVar)
|
||||
} else {
|
||||
arrVar.push(elmJsVar)
|
||||
}
|
||||
})
|
||||
return arrVar
|
||||
case "ObjectExpression":
|
||||
const objVar: ExpressionJsVar = {}
|
||||
;(expression as ObjectExpression).properties.forEach((property) => {
|
||||
const keyName = property.key.name ?? property.key.value
|
||||
|
||||
if (!keyName) {
|
||||
return
|
||||
}
|
||||
const jsVal = expressionToJs(property.value)
|
||||
if (!jsVal) {
|
||||
return
|
||||
}
|
||||
|
||||
objVar[keyName] = jsVal
|
||||
})
|
||||
return objVar
|
||||
case "Literal":
|
||||
return {
|
||||
original: expression,
|
||||
data: (expression as LiteralExpression).value,
|
||||
} as ExpressionJsVarLiteral
|
||||
case "JSXElement":
|
||||
// ignore JSXElements
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ExpressionJsVarLiteral, ExpressionJsVarObj } from "../types/index.js"
|
||||
|
||||
export function isExpressionJsVarLiteral(
|
||||
expression: unknown
|
||||
): expression is ExpressionJsVarLiteral {
|
||||
return (
|
||||
typeof expression === "object" &&
|
||||
expression !== null &&
|
||||
Object.hasOwn(expression, "original")
|
||||
)
|
||||
}
|
||||
|
||||
export function isExpressionJsVarObj(
|
||||
expression: unknown
|
||||
): expression is ExpressionJsVarObj {
|
||||
return (
|
||||
typeof expression === "object" &&
|
||||
expression !== null &&
|
||||
!Object.hasOwn(expression, "original")
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { UnistNodeWithData } from "../types/index.js"
|
||||
import { UnistNodeWithData } from "types"
|
||||
|
||||
export default function getAttribute(
|
||||
node: UnistNodeWithData,
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { ExpressionJsVar, ExpressionJsVarLiteral } from "../types/index.js"
|
||||
import {
|
||||
isExpressionJsVarLiteral,
|
||||
isExpressionJsVarObj,
|
||||
} from "./expression-is-utils.js"
|
||||
import { ExpressionJsVar, ExpressionJsVarLiteral } from "types"
|
||||
import { isExpressionJsVarLiteral, isExpressionJsVarObj } from "docs-utils"
|
||||
|
||||
export const performActionOnLiteral = (
|
||||
item: ExpressionJsVar[] | ExpressionJsVar,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Transformer } from "unified"
|
||||
import { ComponentLinkFixerOptions } from "./types/index.js"
|
||||
import { ComponentLinkFixerOptions } from "types"
|
||||
import { componentLinkFixer } from "./utils/component-link-fixer.js"
|
||||
|
||||
export function workflowDiagramLinkFixerPlugin(
|
||||
|
||||
Reference in new issue
Block a user