vue-styleguidist / vue-styleguidist
1 1
import * as path from 'path'
2 1
import glob from 'globby'
3 1
import chokidar, { FSWatcher } from 'chokidar'
4 1
import { parse, ParamTag, ScriptHandlers, DocGenOptions } from 'vue-docgen-api'
5 1
import { getDocMap } from './utils'
6

7
/**
8
 *
9
 * @param components glob or globs to watch
10
 * @param cwd option to pass chokidar
11
 * @param getDocFileName a function to go from component to doc file
12
 */
13 1
export default async function getSources(
14
	components: string | string[],
15
	cwd: string,
16
	getDocFileName: (componentPath: string) => string | false,
17 1
	optionsApi: DocGenOptions = {}
18
): Promise<{
19
	watcher: FSWatcher
20
	docMap: { [filepath: string]: string }
21
	componentFiles: string[]
22
}> {
23 1
	const watcher = chokidar.watch(components, { cwd })
24

25 1
	const allComponentFiles = await glob(components, { cwd })
26

27
	// we will parse each of the discovered components looking for @requires
28
	// and @example/examples to add them to the watcher.
29 1
	const requiredComponents = (
30 1
		await Promise.all(
31 1
			allComponentFiles.map(compPath => getRequiredComponents(compPath, optionsApi, cwd))
32
		)
33 1
	).reduce((acc, comps) => acc.concat(comps), [])
34

35 1
	const componentFiles = allComponentFiles.filter(
36 1
		compPath => !requiredComponents.includes(compPath)
37
	)
38

39 1
	const docMap = getDocMap(
40
		// if a component is required, it cannot be the direct target of a ReadMe doc
41
		// if we let it be this target it could override a legitimate target.
42
		componentFiles,
43
		getDocFileName,
44
		cwd
45
	)
46 1
	watcher.add(Object.keys(docMap))
47

48 1
	return { watcher, docMap, componentFiles }
49
}
50

51
async function getRequiredComponents(
52
	compPath: string,
53
	optionsApi: DocGenOptions,
54 1
	cwd: string
55
): Promise<string[]> {
56 1
	const compDirName = path.dirname(compPath)
57 1
	const absoluteComponentPath = path.join(cwd, compPath)
58
	try {
59 1
		const { tags } = await parse(absoluteComponentPath, {
60
			// make sure that this is recognized as an option bag
61
			jsx: false,
62
			...optionsApi,
63
			scriptHandlers: [ScriptHandlers.componentHandler]
64
		})
65 1
		if (tags?.requires?.length) {
66 0
			return tags.requires.map((t: ParamTag) => path.join(compDirName, t.description as string))
67
		}
68
	} catch (e) {
69 0
		throw new Error(`Error parsing ${absoluteComponentPath} for @requires tags: ${e.message}`)
70
	}
71 1
	return []
72
}

Read our documentation on viewing source code .

Loading