@backstage/repo-tools 0.1.2 → 0.1.3-next.0

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # @backstage/repo-tools
2
2
 
3
+ ## 0.1.3-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 32a4a05838: Tweaked type dependency check to trim wildcard type imports.
8
+ - 6ba8faf22a: The API report generation process is now able to detect and generate reports for additional entry points declared in the package `"exports"` field.
9
+ - Updated dependencies
10
+ - @backstage/cli-common@0.1.11
11
+ - @backstage/errors@1.1.4
12
+
3
13
  ## 0.1.2
4
14
 
5
15
  ### Patch Changes
@@ -17,6 +17,7 @@ var g = require('glob');
17
17
  var isGlob = require('is-glob');
18
18
  var util = require('util');
19
19
  var minimatch = require('minimatch');
20
+ var entryPoints = require('./entryPoints-c420d90d.cjs.js');
20
21
 
21
22
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
22
23
 
@@ -193,10 +194,9 @@ async function createTemporaryTsConfig(includedPackageDirs) {
193
194
  });
194
195
  return path$1;
195
196
  }
196
- async function countApiReportWarnings(projectFolder) {
197
- const path$1 = path.resolve(projectFolder, "api-report.md");
197
+ async function countApiReportWarnings(reportPath) {
198
198
  try {
199
- const content = await fs__default["default"].readFile(path$1, "utf8");
199
+ const content = await fs__default["default"].readFile(reportPath, "utf8");
200
200
  const lines = content.split("\n");
201
201
  const lineWarnings = lines.filter(
202
202
  (line) => line.includes("// Warning:")
@@ -245,18 +245,37 @@ function logApiReportInstructions() {
245
245
  );
246
246
  console.log("");
247
247
  }
248
+ async function findPackageEntryPoints(packageDirs) {
249
+ return Promise.all(
250
+ packageDirs.map(async (packageDir) => {
251
+ var _a, _b, _c, _d;
252
+ const pkg = await fs__default["default"].readJson(
253
+ paths.resolveTargetRoot(packageDir, "package.json")
254
+ );
255
+ return (_d = (_a = entryPoints.getPackageExportNames(pkg)) == null ? void 0 : _a.map((name) => ({ packageDir, name }))) != null ? _d : {
256
+ packageDir,
257
+ name: "index",
258
+ usesExperimentalTypeBuild: (_c = (_b = pkg.scripts) == null ? void 0 : _b.build) == null ? void 0 : _c.includes(
259
+ "--experimental-type-build"
260
+ )
261
+ };
262
+ })
263
+ ).then((results) => results.flat());
264
+ }
248
265
  async function runApiExtraction({
249
266
  packageDirs,
250
267
  outputDir,
251
268
  isLocalBuild,
252
269
  tsconfigFilePath,
253
270
  allowWarnings = false,
254
- omitMessages = []
271
+ omitMessages = [],
272
+ validateReleaseTags = false
255
273
  }) {
256
274
  await fs__default["default"].remove(outputDir);
257
- const entryPoints = packageDirs.map((packageDir) => {
275
+ const packageEntryPoints = await findPackageEntryPoints(packageDirs);
276
+ const entryPoints = packageEntryPoints.map(({ packageDir, name }) => {
258
277
  return paths.resolveTargetRoot(
259
- `./dist-types/${packageDir}/src/index.d.ts`
278
+ `./dist-types/${packageDir}/src/${name}.d.ts`
260
279
  );
261
280
  });
262
281
  let compilerState = void 0;
@@ -268,7 +287,11 @@ async function runApiExtraction({
268
287
  };
269
288
  }
270
289
  const warnings = new Array();
271
- for (const packageDir of packageDirs) {
290
+ for (const {
291
+ packageDir,
292
+ name,
293
+ usesExperimentalTypeBuild
294
+ } of packageEntryPoints) {
272
295
  console.log(`## Processing ${packageDir}`);
273
296
  const noBail = Array.isArray(allowWarnings) ? allowWarnings.some((aw) => aw === packageDir || minimatch__default["default"](packageDir, aw)) : allowWarnings;
274
297
  const projectFolder = paths.resolveTargetRoot(packageDir);
@@ -276,25 +299,33 @@ async function runApiExtraction({
276
299
  "./dist-types",
277
300
  packageDir
278
301
  );
279
- const warningCountBefore = await countApiReportWarnings(projectFolder);
302
+ const prefix = name === "index" ? "" : `${name}-`;
303
+ const reportFileName = `${prefix}api-report.md`;
304
+ const reportPath = path.resolve(projectFolder, reportFileName);
305
+ const warningCountBefore = await countApiReportWarnings(reportPath);
280
306
  const extractorConfig = apiExtractor.ExtractorConfig.prepare({
281
307
  configObject: {
282
- mainEntryPointFilePath: path.resolve(packageFolder, "src/index.d.ts"),
308
+ mainEntryPointFilePath: path.resolve(packageFolder, `src/${name}.d.ts`),
283
309
  bundledPackages: [],
284
310
  compiler: {
285
311
  tsconfigFilePath
286
312
  },
287
313
  apiReport: {
288
314
  enabled: true,
289
- reportFileName: "api-report.md",
315
+ reportFileName,
290
316
  reportFolder: projectFolder,
291
- reportTempFolder: path.resolve(outputDir, "<unscopedPackageName>")
317
+ reportTempFolder: path.resolve(
318
+ outputDir,
319
+ `${prefix}<unscopedPackageName>`
320
+ )
292
321
  },
293
322
  docModel: {
294
- enabled: true,
323
+ // TODO(Rugvip): This skips docs for non-index entry points. We can try to work around it, but
324
+ // most likely it makes sense to wait for API Extractor to natively support exports.
325
+ enabled: name === "index",
295
326
  apiJsonFilePath: path.resolve(
296
327
  outputDir,
297
- "<unscopedPackageName>.api.json"
328
+ `${prefix}<unscopedPackageName>.api.json`
298
329
  )
299
330
  },
300
331
  dtsRollup: {
@@ -363,6 +394,28 @@ async function runApiExtraction({
363
394
  },
364
395
  compilerState
365
396
  });
397
+ if (validateReleaseTags && !usesExperimentalTypeBuild) {
398
+ if (["index", "alpha", "beta"].includes(name)) {
399
+ const report = await fs__default["default"].readFile(
400
+ extractorConfig.reportFilePath,
401
+ "utf8"
402
+ );
403
+ const lines = report.split(/\r?\n/);
404
+ const expectedTag = name === "index" ? "public" : name;
405
+ for (let i = 0; i < lines.length; i += 1) {
406
+ const line = lines[i];
407
+ const match = line.match(/^\/\/ @(alpha|beta|public)/);
408
+ if (match && match[1] !== expectedTag) {
409
+ if (expectedTag !== "public" && match[1] === "public") {
410
+ continue;
411
+ }
412
+ throw new Error(
413
+ `Unexpected release tag ${match[1]} in ${extractorConfig.reportFilePath} at line ${i + 1}`
414
+ );
415
+ }
416
+ }
417
+ }
418
+ }
366
419
  if (!extractorResult.succeeded) {
367
420
  if (shouldLogInstructions) {
368
421
  logApiReportInstructions();
@@ -384,7 +437,7 @@ async function runApiExtraction({
384
437
  `API Extractor completed with ${extractorResult.errorCount} errors and ${extractorResult.warningCount} warnings`
385
438
  );
386
439
  }
387
- const warningCountAfter = await countApiReportWarnings(projectFolder);
440
+ const warningCountAfter = await countApiReportWarnings(reportPath);
388
441
  if (noBail) {
389
442
  console.log(`Skipping warnings check for ${packageDir}`);
390
443
  }
@@ -1102,7 +1155,8 @@ const buildApiReports = async (paths$1 = [], opts) => {
1102
1155
  isLocalBuild: !isCiBuild,
1103
1156
  tsconfigFilePath,
1104
1157
  allowWarnings: allowAllWarnings || allowWarnings,
1105
- omitMessages: Array.isArray(omitMessages) ? omitMessages : []
1158
+ omitMessages: Array.isArray(omitMessages) ? omitMessages : [],
1159
+ validateReleaseTags: opts.validateReleaseTags
1106
1160
  });
1107
1161
  }
1108
1162
  if (cliPackageDirs.length > 0) {
@@ -1136,4 +1190,4 @@ function parseArrayOption(value) {
1136
1190
  }
1137
1191
 
1138
1192
  exports.buildApiReports = buildApiReports;
1139
- //# sourceMappingURL=api-reports-a8ff4901.cjs.js.map
1193
+ //# sourceMappingURL=api-reports-a4583315.cjs.js.map
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var path = require('path');
4
+
5
+ function getPackageExportNames(pkg) {
6
+ if (pkg.exports && typeof pkg.exports !== "string") {
7
+ return Object.entries(pkg.exports).flatMap(([mount, path$1]) => {
8
+ const ext = path.extname(String(path$1));
9
+ if (![".ts", ".tsx", ".cts", ".mts"].includes(ext)) {
10
+ return [];
11
+ }
12
+ let name = mount;
13
+ if (name.startsWith("./")) {
14
+ name = name.slice(2);
15
+ }
16
+ if (!name || name === ".") {
17
+ return ["index"];
18
+ }
19
+ return [name];
20
+ });
21
+ }
22
+ return void 0;
23
+ }
24
+
25
+ exports.getPackageExportNames = getPackageExportNames;
26
+ //# sourceMappingURL=entryPoints-c420d90d.cjs.js.map
@@ -4,6 +4,7 @@ var fs = require('fs');
4
4
  var path = require('path');
5
5
  var chalk = require('chalk');
6
6
  var getPackages = require('@manypkg/get-packages');
7
+ var entryPoints = require('./entryPoints-c420d90d.cjs.js');
7
8
 
8
9
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
9
10
 
@@ -63,15 +64,22 @@ function findAllDeps(declSrc) {
63
64
  return Array.from(/* @__PURE__ */ new Set([...importedDeps, ...referencedDeps]));
64
65
  }
65
66
  function checkTypes(pkg) {
66
- const typeDecl = fs__default["default"].readFileSync(
67
- path.resolve(pkg.dir, "dist/index.d.ts"),
68
- "utf8"
69
- );
70
- const allDeps = findAllDeps(typeDecl);
67
+ var _a;
68
+ const entryPointNames = (_a = entryPoints.getPackageExportNames(pkg.packageJson)) != null ? _a : ["index"];
69
+ const allDeps = entryPointNames.flatMap((name) => {
70
+ const typeDecl = fs__default["default"].readFileSync(
71
+ path.resolve(pkg.dir, `dist/${name}.d.ts`),
72
+ "utf8"
73
+ );
74
+ return findAllDeps(typeDecl);
75
+ });
71
76
  const deps = Array.from(new Set(allDeps));
72
77
  const errors = [];
73
78
  const typeDeps = [];
74
- for (const dep of deps) {
79
+ for (let dep of deps) {
80
+ if (dep.endsWith("/*")) {
81
+ dep = dep.slice(0, -2);
82
+ }
75
83
  try {
76
84
  const typeDep = findTypesPackage(dep, pkg);
77
85
  if (typeDep) {
@@ -166,4 +174,4 @@ function mkErr(name, msg, extra) {
166
174
  }
167
175
 
168
176
  exports["default"] = typeDeps;
169
- //# sourceMappingURL=type-deps-fba15630.cjs.js.map
177
+ //# sourceMappingURL=type-deps-db1fb735.cjs.js.map
package/dist/index.cjs.js CHANGED
@@ -48,12 +48,15 @@ function registerCommands(program) {
48
48
  ).option(
49
49
  "-o, --omit-messages <messageCodes>",
50
50
  "select some message code to be omited on the API Extractor (comma separated values i.e ae-cyclic-inherit-doc,ae-missing-getter )"
51
+ ).option(
52
+ "--validate-release-tags",
53
+ "Turn on release tag validation for the public, beta, and alpha APIs"
51
54
  ).description("Generate an API report for selected packages").action(
52
55
  lazy(
53
- () => Promise.resolve().then(function () { return require('./cjs/api-reports-a8ff4901.cjs.js'); }).then((m) => m.buildApiReports)
56
+ () => Promise.resolve().then(function () { return require('./cjs/index/api-reports-a4583315.cjs.js'); }).then((m) => m.buildApiReports)
54
57
  )
55
58
  );
56
- program.command("type-deps").description("Find inconsistencies in types of all packages and plugins").action(lazy(() => Promise.resolve().then(function () { return require('./cjs/type-deps-fba15630.cjs.js'); }).then((m) => m.default)));
59
+ program.command("type-deps").description("Find inconsistencies in types of all packages and plugins").action(lazy(() => Promise.resolve().then(function () { return require('./cjs/index/type-deps-db1fb735.cjs.js'); }).then((m) => m.default)));
57
60
  }
58
61
  function lazy(getActionFunc) {
59
62
  return async (...args) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@backstage/repo-tools",
3
3
  "description": "CLI for Backstage repo tooling ",
4
- "version": "0.1.2",
4
+ "version": "0.1.3-next.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -44,7 +44,8 @@
44
44
  "ts-node": "^10.0.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@backstage/cli": "^0.22.2",
47
+ "@backstage/cli": "^0.22.4-next.0",
48
+ "@backstage/types": "^1.0.2",
48
49
  "@types/is-glob": "^4.0.2",
49
50
  "@types/mock-fs": "^4.13.0",
50
51
  "mock-fs": "^5.1.0"