-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
146 lines (129 loc) · 4.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import { getNodes, setNodes, setRuntimeBuiltinNodes } from './consts.ts'
import {
expandNamespaces,
flattenNamespaces,
groupNodes,
sortByAlphabet
} from './utils/docs.ts'
import { generateMarkdown } from './utils/generate.ts'
import { checkIfSiteGeneratorActivated } from './utils/checker.ts'
import { Command } from './deps.ts'
import { errorText, infoText, doneText } from './utils/consoleStyles.ts'
interface parsedOptions {
filename: string
out: string
vuepress: boolean
docusaurus: boolean // maybe later
}
const main = async (): Promise<void> => {
const parsed = await new Command<parsedOptions, string[]>()
.name('Denodown')
.description('Document generator for Deno projects.')
.arguments('<filename:string>')
.option('-o, --out <out>', 'Sets the output directory.', {
default: 'out'
})
.option(
'-v, --vuepress [vuepress:boolean]',
'Sets vuepress mode to enable.',
{
default: false
}
)
.parse(Deno.args)
const uri: string = parsed.args[0]
if (uri === undefined) {
console.log(errorText('No input file detected.'))
Deno.exit(1)
}
await validateUri(uri)
const startTime = Date.now()
console.log(infoText('Reading files and generating nodes...'))
const fileProcess = await Deno.run({
cmd: ['deno', 'doc', uri, '--reload', '--json'],
stdout: 'piped'
})
const textDecoder = new TextDecoder()
const fileJSON = textDecoder.decode(await fileProcess.output())
setNodes(flattenNamespaces(expandNamespaces(JSON.parse(fileJSON))))
const builtinProcess = await Deno.run({
cmd: ['deno', 'doc', '--builtin', '--json'],
stdout: 'piped'
})
const builtinJSON = textDecoder.decode(await builtinProcess.output())
setRuntimeBuiltinNodes(
flattenNamespaces(expandNamespaces(JSON.parse(builtinJSON)))
)
const siteGenerators = checkIfSiteGeneratorActivated(
parsed.options.vuepress,
parsed.options.docusaurus
)
const groups = groupNodes(sortByAlphabet(getNodes()))
console.log(infoText('Generating markdown files...'))
const configResult = generateMarkdown({
groups,
pathPrefix: parsed.options.out,
siteGenerators
})
if (configResult.vuepress !== undefined) {
Deno.writeTextFileSync(
`${parsed.options.out}/vuepress-sidebar.js`,
'// Move this config to where your vuepress config is in and import this config.\n' +
'// And then you can use this config like this:\n' +
'// "/": require("vuepress-sidebar")\n' +
'// For more information please check this page: https://vuepress.vuejs.org/theme/default-theme-config.html#sidebar' +
`module.exports = ${Deno.inspect(configResult.vuepress, {
depth: 100,
iterableLimit: Infinity
})}`
)
}
console.log(doneText(`Done! Took ${Date.now() - startTime}ms.`))
}
if (import.meta.main) {
await main()
}
async function validateUri(uri: string) {
let url: URL | undefined
try {
url = new URL(uri)
} catch (error) {
// not a valid URL, assume file path
}
if (url !== undefined && url.protocol.startsWith('http')) {
// try to fetch file from URL
const controller = new AbortController()
const handle = setTimeout(() => controller.abort(), 10 * 1000) // 10 seconds timeout
try {
const res = await fetch(url, {
method: 'HEAD',
signal: controller.signal
})
clearTimeout(handle)
console.log(infoText('Entrypoint file check has status', res.status))
if (res.status < 200 || 299 < res.status) {
console.log(errorText(`Cannot download entrypoint file from '${uri}'`))
Deno.exit(1)
}
} catch (e) {
if (controller.signal.aborted) {
console.log(errorText(`Download from '${uri}' timed out.`))
Deno.exit(1)
} else {
throw e
}
}
} else {
// try to read file from disk
try {
await Deno.readTextFile(uri)
} catch (e) {
if (e.name === 'NotFound') {
console.log(errorText(`File "${uri}" not found.`))
Deno.exit(1)
} else {
throw e
}
}
}
}