@backstage/repo-tools 0.12.1 → 0.12.2-next.1
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 +28 -0
- package/dist/commands/api-reports/api-reports/buildDocs.cjs.js +443 -0
- package/dist/commands/api-reports/api-reports/createTemporaryTsConfig.cjs.js +37 -0
- package/dist/commands/api-reports/{generateTypeDeclarations.cjs.js → api-reports/generateTypeDeclarations.cjs.js} +1 -1
- package/dist/commands/api-reports/api-reports/patchApiReportGeneration.cjs.js +95 -0
- package/dist/commands/api-reports/api-reports/runApiExtraction.cjs.js +312 -0
- package/dist/commands/api-reports/{api-reports.cjs.js → buildApiReports.cjs.js} +22 -12
- package/dist/commands/api-reports/categorizePackageDirs.cjs.js +50 -0
- package/dist/commands/api-reports/cli-reports/generateCliReport.cjs.js +31 -0
- package/dist/commands/api-reports/cli-reports/runCliExtraction.cjs.js +125 -0
- package/dist/commands/api-reports/common/logApiReportInstructions.cjs.js +21 -0
- package/dist/commands/api-reports/common/tryRunPrettier.cjs.js +19 -0
- package/dist/commands/api-reports/index.cjs.js +8 -0
- package/dist/commands/api-reports/sql-reports/generateSqlReport.cjs.js +67 -0
- package/dist/commands/api-reports/sql-reports/getPgSchemaInfo.cjs.js +67 -0
- package/dist/commands/api-reports/sql-reports/runSqlExtraction.cjs.js +150 -0
- package/dist/commands/index.cjs.js +24 -53
- package/dist/commands/peer-deps/peer-deps.cjs.js +4 -4
- package/dist/commands/repo/schema/openapi/verify.cjs.js +1 -1
- package/dist/package.json.cjs.js +1 -1
- package/package.json +14 -10
- package/dist/commands/api-reports/api-extractor.cjs.js +0 -1041
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @backstage/repo-tools
|
|
2
2
|
|
|
3
|
+
## 0.12.2-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 58ec9e7: Removed older versions of React packages as a preparatory step for upgrading to React 19. This commit does not introduce any functional changes, but removes dependencies on previous React versions, allowing for a cleaner upgrade path in subsequent commits.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @backstage/backend-plugin-api@1.2.0-next.0
|
|
10
|
+
- @backstage/catalog-model@1.7.3
|
|
11
|
+
- @backstage/cli-common@0.1.15
|
|
12
|
+
- @backstage/cli-node@0.2.13-next.0
|
|
13
|
+
- @backstage/config-loader@1.9.6-next.0
|
|
14
|
+
- @backstage/errors@1.2.7
|
|
15
|
+
|
|
16
|
+
## 0.12.2-next.0
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 98ddf05: The `api-reports` command is now also able to generate SQL reports, enabled by the `--sql-reports` flag.
|
|
21
|
+
- cb76663: Internal refactor to support native ESM.
|
|
22
|
+
- ecd01a9: Internal refactor of API report generation.
|
|
23
|
+
- Updated dependencies
|
|
24
|
+
- @backstage/cli-node@0.2.13-next.0
|
|
25
|
+
- @backstage/config-loader@1.9.6-next.0
|
|
26
|
+
- @backstage/backend-plugin-api@1.2.0-next.0
|
|
27
|
+
- @backstage/catalog-model@1.7.3
|
|
28
|
+
- @backstage/cli-common@0.1.15
|
|
29
|
+
- @backstage/errors@1.2.7
|
|
30
|
+
|
|
3
31
|
## 0.12.1
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('path');
|
|
4
|
+
var fs = require('fs-extra');
|
|
5
|
+
var tsdoc = require('@microsoft/tsdoc');
|
|
6
|
+
var apiExtractorModel = require('@microsoft/api-extractor-model');
|
|
7
|
+
var MarkdownDocumenter = require('@microsoft/api-documenter/lib/documenters/MarkdownDocumenter');
|
|
8
|
+
var DocTable = require('@microsoft/api-documenter/lib/nodes/DocTable');
|
|
9
|
+
var DocTableRow = require('@microsoft/api-documenter/lib/nodes/DocTableRow');
|
|
10
|
+
var DocHeading = require('@microsoft/api-documenter/lib/nodes/DocHeading');
|
|
11
|
+
var CustomMarkdownEmitter = require('@microsoft/api-documenter/lib/markdown/CustomMarkdownEmitter');
|
|
12
|
+
|
|
13
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
14
|
+
|
|
15
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
16
|
+
|
|
17
|
+
class ExcerptTokenMatcher {
|
|
18
|
+
#tokens;
|
|
19
|
+
constructor(tokens) {
|
|
20
|
+
this.#tokens = tokens.slice();
|
|
21
|
+
}
|
|
22
|
+
nextContent() {
|
|
23
|
+
const token = this.#tokens.shift();
|
|
24
|
+
if (token?.kind === "Content") {
|
|
25
|
+
return token.text;
|
|
26
|
+
}
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
matchContent(expectedText) {
|
|
30
|
+
const text = this.nextContent();
|
|
31
|
+
return text !== expectedText;
|
|
32
|
+
}
|
|
33
|
+
getTokensUntilArrow() {
|
|
34
|
+
const tokens = [];
|
|
35
|
+
for (; ; ) {
|
|
36
|
+
const token = this.#tokens.shift();
|
|
37
|
+
if (token === void 0) {
|
|
38
|
+
return void 0;
|
|
39
|
+
}
|
|
40
|
+
if (token.kind === "Content" && token.text === ") => ") {
|
|
41
|
+
return tokens;
|
|
42
|
+
}
|
|
43
|
+
tokens.push(token);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
getComponentReturnTokens() {
|
|
47
|
+
const first = this.#tokens.shift();
|
|
48
|
+
if (!first) {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
const second = this.#tokens.shift();
|
|
52
|
+
if (this.#tokens.length !== 0) {
|
|
53
|
+
return void 0;
|
|
54
|
+
}
|
|
55
|
+
if (first.kind !== "Reference" || first.text !== "JSX.Element") {
|
|
56
|
+
return void 0;
|
|
57
|
+
}
|
|
58
|
+
if (!second) {
|
|
59
|
+
return [first];
|
|
60
|
+
} else if (second.kind === "Content" && second.text === " | null") {
|
|
61
|
+
return [first, second];
|
|
62
|
+
}
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
class ApiModelTransforms {
|
|
67
|
+
static deserializeWithTransforms(serialized, transforms) {
|
|
68
|
+
if (serialized.kind !== "Package") {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Unexpected root kind in serialized ApiPackage, ${serialized.kind}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
if (serialized.members.length !== 1) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Unexpected members in serialized ApiPackage, [${serialized.members.map((m) => m.kind).join(" ")}]`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const [entryPoint] = serialized.members;
|
|
79
|
+
if (entryPoint.kind !== "EntryPoint") {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Unexpected kind in serialized ApiPackage member, ${entryPoint.kind}`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
const transformed = {
|
|
85
|
+
...serialized,
|
|
86
|
+
members: [
|
|
87
|
+
{
|
|
88
|
+
...entryPoint,
|
|
89
|
+
members: entryPoint.members.map(
|
|
90
|
+
(member) => transforms.reduce((m, t) => t(m), member)
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
};
|
|
95
|
+
return apiExtractorModel.ApiPackage.deserialize(
|
|
96
|
+
transformed,
|
|
97
|
+
transformed.metadata
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
static transformArrowComponents = (member) => {
|
|
101
|
+
if (member.kind !== "Variable") {
|
|
102
|
+
return member;
|
|
103
|
+
}
|
|
104
|
+
const { name, excerptTokens } = member;
|
|
105
|
+
const [firstChar] = name;
|
|
106
|
+
if (firstChar.toLocaleUpperCase("en-US") !== firstChar) {
|
|
107
|
+
return member;
|
|
108
|
+
}
|
|
109
|
+
const tokens = new ExcerptTokenMatcher(excerptTokens);
|
|
110
|
+
if (tokens.nextContent() !== `${name}: `) {
|
|
111
|
+
return member;
|
|
112
|
+
}
|
|
113
|
+
const declStart = tokens.nextContent();
|
|
114
|
+
if (declStart === "(props: " || declStart === "(_props: ") {
|
|
115
|
+
const props = tokens.getTokensUntilArrow();
|
|
116
|
+
const ret = tokens.getComponentReturnTokens();
|
|
117
|
+
if (props && ret) {
|
|
118
|
+
return this.makeComponentMember(member, ret, props);
|
|
119
|
+
}
|
|
120
|
+
} else if (declStart === "() => ") {
|
|
121
|
+
const ret = tokens.getComponentReturnTokens();
|
|
122
|
+
if (ret) {
|
|
123
|
+
return this.makeComponentMember(member, ret);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return member;
|
|
127
|
+
};
|
|
128
|
+
static makeComponentMember(member, ret, props) {
|
|
129
|
+
const declTokens = props ? [
|
|
130
|
+
{
|
|
131
|
+
kind: "Content",
|
|
132
|
+
text: `export declare function ${member.name}(props: `
|
|
133
|
+
},
|
|
134
|
+
...props,
|
|
135
|
+
{
|
|
136
|
+
kind: "Content",
|
|
137
|
+
text: "): "
|
|
138
|
+
}
|
|
139
|
+
] : [
|
|
140
|
+
{
|
|
141
|
+
kind: "Content",
|
|
142
|
+
text: `export declare function ${member.name}(): `
|
|
143
|
+
}
|
|
144
|
+
];
|
|
145
|
+
return {
|
|
146
|
+
kind: "Function",
|
|
147
|
+
name: member.name,
|
|
148
|
+
releaseTag: member.releaseTag,
|
|
149
|
+
docComment: member.docComment ?? "",
|
|
150
|
+
canonicalReference: member.canonicalReference,
|
|
151
|
+
excerptTokens: [...declTokens, ...ret],
|
|
152
|
+
returnTypeTokenRange: {
|
|
153
|
+
startIndex: declTokens.length,
|
|
154
|
+
endIndex: declTokens.length + ret.length
|
|
155
|
+
},
|
|
156
|
+
parameters: props ? [
|
|
157
|
+
{
|
|
158
|
+
parameterName: "props",
|
|
159
|
+
parameterTypeTokenRange: {
|
|
160
|
+
startIndex: 1,
|
|
161
|
+
endIndex: 1 + props.length
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
] : [],
|
|
165
|
+
overloadIndex: 1
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
static transformTrimDeclare = (member) => {
|
|
169
|
+
const { excerptTokens } = member;
|
|
170
|
+
const firstContent = new ExcerptTokenMatcher(excerptTokens).nextContent();
|
|
171
|
+
if (firstContent && firstContent.startsWith("export declare ")) {
|
|
172
|
+
return {
|
|
173
|
+
...member,
|
|
174
|
+
excerptTokens: [
|
|
175
|
+
{
|
|
176
|
+
kind: "Content",
|
|
177
|
+
text: firstContent.slice("export declare ".length)
|
|
178
|
+
},
|
|
179
|
+
...excerptTokens.slice(1)
|
|
180
|
+
]
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return member;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
async function buildDocs({
|
|
187
|
+
inputDir,
|
|
188
|
+
outputDir
|
|
189
|
+
}) {
|
|
190
|
+
const parseFile = async (filename) => {
|
|
191
|
+
console.log(`Reading ${filename}`);
|
|
192
|
+
return fs__default.default.readJson(path.resolve(inputDir, filename));
|
|
193
|
+
};
|
|
194
|
+
const filenames = await fs__default.default.readdir(inputDir);
|
|
195
|
+
const serializedPackages = await Promise.all(
|
|
196
|
+
filenames.filter((filename) => filename.match(/\.api\.json$/i)).map(parseFile)
|
|
197
|
+
);
|
|
198
|
+
const newModel = new apiExtractorModel.ApiModel();
|
|
199
|
+
for (const serialized of serializedPackages) {
|
|
200
|
+
newModel.addMember(
|
|
201
|
+
ApiModelTransforms.deserializeWithTransforms(serialized, [
|
|
202
|
+
ApiModelTransforms.transformArrowComponents,
|
|
203
|
+
ApiModelTransforms.transformTrimDeclare
|
|
204
|
+
])
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
class DocFrontMatter extends tsdoc.DocNode {
|
|
208
|
+
static kind = "DocFrontMatter";
|
|
209
|
+
values;
|
|
210
|
+
constructor(parameters) {
|
|
211
|
+
super(parameters);
|
|
212
|
+
this.values = parameters.values;
|
|
213
|
+
}
|
|
214
|
+
/** @override */
|
|
215
|
+
get kind() {
|
|
216
|
+
return DocFrontMatter.kind;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
class DocCodeSpanLink extends tsdoc.DocLinkTag {
|
|
220
|
+
static kind = "DocCodeSpanLink";
|
|
221
|
+
/** @override */
|
|
222
|
+
get kind() {
|
|
223
|
+
return DocCodeSpanLink.kind;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
class CustomCustomMarkdownEmitter extends CustomMarkdownEmitter.CustomMarkdownEmitter {
|
|
227
|
+
// Until https://github.com/microsoft/rushstack/issues/2914 gets fixed or we change markdown renderer we need a fix
|
|
228
|
+
// to render pipe | character correctly.
|
|
229
|
+
getEscapedText(text) {
|
|
230
|
+
return text.replace(/\\/g, "\\\\").replace(/[*#[\]_`~]/g, (x) => `\\${x}`).replace(/---/g, "\\-\\-\\-").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\|/g, "|");
|
|
231
|
+
}
|
|
232
|
+
/** @override */
|
|
233
|
+
writeNode(docNode, context, docNodeSiblings) {
|
|
234
|
+
switch (docNode.kind) {
|
|
235
|
+
case DocFrontMatter.kind: {
|
|
236
|
+
const node = docNode;
|
|
237
|
+
context.writer.writeLine("---");
|
|
238
|
+
for (const [name, value] of Object.entries(node.values)) {
|
|
239
|
+
if (value) {
|
|
240
|
+
context.writer.writeLine(
|
|
241
|
+
`${name}: "${String(value).replace(/\"/g, "")}"`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
context.writer.writeLine("---");
|
|
246
|
+
context.writer.writeLine();
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
case "BlockTag": {
|
|
250
|
+
const node = docNode;
|
|
251
|
+
if (node.tagName === "@config") {
|
|
252
|
+
context.writer.writeLine("## Related config ");
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
case DocCodeSpanLink.kind: {
|
|
257
|
+
const node = docNode;
|
|
258
|
+
if (node.codeDestination) {
|
|
259
|
+
super.writeLinkTagWithCodeDestination(node, context);
|
|
260
|
+
} else if (node.urlDestination) {
|
|
261
|
+
const linkText = node.linkText !== void 0 ? node.linkText : node.urlDestination;
|
|
262
|
+
const encodedLinkText = this.getEscapedText(
|
|
263
|
+
linkText.replace(/\s+/g, " ")
|
|
264
|
+
);
|
|
265
|
+
context.writer.write("[");
|
|
266
|
+
context.writer.write(`\`${encodedLinkText}\``);
|
|
267
|
+
context.writer.write(`](${node.urlDestination})`);
|
|
268
|
+
} else if (node.linkText) {
|
|
269
|
+
this.writePlainText(node.linkText, context);
|
|
270
|
+
}
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
default:
|
|
274
|
+
super.writeNode(docNode, context, docNodeSiblings);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/** @override */
|
|
278
|
+
emit(stringBuilder, docNode, options) {
|
|
279
|
+
stringBuilder._chunks.length = 0;
|
|
280
|
+
return super.emit(stringBuilder, docNode, options);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
class CustomMarkdownDocumenter extends MarkdownDocumenter.MarkdownDocumenter {
|
|
284
|
+
constructor(options) {
|
|
285
|
+
super(options);
|
|
286
|
+
this._tsdocConfiguration.docNodeManager.registerDocNodes("@backstage/docs", [
|
|
287
|
+
{ docNodeKind: DocFrontMatter.kind, constructor: DocFrontMatter }
|
|
288
|
+
]);
|
|
289
|
+
this._tsdocConfiguration.docNodeManager.registerDocNodes("@backstage/docs", [
|
|
290
|
+
{ docNodeKind: DocCodeSpanLink.kind, constructor: DocCodeSpanLink }
|
|
291
|
+
]);
|
|
292
|
+
this._tsdocConfiguration.docNodeManager.registerAllowableChildren("Paragraph", [
|
|
293
|
+
DocFrontMatter.kind,
|
|
294
|
+
DocCodeSpanLink.kind
|
|
295
|
+
]);
|
|
296
|
+
const def = {
|
|
297
|
+
tagName: "@config",
|
|
298
|
+
syntaxKind: tsdoc.TSDocTagSyntaxKind.BlockTag,
|
|
299
|
+
tagNameWithUpperCase: "@CONFIG",
|
|
300
|
+
standardization: tsdoc.Standardization.Extended,
|
|
301
|
+
allowMultiple: false
|
|
302
|
+
};
|
|
303
|
+
this._tsdocConfiguration.addTagDefinition(def);
|
|
304
|
+
this._tsdocConfiguration.setSupportForTag(
|
|
305
|
+
def,
|
|
306
|
+
true
|
|
307
|
+
);
|
|
308
|
+
this._markdownEmitter = new CustomCustomMarkdownEmitter(newModel);
|
|
309
|
+
}
|
|
310
|
+
_getFilenameForApiItem(apiItem) {
|
|
311
|
+
const filename = super._getFilenameForApiItem(apiItem);
|
|
312
|
+
if (filename.includes(".html.")) {
|
|
313
|
+
return filename.replace(/\.html\./g, "._html.");
|
|
314
|
+
}
|
|
315
|
+
return filename;
|
|
316
|
+
}
|
|
317
|
+
// We don't really get many chances to modify the generated AST
|
|
318
|
+
// so we hook in wherever we can. In this case we add the front matter
|
|
319
|
+
// just before writing the breadcrumbs at the top.
|
|
320
|
+
/** @override */
|
|
321
|
+
_writeBreadcrumb(output, apiItem) {
|
|
322
|
+
let title;
|
|
323
|
+
let description;
|
|
324
|
+
const name = apiItem.getScopedNameWithinPackage();
|
|
325
|
+
if (name) {
|
|
326
|
+
title = name;
|
|
327
|
+
description = `API reference for ${apiItem.getScopedNameWithinPackage()}`;
|
|
328
|
+
} else if (apiItem.kind === "Model") {
|
|
329
|
+
title = "Package Index";
|
|
330
|
+
description = "Index of all Backstage Packages";
|
|
331
|
+
} else if (apiItem.name) {
|
|
332
|
+
title = apiItem.name;
|
|
333
|
+
description = `API Reference for ${apiItem.name}`;
|
|
334
|
+
} else {
|
|
335
|
+
title = apiItem.displayName;
|
|
336
|
+
description = `API Reference for ${apiItem.displayName}`;
|
|
337
|
+
}
|
|
338
|
+
output.appendNodeInParagraph(
|
|
339
|
+
new DocFrontMatter({
|
|
340
|
+
configuration: this._tsdocConfiguration,
|
|
341
|
+
values: {
|
|
342
|
+
id: this._getFilenameForApiItem(apiItem).slice(0, -3),
|
|
343
|
+
title,
|
|
344
|
+
description
|
|
345
|
+
}
|
|
346
|
+
})
|
|
347
|
+
);
|
|
348
|
+
const configuration = this._tsdocConfiguration;
|
|
349
|
+
output.appendNodeInParagraph(
|
|
350
|
+
new tsdoc.DocLinkTag({
|
|
351
|
+
configuration,
|
|
352
|
+
tagName: "@link",
|
|
353
|
+
linkText: "Home",
|
|
354
|
+
urlDestination: this._getLinkFilenameForApiItem(this._apiModel)
|
|
355
|
+
})
|
|
356
|
+
);
|
|
357
|
+
for (const hierarchyItem of apiItem.getHierarchy()) {
|
|
358
|
+
switch (hierarchyItem.kind) {
|
|
359
|
+
case apiExtractorModel.ApiItemKind.Model:
|
|
360
|
+
case apiExtractorModel.ApiItemKind.EntryPoint:
|
|
361
|
+
break;
|
|
362
|
+
default:
|
|
363
|
+
output.appendNodesInParagraph([
|
|
364
|
+
new tsdoc.DocPlainText({
|
|
365
|
+
configuration,
|
|
366
|
+
text: " > "
|
|
367
|
+
}),
|
|
368
|
+
new DocCodeSpanLink({
|
|
369
|
+
configuration,
|
|
370
|
+
tagName: "@link",
|
|
371
|
+
linkText: hierarchyItem.displayName,
|
|
372
|
+
urlDestination: this._getLinkFilenameForApiItem(hierarchyItem)
|
|
373
|
+
})
|
|
374
|
+
]);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
const oldAppendNode = output.appendNode;
|
|
378
|
+
output.appendNode = () => {
|
|
379
|
+
output.appendNode = oldAppendNode;
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
_writeModelTable(output, apiModel) {
|
|
383
|
+
const configuration = this._tsdocConfiguration;
|
|
384
|
+
const packagesTable = new DocTable.DocTable({
|
|
385
|
+
configuration,
|
|
386
|
+
headerTitles: ["Package", "Description"]
|
|
387
|
+
});
|
|
388
|
+
const pluginsTable = new DocTable.DocTable({
|
|
389
|
+
configuration,
|
|
390
|
+
headerTitles: ["Package", "Description"]
|
|
391
|
+
});
|
|
392
|
+
for (const apiMember of apiModel.members) {
|
|
393
|
+
const row = new DocTableRow.DocTableRow({ configuration }, [
|
|
394
|
+
this._createTitleCell(apiMember),
|
|
395
|
+
this._createDescriptionCell(apiMember)
|
|
396
|
+
]);
|
|
397
|
+
if (apiMember.kind === "Package") {
|
|
398
|
+
this._writeApiItemPage(apiMember);
|
|
399
|
+
if (apiMember.name.startsWith("@backstage/plugin-")) {
|
|
400
|
+
pluginsTable.addRow(row);
|
|
401
|
+
} else {
|
|
402
|
+
packagesTable.addRow(row);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (packagesTable.rows.length > 0) {
|
|
407
|
+
output.appendNode(
|
|
408
|
+
new DocHeading.DocHeading({
|
|
409
|
+
configuration: this._tsdocConfiguration,
|
|
410
|
+
title: "Packages"
|
|
411
|
+
})
|
|
412
|
+
);
|
|
413
|
+
output.appendNode(packagesTable);
|
|
414
|
+
}
|
|
415
|
+
if (pluginsTable.rows.length > 0) {
|
|
416
|
+
output.appendNode(
|
|
417
|
+
new DocHeading.DocHeading({
|
|
418
|
+
configuration: this._tsdocConfiguration,
|
|
419
|
+
title: "Plugins"
|
|
420
|
+
})
|
|
421
|
+
);
|
|
422
|
+
output.appendNode(pluginsTable);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
const documenter = new CustomMarkdownDocumenter({
|
|
427
|
+
apiModel: newModel,
|
|
428
|
+
documenterConfig: {
|
|
429
|
+
outputTarget: "markdown",
|
|
430
|
+
newlineKind: "\n",
|
|
431
|
+
// De ba dålig kod
|
|
432
|
+
configFilePath: "",
|
|
433
|
+
configFile: {}
|
|
434
|
+
},
|
|
435
|
+
outputFolder: outputDir
|
|
436
|
+
});
|
|
437
|
+
await fs__default.default.remove(outputDir);
|
|
438
|
+
await fs__default.default.ensureDir(outputDir);
|
|
439
|
+
documenter.generateFiles();
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
exports.buildDocs = buildDocs;
|
|
443
|
+
//# sourceMappingURL=buildDocs.cjs.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('fs-extra');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var paths = require('../../../lib/paths.cjs.js');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
10
|
+
|
|
11
|
+
async function createTemporaryTsConfig(includedPackageDirs) {
|
|
12
|
+
const path$1 = paths.paths.resolveTargetRoot("tsconfig.tmp.json");
|
|
13
|
+
process.once("exit", () => {
|
|
14
|
+
fs__default.default.removeSync(path$1);
|
|
15
|
+
});
|
|
16
|
+
let assetTypeFile = [];
|
|
17
|
+
try {
|
|
18
|
+
assetTypeFile = [
|
|
19
|
+
require.resolve("@backstage/cli/asset-types/asset-types.d.ts")
|
|
20
|
+
];
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
await fs__default.default.writeJson(path$1, {
|
|
24
|
+
extends: "./tsconfig.json",
|
|
25
|
+
include: [
|
|
26
|
+
// These two contain global definitions that are needed for stable API report generation
|
|
27
|
+
...assetTypeFile,
|
|
28
|
+
...includedPackageDirs.map((dir) => path.join(dir, "src"))
|
|
29
|
+
],
|
|
30
|
+
// we don't exclude node_modules so that we can use the asset-types.d.ts file
|
|
31
|
+
exclude: []
|
|
32
|
+
});
|
|
33
|
+
return path$1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
exports.createTemporaryTsConfig = createTemporaryTsConfig;
|
|
37
|
+
//# sourceMappingURL=createTemporaryTsConfig.cjs.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var fs = require('fs-extra');
|
|
4
4
|
var child_process = require('child_process');
|
|
5
|
-
var paths = require('
|
|
5
|
+
var paths = require('../../../lib/paths.cjs.js');
|
|
6
6
|
|
|
7
7
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
8
8
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var tryRunPrettier = require('../common/tryRunPrettier.cjs.js');
|
|
4
|
+
|
|
5
|
+
let applied = false;
|
|
6
|
+
function patchApiReportGeneration() {
|
|
7
|
+
if (applied) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
applied = true;
|
|
11
|
+
const {
|
|
12
|
+
ApiReportGenerator
|
|
13
|
+
} = require("@microsoft/api-extractor/lib/generators/ApiReportGenerator");
|
|
14
|
+
function patchFileMessageFetcher(router, transform) {
|
|
15
|
+
const {
|
|
16
|
+
fetchAssociatedMessagesForReviewFile,
|
|
17
|
+
fetchUnassociatedMessagesForReviewFile
|
|
18
|
+
} = router;
|
|
19
|
+
router.fetchAssociatedMessagesForReviewFile = function patchedFetchAssociatedMessagesForReviewFile(ast) {
|
|
20
|
+
const messages = fetchAssociatedMessagesForReviewFile.call(this, ast);
|
|
21
|
+
return transform(messages, ast);
|
|
22
|
+
};
|
|
23
|
+
router.fetchUnassociatedMessagesForReviewFile = function patchedFetchUnassociatedMessagesForReviewFile() {
|
|
24
|
+
const messages = fetchUnassociatedMessagesForReviewFile.call(this);
|
|
25
|
+
return transform(messages);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const originalGenerateReviewFileContent = ApiReportGenerator.generateReviewFileContent;
|
|
29
|
+
ApiReportGenerator.generateReviewFileContent = function decoratedGenerateReviewFileContent(collector, ...moreArgs) {
|
|
30
|
+
const program = collector.program;
|
|
31
|
+
patchFileMessageFetcher(
|
|
32
|
+
collector.messageRouter,
|
|
33
|
+
(messages) => {
|
|
34
|
+
return messages.filter((message) => {
|
|
35
|
+
if (message.messageId !== "ae-forgotten-export") {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
const symbolMatch = message.text.match(/The symbol "([^"]+)"/);
|
|
39
|
+
if (!symbolMatch) {
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Failed to extract symbol name from message "${message.text}"`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
const [, symbolName] = symbolMatch;
|
|
45
|
+
const sourceFile = message.sourceFilePath && program.getSourceFile(message.sourceFilePath);
|
|
46
|
+
if (!sourceFile) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Failed to find source file in program at path "${message.sourceFilePath}"`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
let localName = sourceFile.identifiers?.get(symbolName);
|
|
52
|
+
if (!localName) {
|
|
53
|
+
const [, trimmedSymbolName] = symbolName.match(/(.*)_\d+/) || [];
|
|
54
|
+
localName = sourceFile.identifiers?.get(
|
|
55
|
+
trimmedSymbolName
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (!localName) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`Unable to find local name of "${symbolName}" in ${sourceFile.fileName}`
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const local = sourceFile.locals?.get(localName);
|
|
64
|
+
if (!local) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const type = program.getTypeChecker().getDeclaredTypeOfSymbol(local);
|
|
68
|
+
if (!type) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Unable to find type declaration of "${symbolName}" in ${sourceFile.fileName}`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const declarations = type.aliasSymbol?.declarations;
|
|
74
|
+
if (!declarations || declarations.length === 0) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
const isIgnored = declarations.some((declaration) => {
|
|
78
|
+
const tags = [declaration.jsDoc].flat().filter(Boolean).flatMap((tagNode) => tagNode.tags);
|
|
79
|
+
return tags.some((tag) => tag?.tagName.text === "ignore");
|
|
80
|
+
});
|
|
81
|
+
return !isIgnored;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
const content = originalGenerateReviewFileContent.call(
|
|
86
|
+
this,
|
|
87
|
+
collector,
|
|
88
|
+
...moreArgs
|
|
89
|
+
);
|
|
90
|
+
return tryRunPrettier.tryRunPrettier(content);
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
exports.patchApiReportGeneration = patchApiReportGeneration;
|
|
95
|
+
//# sourceMappingURL=patchApiReportGeneration.cjs.js.map
|