-
Notifications
You must be signed in to change notification settings - Fork 3
/
docgen.js
108 lines (96 loc) · 2.76 KB
/
docgen.js
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
/**
* https://gist.github.com/phiter/14e96783633d6653dbfe26a559d8c5b6
*/
const { promisify } = require('util');
const fs = require('fs');
const glob = promisify(require('glob'));
const { parse } = require('vue-docgen-api');
const TagsMap = {
Bdage: 'VBadge',
Button: 'VBtn',
Icon: 'VIcon',
Checkbox: 'VCheckbox',
Dialog: 'VDialog',
LinearProgress: 'VLinearProgress',
List: 'VList',
Menu: 'VMenu',
RadioButton: 'VRadioBtn',
Select: 'VSelect',
Slider: 'VSlider',
Spinner: 'VSpinner',
Switch: 'VSwitch',
Table: 'VTable',
TextField: 'VTextField',
Tooltip: 'VTooltip',
TreeView: 'VTreeView'
}
const convertToKebabCase = str => (
str
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
.map(x => x.toLowerCase())
.join('-')
);
const listComponents = async () => {
// Glob for your components.
const files = await glob('src/ui/**/*.vue');
return files;
};
/**
* Parses the component tags
* @param {import('vue-docgen-api').ComponentDoc} component
*/
const parseTag = (component) => {
const tag = {};
if (component.props) {
tag.attributes = component.props.map(prop => convertToKebabCase(prop.name));
}
tag.description = component.description || '';
return tag;
};
/**
* Parses the component tags
* @param {String} componentTag
* @param {import('vue-docgen-api').ComponentDoc} component
*/
const parseAttributes = (componentTag, component) => {
const props = {};
component.props.forEach((prop) => {
const propName = convertToKebabCase(prop.name);
// eslint-disable-next-line no-multi-assign
const propDoc = props[`${componentTag}/${propName}`] = {};
propDoc.description = prop.description || '';
if (prop.type) {
propDoc.type = prop.type.name;
}
if (prop.values) {
propDoc.options = prop.values;
}
});
return props;
};
const parseDocs = (components) => {
const tags = {};
let attributes = {};
components.forEach((component) => {
let componentName = component.displayName;
componentName = TagsMap[componentName] || componentName;
const componentTag = convertToKebabCase(componentName);
tags[componentTag] = parseTag(component);
if (component.props) {
attributes = { ...parseAttributes(componentTag, component), ...attributes };
}
});
return [tags, attributes];
};
const gen = async () => {
const components = await listComponents();
const componentDocsPromises = components.map(c => parse(c));
const docs = await Promise.all(componentDocsPromises);
const [tags, attributes] = parseDocs(docs);
if (!fs.existsSync('vetur')) {
fs.mkdirSync('vetur');
}
fs.writeFileSync('vetur/tags.json', JSON.stringify(tags, null, 2));
fs.writeFileSync('vetur/attributes.json', JSON.stringify(attributes, null, 2));
};
gen();