forked from medusajs/medusa
-
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.
docs: handle Card and CardList components in cross-links plugin (medu…
- Loading branch information
1 parent
490586f
commit 1160a34
Showing
6 changed files
with
364 additions
and
116 deletions.
There are no files selected for viewing
151 changes: 124 additions & 27 deletions
151
www/packages/remark-rehype-plugins/src/cross-project-links.ts
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,45 +1,142 @@ | ||
/* eslint-disable no-case-declarations */ | ||
import type { Transformer } from "unified" | ||
import type { | ||
CrossProjectLinksOptions, | ||
ExpressionJsVar, | ||
UnistNode, | ||
UnistNodeWithData, | ||
UnistTree, | ||
} from "./types/index.js" | ||
import { estreeToJs } from "./utils/estree-to-js.js" | ||
import getAttribute from "./utils/get-attribute.js" | ||
import { | ||
isExpressionJsVarLiteral, | ||
isExpressionJsVarObj, | ||
} from "./utils/expression-is-utils.js" | ||
|
||
const PROJECT_REGEX = /^!(?<area>[\w-]+)!/ | ||
|
||
export function crossProjectLinksPlugin({ | ||
baseUrl, | ||
projectUrls, | ||
}: CrossProjectLinksOptions): Transformer { | ||
return async (tree) => { | ||
const { visit } = await import("unist-util-visit") | ||
visit(tree as UnistTree, "element", (node: UnistNode) => { | ||
if (node.tagName !== "a" || !node.properties?.href) { | ||
function matchAndFixLinks( | ||
link: string, | ||
{ baseUrl, projectUrls }: CrossProjectLinksOptions | ||
): string { | ||
const projectArea = PROJECT_REGEX.exec(link) | ||
|
||
if (!projectArea?.groups?.area) { | ||
return link | ||
} | ||
|
||
const actualUrl = link.replace(PROJECT_REGEX, "") | ||
|
||
const base = | ||
projectUrls && | ||
Object.hasOwn(projectUrls, projectArea.groups.area) && | ||
projectUrls[projectArea.groups.area]?.url | ||
? projectUrls[projectArea.groups.area].url | ||
: baseUrl | ||
const path = | ||
projectUrls && | ||
Object.hasOwn(projectUrls, projectArea.groups.area) && | ||
projectUrls[projectArea.groups.area]?.path | ||
? projectUrls[projectArea.groups.area].path | ||
: projectArea.groups.area | ||
|
||
return `${base}/${path}${actualUrl}` | ||
} | ||
|
||
function linkElmFixer(node: UnistNode, options: CrossProjectLinksOptions) { | ||
if (!node.properties) { | ||
return | ||
} | ||
|
||
node.properties.href = matchAndFixLinks(node.properties.href, options) | ||
} | ||
|
||
function componentFixer( | ||
node: UnistNodeWithData, | ||
options: CrossProjectLinksOptions | ||
) { | ||
if (!node.name) { | ||
return | ||
} | ||
|
||
switch (node.name) { | ||
case "CardList": | ||
const itemsAttribute = getAttribute(node, "items") | ||
|
||
if ( | ||
!itemsAttribute?.value || | ||
typeof itemsAttribute.value === "string" || | ||
!itemsAttribute.value.data?.estree | ||
) { | ||
return | ||
} | ||
|
||
const projectArea = PROJECT_REGEX.exec(node.properties.href) | ||
const jsVar = estreeToJs(itemsAttribute.value.data.estree) | ||
|
||
if (!projectArea?.groups?.area) { | ||
if (!jsVar) { | ||
return | ||
} | ||
|
||
const actualUrl = node.properties.href.replace(PROJECT_REGEX, "") | ||
|
||
const base = | ||
projectUrls && | ||
Object.hasOwn(projectUrls, projectArea.groups.area) && | ||
projectUrls[projectArea.groups.area]?.url | ||
? projectUrls[projectArea.groups.area].url | ||
: baseUrl | ||
const path = | ||
projectUrls && | ||
Object.hasOwn(projectUrls, projectArea.groups.area) && | ||
projectUrls[projectArea.groups.area]?.path | ||
? projectUrls[projectArea.groups.area].path | ||
: projectArea.groups.area | ||
|
||
node.properties.href = `${base}/${path}${actualUrl}` | ||
}) | ||
const fixProperty = (item: ExpressionJsVar) => { | ||
if (!isExpressionJsVarObj(item)) { | ||
return | ||
} | ||
|
||
Object.entries(item).forEach(([key, value]) => { | ||
if (key !== "href" || !isExpressionJsVarLiteral(value)) { | ||
return | ||
} | ||
|
||
value.original.value = matchAndFixLinks( | ||
value.original.value as string, | ||
options | ||
) | ||
value.original.raw = JSON.stringify(value.original.value) | ||
}) | ||
} | ||
|
||
if (Array.isArray(jsVar)) { | ||
jsVar.forEach(fixProperty) | ||
} else { | ||
fixProperty(jsVar) | ||
} | ||
return | ||
case "Card": | ||
const hrefAttribute = getAttribute(node, "href") | ||
|
||
if (!hrefAttribute?.value || typeof hrefAttribute.value !== "string") { | ||
return | ||
} | ||
|
||
hrefAttribute.value = matchAndFixLinks(hrefAttribute.value, options) | ||
|
||
return | ||
} | ||
} | ||
|
||
export function crossProjectLinksPlugin( | ||
options: CrossProjectLinksOptions | ||
): Transformer { | ||
return async (tree) => { | ||
const { visit } = await import("unist-util-visit") | ||
|
||
visit( | ||
tree as UnistTree, | ||
["element", "mdxJsxFlowElement"], | ||
(node: UnistNode) => { | ||
const isComponent = node.name === "Card" || node.name === "CardList" | ||
const isLink = node.tagName === "a" && node.properties?.href | ||
if (!isComponent && !isLink) { | ||
return | ||
} | ||
|
||
if (isComponent) { | ||
componentFixer(node as UnistNodeWithData, options) | ||
} | ||
|
||
linkElmFixer(node, options) | ||
} | ||
) | ||
} | ||
} |
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.