forked from react-navigation/react-navigation.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathremark-npm2yarn.mjs
More file actions
97 lines (82 loc) · 2.39 KB
/
remark-npm2yarn.mjs
File metadata and controls
97 lines (82 loc) · 2.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import npmToYarn from 'npm-to-yarn';
import { Parser } from 'acorn';
import acornJsx from 'acorn-jsx';
const parser = Parser.extend(acornJsx());
function parseExpression(code) {
return parser.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });
}
function createLabelWithIcon(pm) {
const value = `<><img className="pm-icon" src="/assets/pm/${pm}.svg" alt="" />${pm}</>`;
return {
type: 'mdxJsxAttributeValueExpression',
value,
data: { estree: parseExpression(value) },
};
}
function createTabItem({ code, node, pm }) {
return {
type: 'mdxJsxFlowElement',
name: 'TabItem',
attributes: [
{ type: 'mdxJsxAttribute', name: 'value', value: pm },
{
type: 'mdxJsxAttribute',
name: 'label',
value: createLabelWithIcon(pm),
},
],
children: [{ type: node.type, lang: node.lang, value: code }],
};
}
function transformNode(node, sync, converters) {
const npmCode = node.value;
return {
type: 'mdxJsxFlowElement',
name: 'Tabs',
attributes: sync
? [{ type: 'mdxJsxAttribute', name: 'groupId', value: 'npm2yarn' }]
: [],
children: [
createTabItem({ code: npmCode, node, pm: 'npm' }),
...converters.map((pm) =>
createTabItem({ code: npmToYarn(npmCode, pm), node, pm })
),
],
};
}
function createImportNode() {
const value =
"import Tabs from '@theme/Tabs'\nimport TabItem from '@theme/TabItem'";
return {
type: 'mdxjsEsm',
value,
data: { estree: parseExpression(value) },
};
}
export default function remarkNpm2Yarn(options = {}) {
const { sync = false, converters = ['yarn', 'pnpm', 'bun'] } = options;
return async (root) => {
const { visit } = await import('unist-util-visit');
let transformed = false;
let alreadyImported = false;
visit(root, (node) => {
if (node.type === 'mdxjsEsm' && node.value.includes('@theme/Tabs')) {
alreadyImported = true;
}
if (Array.isArray(node.children)) {
let i = 0;
while (i < node.children.length) {
const child = node.children[i];
if (child.type === 'code' && child.meta === 'npm2yarn') {
node.children[i] = transformNode(child, sync, converters);
transformed = true;
}
i++;
}
}
});
if (transformed && !alreadyImported) {
root.children.unshift(createImportNode());
}
};
}