forked from FormidableLabs/prism-react-renderer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
108 lines (94 loc) · 3.05 KB
/
index.ts
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
98
99
100
101
102
103
104
105
106
107
108
import flowRight from "lodash.flowright"
import pc from "picocolors"
import { readFile, writeFile, access } from "node:fs/promises"
import { constants } from "node:fs"
import { join, dirname } from "node:path"
import { languages as prismLanguages } from "prismjs/components"
import uglify from "uglify-js"
export const languagesToBundle = <const>[
"jsx",
"tsx",
"swift",
"kotlin",
"objectivec",
"js-extras",
"reason",
"rust",
"graphql",
"yaml",
"go",
"cpp",
"markdown",
"html",
"python",
]
/**
* We need to disable typechecking on this generated file as it's just concatenating JS code
* that starts off assuming Prism lives in global scope. We also need to provide Prism as that
* gets passed into an iffe preventing us from needing to use global scope.
*/
const header = `// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport * as Prism from "prismjs";\nexport { Prism };`
const prismPath = dirname(require.resolve("prismjs"))
const readLanguageFile = async (language: string): Promise<string> => {
const pathToLanguage = join(prismPath, `components/prism-${language}.js`)
await access(pathToLanguage, constants.R_OK)
const buffer = await readFile(pathToLanguage, { encoding: "utf-8" })
return buffer.toString()
}
const strArrayFromUnknown = (input: unknown) => (array: string[]) => {
if (typeof input === "string") array.push(input)
else if (Array.isArray(input)) array = array.concat(input)
return array
}
const main = async () => {
let output = ""
const bundledLanguages = new Set<keyof typeof prismLanguages>()
const orderBundled = new Set<keyof typeof prismLanguages>()
const outputPath = join(
__dirname,
"../prism-react-renderer/src/prism-langs.ts"
)
const addLanguageToOutput = async (language?: string) => {
if (bundledLanguages.has(language)) {
return
}
if (language == null || prismLanguages[language] == null) {
return
}
bundledLanguages.add(language)
/**
* We need to ensure any language dependencies are bundled first
*/
const prismLang = prismLanguages[language]
const deps = flowRight(
strArrayFromUnknown(prismLang.require),
strArrayFromUnknown(prismLang.optional)
)([])
const peerDeps = strArrayFromUnknown(prismLang.peerDependencies)([])
for await (const language of deps) {
await addLanguageToOutput(language)
}
output += await readLanguageFile(language)
orderBundled.add(language)
for await (const language of peerDeps) {
await addLanguageToOutput(language)
}
}
for await (const language of languagesToBundle) {
await addLanguageToOutput(language)
}
console.info(
pc.bold(pc.bgYellow(pc.black("Formidable Prism React Renderer"))),
"\n"
)
console.info(
pc.bgBlue(`Generated TypeScript output at:`),
pc.cyan(outputPath)
)
console.info(
pc.bgGreen(`Included language definitions in the following order:`),
Array.from(orderBundled.values()).join(", ")
)
await writeFile(outputPath, header + uglify.minify(output).code)
}
main()