@patternfly/documentation-framework 2.0.0-alpha.23 → 2.0.0-alpha.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +2 -2
- package/scripts/cli/cli.js +1 -0
- package/scripts/tsDocgen.js +119 -91
- package/scripts/writeScreenshots.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 2.0.0-alpha.24 (2023-04-17)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @patternfly/documentation-framework
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
# 2.0.0-alpha.23 (2023-04-17)
|
|
7
15
|
|
|
8
16
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/documentation-framework",
|
|
3
3
|
"description": "A framework to build documentation for PatternFly.",
|
|
4
|
-
"version": "2.0.0-alpha.
|
|
4
|
+
"version": "2.0.0-alpha.24",
|
|
5
5
|
"author": "Red Hat",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"react": "^17.0.0 || ^18.0.0",
|
|
91
91
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
92
92
|
},
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "2ccf5bbcf789a71ed52c342970d63cf0b568f8f8"
|
|
94
94
|
}
|
package/scripts/cli/cli.js
CHANGED
|
@@ -45,6 +45,7 @@ program
|
|
|
45
45
|
program
|
|
46
46
|
.command('screenshots')
|
|
47
47
|
.option('-u, --urlPrefix <prefix>', 'where fullscreen pages are hosted', 'http://localhost:5000/v4')
|
|
48
|
+
.option('-a, --allRoutes', 'true if screenshots of all examples - not just full screen', false)
|
|
48
49
|
.description('updates screenshots for generated components')
|
|
49
50
|
.action(options => {
|
|
50
51
|
const { writeScreenshots } = require('../writeScreenshots');
|
package/scripts/tsDocgen.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
const fs = require(
|
|
2
|
-
const reactDocgen = require(
|
|
3
|
-
const ts = require(
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const reactDocgen = require("react-docgen");
|
|
3
|
+
const ts = require("typescript");
|
|
4
4
|
|
|
5
5
|
const annotations = [
|
|
6
6
|
{
|
|
7
7
|
regex: /@deprecated/,
|
|
8
|
-
name:
|
|
9
|
-
type:
|
|
8
|
+
name: "deprecated",
|
|
9
|
+
type: "Boolean",
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
regex: /@hide/,
|
|
13
|
-
name:
|
|
14
|
-
type:
|
|
13
|
+
name: "hide",
|
|
14
|
+
type: "Boolean",
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
regex: /@beta/,
|
|
18
|
-
name:
|
|
19
|
-
type:
|
|
18
|
+
name: "beta",
|
|
19
|
+
type: "Boolean",
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
regex: /@propType\s+(.*)/,
|
|
23
|
-
name:
|
|
24
|
-
type:
|
|
25
|
-
}
|
|
23
|
+
name: "type",
|
|
24
|
+
type: "String",
|
|
25
|
+
},
|
|
26
26
|
];
|
|
27
27
|
|
|
28
28
|
function addAnnotations(prop) {
|
|
@@ -30,12 +30,12 @@ function addAnnotations(prop) {
|
|
|
30
30
|
annotations.forEach(({ regex, name }) => {
|
|
31
31
|
const match = prop.description.match(regex);
|
|
32
32
|
if (match) {
|
|
33
|
-
prop.description = prop.description.replace(regex,
|
|
33
|
+
prop.description = prop.description.replace(regex, "").trim();
|
|
34
34
|
if (name) {
|
|
35
35
|
prop[name] = match[2] || match[1] || true;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
})
|
|
38
|
+
});
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
return prop;
|
|
@@ -55,74 +55,101 @@ function getComponentMetadata(filename, sourceText) {
|
|
|
55
55
|
// console.warn(`No component found in ${filename}:`, err);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
return (parsedComponents || []).filter(
|
|
58
|
+
return (parsedComponents || []).filter(
|
|
59
|
+
(parsed) => parsed && parsed.displayName
|
|
60
|
+
);
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
const getNodeText = (node, sourceText) => {
|
|
64
|
+
if (!node || !node.pos || !node.end) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return sourceText.substring(node.pos, node.end).trim();
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const buildJsDocProps = (nodes, sourceText) =>
|
|
72
|
+
nodes?.reduce((acc, member) => {
|
|
73
|
+
const name =
|
|
74
|
+
(member.name && member.name.escapedText) ||
|
|
75
|
+
(member.parameters &&
|
|
76
|
+
`[${getNodeText(member.parameters[0], sourceText)}]`) ||
|
|
77
|
+
"Unknown";
|
|
78
|
+
acc[name] = {
|
|
79
|
+
description: member.jsDoc
|
|
80
|
+
? member.jsDoc.map((doc) => doc.comment).join("\n")
|
|
81
|
+
: null,
|
|
82
|
+
required: member.questionToken === undefined,
|
|
83
|
+
type: {
|
|
84
|
+
raw: getNodeText(member.type, sourceText).trim(),
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
return acc;
|
|
88
|
+
}, {});
|
|
89
|
+
|
|
90
|
+
const getSourceFileStatements = (filename, sourceText) => {
|
|
91
|
+
const { statements } = ts.createSourceFile(
|
|
63
92
|
filename,
|
|
64
93
|
sourceText,
|
|
65
94
|
ts.ScriptTarget.Latest // languageVersion
|
|
66
95
|
);
|
|
67
|
-
|
|
68
|
-
function getText(node) {
|
|
69
|
-
if (!node || !node.pos || !node.end) {
|
|
70
|
-
return undefined;
|
|
71
|
-
}
|
|
72
|
-
return sourceText.substring(node.pos, node.end).trim();
|
|
73
|
-
}
|
|
74
96
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
97
|
+
return statements;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const getInterfaceMetadata = (filename, sourceText) =>
|
|
101
|
+
getSourceFileStatements(filename, sourceText).reduce(
|
|
102
|
+
(metaDataAcc, statement) => {
|
|
103
|
+
if (statement.kind === ts.SyntaxKind.InterfaceDeclaration) {
|
|
104
|
+
metaDataAcc.push({
|
|
105
|
+
displayName: statement.name.escapedText,
|
|
106
|
+
description: statement.jsDoc?.map((doc) => doc.comment).join("\n"),
|
|
107
|
+
props: buildJsDocProps(statement.members, sourceText),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return metaDataAcc;
|
|
112
|
+
},
|
|
113
|
+
[]
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const getTypeAliasMetadata = (filename, sourceText) =>
|
|
117
|
+
getSourceFileStatements(filename, sourceText).reduce(
|
|
118
|
+
(metaDataAcc, statement) => {
|
|
119
|
+
if (statement.kind === ts.SyntaxKind.TypeAliasDeclaration) {
|
|
120
|
+
const props = statement.type.types?.reduce((propAcc, type) => {
|
|
121
|
+
if (type.members) {
|
|
122
|
+
propAcc.push(buildJsDocProps(type.members, sourceText));
|
|
91
123
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
124
|
+
|
|
125
|
+
return propAcc;
|
|
126
|
+
}, []);
|
|
127
|
+
|
|
128
|
+
metaDataAcc.push({
|
|
129
|
+
props,
|
|
130
|
+
displayName: statement.name.escapedText,
|
|
131
|
+
description: statement.jsDoc?.map((doc) => doc.comment).join("\n"),
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return metaDataAcc;
|
|
136
|
+
},
|
|
137
|
+
[]
|
|
138
|
+
);
|
|
106
139
|
|
|
107
140
|
function normalizeProp([
|
|
108
141
|
name,
|
|
109
|
-
{
|
|
110
|
-
required,
|
|
111
|
-
annotatedType,
|
|
112
|
-
type,
|
|
113
|
-
tsType,
|
|
114
|
-
description,
|
|
115
|
-
defaultValue
|
|
116
|
-
}
|
|
142
|
+
{ required, annotatedType, type, tsType, description, defaultValue },
|
|
117
143
|
]) {
|
|
118
144
|
const res = {
|
|
119
145
|
name,
|
|
120
|
-
type:
|
|
121
|
-
||
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
||
|
|
125
|
-
|
|
146
|
+
type:
|
|
147
|
+
annotatedType ||
|
|
148
|
+
(type && type.name) ||
|
|
149
|
+
(type && (type.raw || type.name)) ||
|
|
150
|
+
(tsType && (tsType.raw || tsType.name)) ||
|
|
151
|
+
"No type info",
|
|
152
|
+
description,
|
|
126
153
|
};
|
|
127
154
|
if (required) {
|
|
128
155
|
res.required = true;
|
|
@@ -134,45 +161,46 @@ function normalizeProp([
|
|
|
134
161
|
return res;
|
|
135
162
|
}
|
|
136
163
|
|
|
137
|
-
function getDescription(parsed, ) {
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
164
|
function tsDocgen(file) {
|
|
142
|
-
const sourceText = fs.readFileSync(file,
|
|
165
|
+
const sourceText = fs.readFileSync(file, "utf8");
|
|
143
166
|
const componentMeta = getComponentMetadata(file, sourceText); // Array of components with props
|
|
144
167
|
const interfaceMeta = getInterfaceMetadata(file, sourceText); // Array of interfaces with props
|
|
145
|
-
const
|
|
146
|
-
|
|
168
|
+
const typeAliasMeta = getTypeAliasMetadata(file, sourceText); // Array of type aliases with props
|
|
169
|
+
const propsMetaMap = [...interfaceMeta, ...typeAliasMeta].reduce(function (
|
|
170
|
+
target,
|
|
171
|
+
interfaceOrTypeAlias
|
|
172
|
+
) {
|
|
173
|
+
target[interfaceOrTypeAlias.displayName] = interfaceOrTypeAlias;
|
|
147
174
|
return target;
|
|
148
|
-
},
|
|
175
|
+
},
|
|
176
|
+
{});
|
|
149
177
|
|
|
150
|
-
// Go through each component and check if they have an interface with a jsDoc description
|
|
178
|
+
// Go through each component and check if they have an interface or type alias with a jsDoc description
|
|
151
179
|
// If so copy it over (fix for https://github.com/patternfly/patternfly-react/issues/7612)
|
|
152
|
-
componentMeta.forEach(c => {
|
|
180
|
+
componentMeta.forEach((c) => {
|
|
153
181
|
if (c.description) {
|
|
154
182
|
return c;
|
|
155
183
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
184
|
+
|
|
185
|
+
const propsName = `${c.displayName}Props`;
|
|
186
|
+
if (propsMetaMap[propsName]?.description) {
|
|
187
|
+
c.description = propsMetaMap[propsName].description;
|
|
159
188
|
}
|
|
160
|
-
})
|
|
189
|
+
});
|
|
161
190
|
|
|
162
|
-
return componentMeta
|
|
163
|
-
|
|
164
|
-
.map(parsed => ({
|
|
191
|
+
return [...componentMeta, ...interfaceMeta, ...typeAliasMeta].map(
|
|
192
|
+
(parsed) => ({
|
|
165
193
|
name: parsed.displayName,
|
|
166
|
-
description: parsed.description ||
|
|
194
|
+
description: parsed.description || "",
|
|
167
195
|
props: Object.entries(parsed.props || {})
|
|
168
196
|
.map(normalizeProp)
|
|
169
197
|
.map(addAnnotations)
|
|
170
|
-
.filter(prop => !prop.hide)
|
|
171
|
-
.sort((p1, p2) => p1.name.localeCompare(p2.name))
|
|
172
|
-
})
|
|
198
|
+
.filter((prop) => !prop.hide)
|
|
199
|
+
.sort((p1, p2) => p1.name.localeCompare(p2.name)),
|
|
200
|
+
})
|
|
201
|
+
);
|
|
173
202
|
}
|
|
174
203
|
|
|
175
204
|
module.exports = {
|
|
176
|
-
tsDocgen
|
|
205
|
+
tsDocgen,
|
|
177
206
|
};
|
|
178
|
-
|
|
@@ -27,7 +27,7 @@ async function writeScreenshot({ page, data: { url, urlPrefix } }) {
|
|
|
27
27
|
await sharp(buffer).toFile(outfile);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
async function writeScreenshots({ urlPrefix }) {
|
|
30
|
+
async function writeScreenshots({ urlPrefix, allRoutes }) {
|
|
31
31
|
const cluster = await Cluster.launch({
|
|
32
32
|
concurrency: Cluster.CONCURRENCY_CONTEXT,
|
|
33
33
|
maxConcurrency: os.cpus().length,
|
|
@@ -43,7 +43,7 @@ async function writeScreenshots({ urlPrefix }) {
|
|
|
43
43
|
|
|
44
44
|
// Add some pages to queue
|
|
45
45
|
Object.entries(fullscreenRoutes)
|
|
46
|
-
.filter(([, { isFullscreenOnly }]) => isFullscreenOnly)
|
|
46
|
+
.filter(([, { isFullscreenOnly }]) => allRoutes || isFullscreenOnly)
|
|
47
47
|
.forEach(([url,]) => cluster.queue({
|
|
48
48
|
url: `${urlPrefix}${url}`,
|
|
49
49
|
urlPrefix
|