@backstage/repo-tools 0.16.5 → 0.17.0-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.
Files changed (31) hide show
  1. package/CHANGELOG.md +31 -2
  2. package/dist/commands/api-reports/api-reports/createTemporaryTsConfig.cjs.js +2 -2
  3. package/dist/commands/api-reports/api-reports/generateTypeDeclarations.cjs.js +2 -3
  4. package/dist/commands/api-reports/api-reports/patchApiReportGeneration.cjs.js +2 -2
  5. package/dist/commands/api-reports/api-reports/runApiExtraction.cjs.js +6 -15
  6. package/dist/commands/api-reports/buildApiReports.cjs.js +4 -5
  7. package/dist/commands/api-reports/categorizePackageDirs.cjs.js +3 -3
  8. package/dist/commands/api-reports/cli-reports/runCliExtraction.cjs.js +17 -8
  9. package/dist/commands/api-reports/common/tryRunPrettier.cjs.js +3 -3
  10. package/dist/commands/api-reports/sql-reports/runSqlExtraction.cjs.js +6 -6
  11. package/dist/commands/index.cjs.js +1 -1
  12. package/dist/commands/knip-reports/knip-extractor.cjs.js +6 -6
  13. package/dist/commands/lint-legacy-backend-exports/lint-legacy-backend-exports.cjs.js +2 -2
  14. package/dist/commands/package/schema/openapi/diff.cjs.js +4 -4
  15. package/dist/commands/package/schema/openapi/fuzz.cjs.js +3 -3
  16. package/dist/commands/package/schema/openapi/generate/client.cjs.js +12 -6
  17. package/dist/commands/package/schema/openapi/generate/server.cjs.js +13 -7
  18. package/dist/commands/package/schema/openapi/init.cjs.js +4 -4
  19. package/dist/commands/package-docs/command.cjs.js +17 -22
  20. package/dist/commands/package-docs/utils.cjs.js +5 -2
  21. package/dist/commands/repo/schema/openapi/diff.cjs.js +3 -3
  22. package/dist/commands/repo/schema/openapi/lint.cjs.js +4 -3
  23. package/dist/commands/repo/schema/openapi/test.cjs.js +8 -3
  24. package/dist/commands/repo/schema/openapi/verify.cjs.js +2 -2
  25. package/dist/commands/util.cjs.js +37 -42
  26. package/dist/lib/openapi/helpers.cjs.js +25 -2
  27. package/dist/lib/paths.cjs.js +7 -7
  28. package/dist/lib/runner.cjs.js +2 -1
  29. package/dist/package.json.cjs.js +1 -1
  30. package/openapitools.json +1 -1
  31. package/package.json +12 -12
package/CHANGELOG.md CHANGED
@@ -1,10 +1,39 @@
1
1
  # @backstage/repo-tools
2
2
 
3
- ## 0.16.5
3
+ ## 0.17.0-next.1
4
+
5
+ ### Minor Changes
6
+
7
+ - 0fbcf23: Added support for OpenAPI 3.1 to all `schema openapi` commands. The commands now auto-detect the OpenAPI version from the spec file and use the appropriate generator, supporting both OpenAPI 3.0.x and 3.1.x specifications.
4
8
 
5
9
  ### Patch Changes
6
10
 
7
- - e67d18a: Updated `@microsoft/api-extractor` to `7.57.3` and added tests for `getTsDocConfig`
11
+ - 426edbe: Fixed `generate-catalog-info` command failing with "too many arguments" when invoked by lint-staged via the pre-commit hook.
12
+ - d5779e5: Updated the CLI report parser to support cleye-style help output, and strip ANSI escape codes from captured output.
13
+ - Updated dependencies
14
+ - @backstage/cli-common@0.2.0-next.1
15
+ - @backstage/cli-node@0.2.19-next.1
16
+ - @backstage/backend-plugin-api@1.7.1-next.0
17
+ - @backstage/catalog-model@1.7.6
18
+ - @backstage/config-loader@1.10.9-next.0
19
+ - @backstage/errors@1.2.7
20
+
21
+ ## 0.16.6-next.0
22
+
23
+ ### Patch Changes
24
+
25
+ - 6738cf0: build(deps): bump `minimatch` from 9.0.5 to 10.2.1
26
+ - 2a51546: Fixed prettier existence checks in OpenAPI commands to use `fs.pathExists` instead of checking the resolved path string, which was always truthy.
27
+ - 70fc178: Migrated from deprecated `findPaths` to `targetPaths` and `findOwnPaths` from `@backstage/cli-common`.
28
+ - de62a9d: Upgraded `commander` dependency from `^12.0.0` to `^14.0.3` across all CLI packages.
29
+ - 18a946c: Updated `@microsoft/api-extractor` to `7.57.3` and added tests for `getTsDocConfig`
30
+ - Updated dependencies
31
+ - @backstage/cli-common@0.2.0-next.0
32
+ - @backstage/cli-node@0.2.19-next.0
33
+ - @backstage/config-loader@1.10.9-next.0
34
+ - @backstage/backend-plugin-api@1.7.1-next.0
35
+ - @backstage/catalog-model@1.7.6
36
+ - @backstage/errors@1.2.7
8
37
 
9
38
  ## 0.16.4
10
39
 
@@ -2,14 +2,14 @@
2
2
 
3
3
  var fs = require('fs-extra');
4
4
  var path = require('node:path');
5
- var paths = require('../../../lib/paths.cjs.js');
5
+ var cliCommon = require('@backstage/cli-common');
6
6
 
7
7
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
8
 
9
9
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
10
10
 
11
11
  async function createTemporaryTsConfig(includedPackageDirs) {
12
- const path$1 = paths.paths.resolveTargetRoot("tsconfig.tmp.json");
12
+ const path$1 = cliCommon.targetPaths.resolveRoot("tsconfig.tmp.json");
13
13
  process.once("exit", () => {
14
14
  fs__default.default.removeSync(path$1);
15
15
  });
@@ -2,14 +2,13 @@
2
2
 
3
3
  var fs = require('fs-extra');
4
4
  var cliCommon = require('@backstage/cli-common');
5
- var paths = require('../../../lib/paths.cjs.js');
6
5
 
7
6
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
7
 
9
8
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
10
9
 
11
10
  async function generateTypeDeclarations(tsconfigFilePath) {
12
- await fs__default.default.remove(paths.paths.resolveTargetRoot("dist-types"));
11
+ await fs__default.default.remove(cliCommon.targetPaths.resolveRoot("dist-types"));
13
12
  try {
14
13
  await cliCommon.run(
15
14
  [
@@ -23,7 +22,7 @@ async function generateTypeDeclarations(tsconfigFilePath) {
23
22
  "false"
24
23
  ],
25
24
  {
26
- cwd: paths.paths.targetRoot
25
+ cwd: cliCommon.targetPaths.rootDir
27
26
  }
28
27
  ).waitForExit();
29
28
  } catch (error) {
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var tryRunPrettier = require('../common/tryRunPrettier.cjs.js');
4
- var paths = require('../../../lib/paths.cjs.js');
4
+ var cliCommon = require('@backstage/cli-common');
5
5
 
6
6
  let applied = false;
7
7
  function patchApiReportGeneration() {
@@ -92,7 +92,7 @@ function patchApiReportGeneration() {
92
92
  parser: "markdown",
93
93
  // We need a real-looking filepath for proper config resolution, not just a directory
94
94
  // Ideally, the real filepath would be better, but it would require too much patching, for very little gain.
95
- filepath: `${paths.paths.targetRoot}/report.api.md`
95
+ filepath: `${cliCommon.targetPaths.rootDir}/report.api.md`
96
96
  });
97
97
  };
98
98
  }
@@ -8,7 +8,7 @@ var lodash = require('lodash');
8
8
  var minimatch = require('minimatch');
9
9
  var path = require('node:path');
10
10
  var getPackageExportDetails = require('../../../lib/getPackageExportDetails.cjs.js');
11
- var paths = require('../../../lib/paths.cjs.js');
11
+ var cliCommon = require('@backstage/cli-common');
12
12
  var logApiReportInstructions = require('../common/logApiReportInstructions.cjs.js');
13
13
  var patchApiReportGeneration = require('./patchApiReportGeneration.cjs.js');
14
14
 
@@ -16,9 +16,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
16
16
 
17
17
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
18
18
 
19
- const tmpDir = paths.paths.resolveTargetRoot(
20
- "./node_modules/.cache/api-extractor"
21
- );
19
+ const tmpDir = cliCommon.targetPaths.resolveRoot("./node_modules/.cache/api-extractor");
22
20
  async function countApiReportWarnings(reportPath) {
23
21
  try {
24
22
  const content = await fs__default.default.readFile(reportPath, "utf8");
@@ -58,7 +56,7 @@ async function findPackageEntryPoints(packageDirs) {
58
56
  return Promise.all(
59
57
  packageDirs.map(async (packageDir) => {
60
58
  const pkg = await fs__default.default.readJson(
61
- paths.paths.resolveTargetRoot(packageDir, "package.json")
59
+ cliCommon.targetPaths.resolveRoot(packageDir, "package.json")
62
60
  );
63
61
  return getPackageExportDetails.getPackageExportDetails(pkg).map((details) => {
64
62
  return { packageDir, ...details };
@@ -80,11 +78,7 @@ async function runApiExtraction({
80
78
  const allEntryPoints = await findPackageEntryPoints(packageDirs);
81
79
  const allDistTypesEntryPointPaths = allEntryPoints.map(
82
80
  ({ packageDir, distTypesPath }) => {
83
- return paths.paths.resolveTargetRoot(
84
- "./dist-types",
85
- packageDir,
86
- distTypesPath
87
- );
81
+ return cliCommon.targetPaths.resolveRoot("./dist-types", packageDir, distTypesPath);
88
82
  }
89
83
  );
90
84
  let compilerState = void 0;
@@ -101,11 +95,8 @@ async function runApiExtraction({
101
95
  )) {
102
96
  console.log(`## Processing ${packageDir}`);
103
97
  const noBail = Array.isArray(allowWarnings) ? allowWarnings.some((aw) => aw === packageDir || minimatch.minimatch(packageDir, aw)) : allowWarnings;
104
- const projectFolder = paths.paths.resolveTargetRoot(packageDir);
105
- const packageFolder = paths.paths.resolveTargetRoot(
106
- "./dist-types",
107
- packageDir
108
- );
98
+ const projectFolder = cliCommon.targetPaths.resolveRoot(packageDir);
99
+ const packageFolder = cliCommon.targetPaths.resolveRoot("./dist-types", packageDir);
109
100
  const remainingReportFiles = new Set(
110
101
  fs__default.default.readdirSync(projectFolder).filter(
111
102
  (filename) => (
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var categorizePackageDirs = require('./categorizePackageDirs.cjs.js');
4
+ var cliCommon = require('@backstage/cli-common');
4
5
  var paths = require('../../lib/paths.cjs.js');
5
6
  var runSqlExtraction = require('./sql-reports/runSqlExtraction.cjs.js');
6
7
  var runCliExtraction = require('./cli-reports/runCliExtraction.cjs.js');
@@ -10,9 +11,7 @@ var createTemporaryTsConfig = require('./api-reports/createTemporaryTsConfig.cjs
10
11
  var generateTypeDeclarations = require('./api-reports/generateTypeDeclarations.cjs.js');
11
12
 
12
13
  async function buildApiReports(paths$1 = [], opts) {
13
- const tmpDir = paths.paths.resolveTargetRoot(
14
- "./node_modules/.cache/api-extractor"
15
- );
14
+ const tmpDir = cliCommon.targetPaths.resolveRoot("./node_modules/.cache/api-extractor");
16
15
  const isCiBuild = opts.ci;
17
16
  const isDocsBuild = opts.docs;
18
17
  const runTsc = opts.tsc;
@@ -40,7 +39,7 @@ async function buildApiReports(paths$1 = [], opts) {
40
39
  if (!isAllPackages) {
41
40
  temporaryTsConfigPath = await createTemporaryTsConfig.createTemporaryTsConfig(selectedPackageDirs);
42
41
  }
43
- const tsconfigFilePath = temporaryTsConfigPath ?? paths.paths.resolveTargetRoot("tsconfig.json");
42
+ const tsconfigFilePath = temporaryTsConfigPath ?? cliCommon.targetPaths.resolveRoot("tsconfig.json");
44
43
  if (runTsc) {
45
44
  console.log("# Compiling TypeScript");
46
45
  await generateTypeDeclarations.generateTypeDeclarations(tsconfigFilePath);
@@ -76,7 +75,7 @@ async function buildApiReports(paths$1 = [], opts) {
76
75
  console.log("# Generating package documentation");
77
76
  await buildDocs.buildDocs({
78
77
  inputDir: tmpDir,
79
- outputDir: paths.paths.resolveTargetRoot("docs/reference")
78
+ outputDir: cliCommon.targetPaths.resolveRoot("docs/reference")
80
79
  });
81
80
  }
82
81
  }
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var fs = require('fs-extra');
4
- var paths = require('../../lib/paths.cjs.js');
4
+ var cliCommon = require('@backstage/cli-common');
5
5
 
6
6
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
7
7
 
@@ -19,7 +19,7 @@ async function categorizePackageDirs(packageDirs) {
19
19
  if (!dir) {
20
20
  return;
21
21
  }
22
- const pkgJson = await fs__default.default.readJson(paths.paths.resolveTargetRoot(dir, "package.json")).catch((error) => {
22
+ const pkgJson = await fs__default.default.readJson(cliCommon.targetPaths.resolveRoot(dir, "package.json")).catch((error) => {
23
23
  if (error.code === "ENOENT") {
24
24
  return void 0;
25
25
  }
@@ -29,7 +29,7 @@ async function categorizePackageDirs(packageDirs) {
29
29
  if (!role) {
30
30
  return;
31
31
  }
32
- if (await fs__default.default.pathExists(paths.paths.resolveTargetRoot(dir, "migrations"))) {
32
+ if (await fs__default.default.pathExists(cliCommon.targetPaths.resolveRoot(dir, "migrations"))) {
33
33
  sqlPackageDirs.push(dir);
34
34
  }
35
35
  if (pkgJson?.backstage?.inline) {
@@ -3,7 +3,7 @@
3
3
  var path = require('node:path');
4
4
  var fs = require('fs-extra');
5
5
  var util = require('../../util.cjs.js');
6
- var paths = require('../../../lib/paths.cjs.js');
6
+ var cliCommon = require('@backstage/cli-common');
7
7
  var generateCliReport = require('./generateCliReport.cjs.js');
8
8
  var logApiReportInstructions = require('../common/logApiReportInstructions.cjs.js');
9
9
 
@@ -12,7 +12,11 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
12
12
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
13
13
 
14
14
  function parseHelpPage(helpPageContent) {
15
- const [, usage] = helpPageContent.match(/^\s*Usage: (.*)$/im) ?? [];
15
+ let usage;
16
+ const commanderUsage = helpPageContent.match(/^\s*Usage: (.*)$/im);
17
+ if (commanderUsage) {
18
+ usage = commanderUsage[1];
19
+ }
16
20
  const lines = helpPageContent.split(/\r?\n/);
17
21
  let options = new Array();
18
22
  let commands = new Array();
@@ -22,19 +26,24 @@ function parseHelpPage(helpPageContent) {
22
26
  lines.shift();
23
27
  }
24
28
  if (lines.length > 0) {
25
- const sectionName = lines.shift();
29
+ const sectionName = lines.shift()?.toLocaleLowerCase("en-US");
26
30
  const sectionEndIndex = lines.findIndex(
27
31
  (line) => line && !line.match(/^\s/)
28
32
  );
29
33
  const sectionLines = lines.slice(0, sectionEndIndex);
30
34
  lines.splice(0, sectionLines.length);
31
35
  const sectionItems = sectionLines.map((line) => line.match(/^\s{1,8}(.*?)\s\s+/)?.[1]).filter(Boolean);
32
- if (sectionName?.toLocaleLowerCase("en-US") === "options:") {
36
+ if (sectionName === "options:" || sectionName === "flags:") {
33
37
  options = sectionItems;
34
- } else if (sectionName?.toLocaleLowerCase("en-US") === "commands:") {
38
+ } else if (sectionName === "commands:") {
35
39
  commands = sectionItems;
36
- } else if (sectionName?.toLocaleLowerCase("en-US") === "arguments:") {
40
+ } else if (sectionName === "arguments:") {
37
41
  commandArguments = sectionItems;
42
+ } else if (sectionName === "usage:") {
43
+ const usageLine = sectionLines.find((l) => l.trim().length > 0)?.trim();
44
+ if (usageLine) {
45
+ usage = usageLine;
46
+ }
38
47
  } else {
39
48
  throw new Error(`Unknown CLI section: ${sectionName}`);
40
49
  }
@@ -75,7 +84,7 @@ async function runCliExtraction({
75
84
  }) {
76
85
  for (const packageDir of packageDirs) {
77
86
  console.log(`## Processing ${packageDir}`);
78
- const fullDir = paths.paths.resolveTargetRoot(packageDir);
87
+ const fullDir = cliCommon.targetPaths.resolveRoot(packageDir);
79
88
  const pkgJson = await fs__default.default.readJson(path.resolve(fullDir, "package.json"));
80
89
  if (!pkgJson.bin) {
81
90
  throw new Error(`CLI Package in ${packageDir} has no bin field`);
@@ -114,7 +123,7 @@ async function runCliExtraction({
114
123
  console.log("");
115
124
  console.log(
116
125
  `The conflicting file is ${path.relative(
117
- paths.paths.targetRoot,
126
+ cliCommon.targetPaths.rootDir,
118
127
  reportPath
119
128
  )}, expecting the following content:`
120
129
  );
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var paths = require('../../../lib/paths.cjs.js');
3
+ var cliCommon = require('@backstage/cli-common');
4
4
 
5
5
  async function tryRunPrettierAsync(content, extraConfig = { parser: "markdown" }) {
6
6
  try {
7
7
  const prettier = require("prettier");
8
- const filepath = extraConfig.filepath ?? `${paths.paths.targetRoot}/should-not-be-ignored.any`;
8
+ const filepath = extraConfig.filepath ?? `${cliCommon.targetPaths.rootDir}/should-not-be-ignored.any`;
9
9
  const config = await prettier.resolveConfig(filepath, { editorconfig: true }) ?? {};
10
10
  const formattedContent = prettier.format(content, {
11
11
  ...config,
@@ -22,7 +22,7 @@ async function tryRunPrettierAsync(content, extraConfig = { parser: "markdown" }
22
22
  function createPrettierSyncFormatter(prettierSync, extraConfig = {}) {
23
23
  return function tryRunPrettierInner(content) {
24
24
  try {
25
- const filepath = extraConfig.filepath ?? `${paths.paths.targetRoot}/should-not-be-ignored.any`;
25
+ const filepath = extraConfig.filepath ?? `${cliCommon.targetPaths.rootDir}/should-not-be-ignored.any`;
26
26
  const resolveConfig = (
27
27
  // @ts-expect-error: v2 requires .sync, @prettier/sync v3 does not
28
28
  prettierSync.resolveConfig?.sync ?? prettierSync.resolveConfig
@@ -2,7 +2,7 @@
2
2
 
3
3
  var fs = require('fs-extra');
4
4
  var path = require('node:path');
5
- var paths = require('../../../lib/paths.cjs.js');
5
+ var cliCommon = require('@backstage/cli-common');
6
6
  var justDiff = require('just-diff');
7
7
  var getPgSchemaInfo = require('./getPgSchemaInfo.cjs.js');
8
8
  var generateSqlReport = require('./generateSqlReport.cjs.js');
@@ -23,13 +23,13 @@ async function runSqlExtraction(options) {
23
23
  }
24
24
  let dbIndex = 1;
25
25
  for (const packageDir of options.packageDirs) {
26
- const migrationDir = paths.paths.resolveTargetRoot(packageDir, "migrations");
26
+ const migrationDir = cliCommon.targetPaths.resolveRoot(packageDir, "migrations");
27
27
  if (!await fs__default.default.pathExists(migrationDir)) {
28
28
  console.log(`No SQL migrations found in ${packageDir}`);
29
29
  continue;
30
30
  }
31
31
  const { name: pkgName } = await fs.readJson(
32
- paths.paths.resolveTargetRoot(packageDir, "package.json")
32
+ cliCommon.targetPaths.resolveRoot(packageDir, "package.json")
33
33
  );
34
34
  const migrationFiles = await fs__default.default.readdir(migrationDir, {
35
35
  withFileTypes: true
@@ -59,7 +59,7 @@ async function runSqlExtraction(options) {
59
59
  }
60
60
  }
61
61
  async function runSingleSqlExtraction(targetDir, migrationTarget, pkgName, knex, options) {
62
- const migrationDir = paths.paths.resolveTargetRoot(
62
+ const migrationDir = cliCommon.targetPaths.resolveRoot(
63
63
  targetDir,
64
64
  "migrations",
65
65
  migrationTarget
@@ -106,7 +106,7 @@ async function runSingleSqlExtraction(targetDir, migrationTarget, pkgName, knex,
106
106
  break;
107
107
  }
108
108
  }
109
- const reportPath = paths.paths.resolveTargetRoot(
109
+ const reportPath = cliCommon.targetPaths.resolveRoot(
110
110
  targetDir,
111
111
  `report${migrationTarget === "." ? "" : `-${migrationTarget}`}.sql.md`
112
112
  );
@@ -134,7 +134,7 @@ async function runSingleSqlExtraction(targetDir, migrationTarget, pkgName, knex,
134
134
  console.log("");
135
135
  console.log(
136
136
  `The conflicting file is ${path.relative(
137
- paths.paths.targetRoot,
137
+ cliCommon.targetPaths.rootDir,
138
138
  reportPath
139
139
  )}, expecting the following content:`
140
140
  );
@@ -108,7 +108,7 @@ function registerCommands(program) {
108
108
  ).option(
109
109
  "--ci",
110
110
  "CI run checks that there are no changes to catalog-info.yaml files"
111
- ).description("Create or fix info yaml files for all backstage packages").action(
111
+ ).description("Create or fix info yaml files for all backstage packages").allowExcessArguments(true).action(
112
112
  lazy(
113
113
  () => import('./generate-catalog-info/generate-catalog-info.cjs.js'),
114
114
  "default"
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var paths = require('../../lib/paths.cjs.js');
3
+ var cliCommon = require('@backstage/cli-common');
4
4
  var pLimit = require('p-limit');
5
5
  var os = require('node:os');
6
6
  var path = require('node:path');
@@ -77,9 +77,9 @@ async function handlePackage({
77
77
  isLocalBuild
78
78
  }) {
79
79
  console.log(`## Processing ${packageDir}`);
80
- const fullDir = paths.paths.resolveTargetRoot(packageDir);
80
+ const fullDir = cliCommon.targetPaths.resolveRoot(packageDir);
81
81
  const reportPath = path.resolve(fullDir, "knip-report.md");
82
- const run = util.createBinRunner(paths.paths.targetRoot, "");
82
+ const run = util.createBinRunner(cliCommon.targetPaths.rootDir, "");
83
83
  let report = await run(
84
84
  `${knipDir}/knip.js`,
85
85
  "-W",
@@ -122,7 +122,7 @@ async function handlePackage({
122
122
  console.log("");
123
123
  console.log(
124
124
  `The conflicting file is ${path.relative(
125
- paths.paths.targetRoot,
125
+ cliCommon.targetPaths.rootDir,
126
126
  reportPath
127
127
  )}, expecting the following content:`
128
128
  );
@@ -138,8 +138,8 @@ async function runKnipReports({
138
138
  packageDirs,
139
139
  isLocalBuild
140
140
  }) {
141
- const knipDir = paths.paths.resolveTargetRoot("./node_modules/knip/bin/");
142
- const knipConfigPath = paths.paths.resolveTargetRoot("./knip.json");
141
+ const knipDir = cliCommon.targetPaths.resolveRoot("./node_modules/knip/bin/");
142
+ const knipConfigPath = cliCommon.targetPaths.resolveRoot("./knip.json");
143
143
  const limiter = pLimit__default.default(os__default.default.cpus().length);
144
144
  await generateKnipConfig({ knipConfigPath });
145
145
  try {
@@ -3,7 +3,7 @@
3
3
  var tsMorph = require('ts-morph');
4
4
  var cliNode = require('@backstage/cli-node');
5
5
  var fs = require('fs-extra');
6
- var paths = require('../../lib/paths.cjs.js');
6
+ var cliCommon = require('@backstage/cli-common');
7
7
  var path = require('node:path');
8
8
 
9
9
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
@@ -12,7 +12,7 @@ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
12
12
  var path__default = /*#__PURE__*/_interopDefaultCompat(path);
13
13
 
14
14
  const project = new tsMorph.Project({
15
- tsConfigFilePath: paths.paths.resolveTargetRoot("tsconfig.json")
15
+ tsConfigFilePath: cliCommon.targetPaths.resolveRoot("tsconfig.json")
16
16
  });
17
17
  function readPackageJson(pkg) {
18
18
  return JSON.parse(fs__default.default.readFileSync(path__default.default.join(pkg, "package.json"), "utf-8"));
@@ -3,7 +3,7 @@
3
3
  var chalk = require('chalk');
4
4
  var exec = require('../../../../lib/exec.cjs.js');
5
5
  var helpers = require('../../../../lib/openapi/helpers.cjs.js');
6
- var paths = require('../../../../lib/paths.cjs.js');
6
+ var cliCommon = require('@backstage/cli-common');
7
7
  var node_process = require('node:process');
8
8
  var promises = require('node:fs/promises');
9
9
  var path = require('node:path');
@@ -37,7 +37,7 @@ async function check(opts) {
37
37
  baseRef
38
38
  ],
39
39
  {
40
- cwd: paths.paths.targetRoot,
40
+ cwd: cliCommon.targetPaths.rootDir,
41
41
  env: { CI: opts.json ? "1" : void 0, ...node_process.env }
42
42
  }
43
43
  );
@@ -47,13 +47,13 @@ async function check(opts) {
47
47
  failed = true;
48
48
  }
49
49
  if (opts.json) {
50
- const file = (await promises.readFile(path.resolve(paths.paths.targetRoot, "ci-run-details.json"))).toString();
50
+ const file = (await promises.readFile(path.resolve(cliCommon.targetPaths.rootDir, "ci-run-details.json"))).toString();
51
51
  const results = JSON.parse(file);
52
52
  console.log(file);
53
53
  if (!opts.ignore && results.failed) {
54
54
  throw new Error("Some checks failed");
55
55
  }
56
- await promises.rm(path.resolve(paths.paths.targetRoot, "ci-run-details.json"));
56
+ await promises.rm(path.resolve(cliCommon.targetPaths.rootDir, "ci-run-details.json"));
57
57
  } else {
58
58
  console.log(reduceOpticOutput(output));
59
59
  if (!opts.ignore && failed) {
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var fs = require('fs-extra');
4
- var paths = require('../../../../lib/paths.cjs.js');
4
+ var cliCommon = require('@backstage/cli-common');
5
5
  var chalk = require('chalk');
6
6
  var exec = require('../../../../lib/exec.cjs.js');
7
7
  var helpers = require('../../../../lib/openapi/helpers.cjs.js');
@@ -30,7 +30,7 @@ async function fuzz(opts) {
30
30
  await fs__default.default.readFile(resolvedOpenapiPath, "utf8")
31
31
  );
32
32
  const configSource = configLoader.ConfigSources.default({
33
- rootDir: paths.paths.targetRoot
33
+ rootDir: cliCommon.targetPaths.rootDir
34
34
  });
35
35
  const config = await configLoader.ConfigSources.toConfig(configSource);
36
36
  const pluginId = openapiSpec.info.title;
@@ -38,7 +38,7 @@ async function fuzz(opts) {
38
38
  if (opts.debug) {
39
39
  args.push(
40
40
  "--cassette-path",
41
- paths.paths.resolveTargetRoot(path.join(".cassettes", `${pluginId}.yml`))
41
+ cliCommon.targetPaths.resolveRoot(path.join(".cassettes", `${pluginId}.yml`))
42
42
  );
43
43
  }
44
44
  if (opts.limit) {
@@ -7,8 +7,8 @@ var path = require('node:path');
7
7
  var exec = require('../../../../../lib/exec.cjs.js');
8
8
  var constants = require('../../../../../lib/openapi/constants.cjs.js');
9
9
  var dedupeImports = require('../../../../../lib/openapi/dedupe-imports.cjs.js');
10
+ var cliCommon = require('@backstage/cli-common');
10
11
  var helpers = require('../../../../../lib/openapi/helpers.cjs.js');
11
- var paths = require('../../../../../lib/paths.cjs.js');
12
12
 
13
13
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
14
14
 
@@ -17,13 +17,14 @@ var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
17
17
 
18
18
  async function generate(outputDirectory, clientAdditionalProperties, abortSignal) {
19
19
  const resolvedOpenapiPath = await helpers.getPathToCurrentOpenApiSpec();
20
- const resolvedOutputDirectory = paths.paths.resolveTargetRoot(
20
+ const resolvedOutputDirectory = cliCommon.targetPaths.resolveRoot(
21
21
  outputDirectory,
22
22
  constants.OUTPUT_PATH
23
23
  );
24
24
  const additionalProperties = helpers.toGeneratorAdditionalProperties({
25
25
  initialValue: clientAdditionalProperties
26
26
  });
27
+ const generatorKey = await helpers.getOpenApiGeneratorKey(resolvedOpenapiPath);
27
28
  await fs__default.default.emptyDir(resolvedOutputDirectory);
28
29
  await fs__default.default.writeFile(
29
30
  path.resolve(resolvedOutputDirectory, ".openapi-generator-ignore"),
@@ -46,7 +47,7 @@ async function generate(outputDirectory, clientAdditionalProperties, abortSignal
46
47
  "templates/typescript-backstage-client.yaml"
47
48
  ),
48
49
  "--generator-key",
49
- "v3.0",
50
+ generatorKey,
50
51
  additionalProperties ? `--additional-properties=${additionalProperties}` : ""
51
52
  ],
52
53
  {
@@ -61,14 +62,14 @@ async function generate(outputDirectory, clientAdditionalProperties, abortSignal
61
62
  const parentDirectory = path.resolve(resolvedOutputDirectory, "..");
62
63
  await fs__default.default.writeFile(
63
64
  path.resolve(parentDirectory, "index.ts"),
64
- `//
65
+ `//
65
66
  export * from './generated';`
66
67
  );
67
68
  await exec.exec(`yarn backstage-cli package lint --fix ${parentDirectory}`, [], {
68
69
  signal: abortSignal?.signal
69
70
  });
70
- const prettier = paths.paths.resolveTargetRoot("node_modules/.bin/prettier");
71
- if (prettier) {
71
+ const prettier = cliCommon.targetPaths.resolveRoot("node_modules/.bin/prettier");
72
+ if (await fs__default.default.pathExists(prettier)) {
72
73
  await exec.exec(`${prettier} --write ${parentDirectory}`, [], {
73
74
  signal: abortSignal?.signal
74
75
  });
@@ -80,6 +81,11 @@ async function generate(outputDirectory, clientAdditionalProperties, abortSignal
80
81
  }
81
82
  }
82
83
  fs__default.default.removeSync(path.resolve(resolvedOutputDirectory, ".openapi-generator-ignore"));
84
+ fs__default.default.removeSync(path.resolve(resolvedOutputDirectory, ".gitattributes"));
85
+ fs__default.default.rmSync(path.resolve(resolvedOutputDirectory, "docs"), {
86
+ recursive: true,
87
+ force: true
88
+ });
83
89
  fs__default.default.rmSync(path.resolve(resolvedOutputDirectory, ".openapi-generator"), {
84
90
  recursive: true,
85
91
  force: true
@@ -8,8 +8,8 @@ var path = require('node:path');
8
8
  var exec = require('../../../../../lib/exec.cjs.js');
9
9
  var constants = require('../../../../../lib/openapi/constants.cjs.js');
10
10
  var dedupeImports = require('../../../../../lib/openapi/dedupe-imports.cjs.js');
11
+ var cliCommon = require('@backstage/cli-common');
11
12
  var helpers = require('../../../../../lib/openapi/helpers.cjs.js');
12
- var paths = require('../../../../../lib/paths.cjs.js');
13
13
 
14
14
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
15
15
 
@@ -20,10 +20,10 @@ var YAML__default = /*#__PURE__*/_interopDefaultCompat(YAML);
20
20
  async function generateSpecFile() {
21
21
  const openapiPath = await helpers.getPathToCurrentOpenApiSpec();
22
22
  const yaml = YAML__default.default.load(await fs__default.default.readFile(openapiPath, "utf8"));
23
- const tsPath = paths.paths.resolveTarget(constants.TS_SCHEMA_PATH);
23
+ const tsPath = cliCommon.targetPaths.resolve(constants.TS_SCHEMA_PATH);
24
24
  const schemaDir = path.dirname(tsPath);
25
25
  await fs__default.default.mkdirp(schemaDir);
26
- const oldTsPath = paths.paths.resolveTarget(constants.OLD_SCHEMA_PATH);
26
+ const oldTsPath = cliCommon.targetPaths.resolve(constants.OLD_SCHEMA_PATH);
27
27
  if (fs__default.default.existsSync(oldTsPath)) {
28
28
  console.warn(`Removing old schema file at ${oldTsPath}`);
29
29
  fs__default.default.removeSync(oldTsPath);
@@ -50,9 +50,9 @@ export const createOpenApiRouter = async (
50
50
  export * from './generated';`
51
51
  );
52
52
  await exec.exec(`yarn backstage-cli package lint`, ["--fix", tsPath, indexFile]);
53
- if (await paths.paths.resolveTargetRoot("node_modules/.bin/prettier")) {
53
+ if (await fs__default.default.pathExists(cliCommon.targetPaths.resolveRoot("node_modules/.bin/prettier"))) {
54
54
  await exec.exec(`yarn prettier`, ["--write", tsPath, indexFile], {
55
- cwd: paths.paths.targetRoot
55
+ cwd: cliCommon.targetPaths.rootDir
56
56
  });
57
57
  }
58
58
  }
@@ -67,6 +67,7 @@ async function generate(serverAdditionalProperties, abortSignal) {
67
67
  const additionalProperties = helpers.toGeneratorAdditionalProperties({
68
68
  initialValue: serverAdditionalProperties
69
69
  });
70
+ const generatorKey = await helpers.getOpenApiGeneratorKey(resolvedOpenapiPath);
70
71
  await exec.exec(
71
72
  "node",
72
73
  [
@@ -84,7 +85,7 @@ async function generate(serverAdditionalProperties, abortSignal) {
84
85
  "templates/typescript-backstage-server.yaml"
85
86
  ),
86
87
  "--generator-key",
87
- "v3.0",
88
+ generatorKey,
88
89
  additionalProperties ? `--additional-properties=${additionalProperties}` : ""
89
90
  ],
90
91
  {
@@ -109,13 +110,18 @@ async function generate(serverAdditionalProperties, abortSignal) {
109
110
  signal: abortSignal?.signal
110
111
  }
111
112
  );
112
- const prettier = paths.paths.resolveTargetRoot("node_modules/.bin/prettier");
113
+ const prettier = cliCommon.targetPaths.resolveRoot("node_modules/.bin/prettier");
113
114
  if (prettier) {
114
115
  await exec.exec(`${prettier} --write ${resolvedOutputDirectory}`, [], {
115
116
  signal: abortSignal?.signal
116
117
  });
117
118
  }
118
119
  fs__default.default.removeSync(path.resolve(resolvedOutputDirectory, ".openapi-generator-ignore"));
120
+ fs__default.default.removeSync(path.resolve(resolvedOutputDirectory, ".gitattributes"));
121
+ fs__default.default.rmSync(path.resolve(resolvedOutputDirectory, "docs"), {
122
+ recursive: true,
123
+ force: true
124
+ });
119
125
  fs__default.default.rmSync(path.resolve(resolvedOutputDirectory, ".openapi-generator"), {
120
126
  recursive: true,
121
127
  force: true
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var fs = require('fs-extra');
4
+ var cliCommon = require('@backstage/cli-common');
4
5
  var constants = require('../../../../lib/openapi/constants.cjs.js');
5
- var paths = require('../../../../lib/paths.cjs.js');
6
6
  var chalk = require('chalk');
7
7
  var exec = require('../../../../lib/exec.cjs.js');
8
8
  var helpers = require('../../../../lib/openapi/helpers.cjs.js');
@@ -35,7 +35,7 @@ async function init() {
35
35
  capture:
36
36
  ${constants.YAML_SCHEMA_PATH}:
37
37
  # \u{1F527} Runnable example with simple get requests.
38
- # Run with "PORT=3000 optic capture ${constants.YAML_SCHEMA_PATH} --update interactive" in '${paths.paths.targetDir}'
38
+ # Run with "PORT=3000 optic capture ${constants.YAML_SCHEMA_PATH} --update interactive" in '${cliCommon.targetPaths.dir}'
39
39
  # You can change the server and the 'requests' section to experiment
40
40
  server:
41
41
  # This will not be used by 'backstage-repo-tools schema openapi test', but may be useful for interactive updates.
@@ -46,10 +46,10 @@ capture:
46
46
  # \u{1F527} Specify a command that will generate traffic
47
47
  command: yarn backstage-cli package test --no-watch ${ROUTER_TEST_PATHS.map(
48
48
  (e) => `"${e}"`
49
- ).join(" ")}
49
+ ).join(" ")}
50
50
  `
51
51
  );
52
- if (await paths.paths.resolveTargetRoot("node_modules/.bin/prettier")) {
52
+ if (await fs__default.default.pathExists(cliCommon.targetPaths.resolveRoot("node_modules/.bin/prettier"))) {
53
53
  await exec.exec(`yarn prettier`, ["--write", opticConfigFilePath]);
54
54
  }
55
55
  }
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var node_child_process = require('node:child_process');
6
6
  var node_util = require('node:util');
7
+ var cliCommon = require('@backstage/cli-common');
7
8
  var paths = require('../../lib/paths.cjs.js');
8
9
  var utils = require('./utils.cjs.js');
9
10
  var promises = require('node:fs/promises');
@@ -61,22 +62,22 @@ function getExports(packageJson) {
61
62
  async function generateDocJson(pkg) {
62
63
  const temporaryTsConfigPath = await utils.createTemporaryTsConfig(pkg);
63
64
  const packageJson = JSON.parse(
64
- await promises.readFile(paths.paths.resolveTargetRoot(pkg, "package.json"), "utf-8")
65
+ await promises.readFile(cliCommon.targetPaths.resolveRoot(pkg, "package.json"), "utf-8")
65
66
  );
66
67
  const exports$1 = getExports(packageJson);
67
68
  if (!exports$1.length || !exports$1.some((e) => e.startsWith("src") || e.startsWith("./src"))) {
68
69
  return false;
69
70
  }
70
- await fs$1.mkdirp(paths.paths.resolveTargetRoot(`dist-types`, pkg));
71
+ await fs$1.mkdirp(cliCommon.targetPaths.resolveRoot(`dist-types`, pkg));
71
72
  const { stdout, stderr } = await execAsync(
72
73
  [
73
- paths.paths.resolveTargetRoot("node_modules/.bin/typedoc"),
74
+ cliCommon.targetPaths.resolveRoot("node_modules/.bin/typedoc"),
74
75
  "--json",
75
- paths.paths.resolveTargetRoot(`dist-types`, pkg, "docs.json"),
76
+ cliCommon.targetPaths.resolveRoot(`dist-types`, pkg, "docs.json"),
76
77
  "--tsconfig",
77
78
  temporaryTsConfigPath,
78
79
  "--basePath",
79
- paths.paths.targetRoot,
80
+ cliCommon.targetPaths.rootDir,
80
81
  "--skipErrorChecking",
81
82
  ...getExports(packageJson).flatMap((e) => [
82
83
  "--entryPoints",
@@ -96,7 +97,7 @@ async function generateDocJson(pkg) {
96
97
  async function packageDocs(paths$1 = [], opts) {
97
98
  console.warn("!!! This is an experimental command !!!");
98
99
  const existingDocsJsonPaths = glob.glob.sync(
99
- paths.paths.resolveTargetRoot("dist-types/**/docs.json")
100
+ cliCommon.targetPaths.resolveRoot("dist-types/**/docs.json")
100
101
  );
101
102
  if (existingDocsJsonPaths.length > 0) {
102
103
  console.warn(
@@ -107,7 +108,7 @@ async function packageDocs(paths$1 = [], opts) {
107
108
  }
108
109
  }
109
110
  console.warn("!!! Deleting existing docs output !!!");
110
- await promises.rm(paths.paths.resolveTargetRoot("type-docs"), {
111
+ await promises.rm(cliCommon.targetPaths.resolveRoot("type-docs"), {
111
112
  recursive: true,
112
113
  force: true
113
114
  });
@@ -117,18 +118,15 @@ async function packageDocs(paths$1 = [], opts) {
117
118
  exclude: opts.exclude
118
119
  });
119
120
  const cache = await Cache.PackageDocsCache.loadAsync(
120
- paths.paths.resolveTargetRoot(),
121
- await cliNode.Lockfile.load(paths.paths.resolveTargetRoot("yarn.lock"))
121
+ cliCommon.targetPaths.rootDir,
122
+ await cliNode.Lockfile.load(cliCommon.targetPaths.resolveRoot("yarn.lock"))
122
123
  );
123
124
  console.log(`### Generating docs.`);
124
125
  await Promise.all(
125
126
  selectedPackageDirs.map(
126
127
  (pkg) => limit(async () => {
127
128
  const pkgJson = JSON.parse(
128
- await promises.readFile(
129
- paths.paths.resolveTargetRoot(pkg, "package.json"),
130
- "utf-8"
131
- )
129
+ await promises.readFile(cliCommon.targetPaths.resolveRoot(pkg, "package.json"), "utf-8")
132
130
  );
133
131
  if (EXCLUDE.includes(pkg) || pkgJson.name.startsWith("@internal/")) {
134
132
  return;
@@ -147,10 +145,7 @@ async function packageDocs(paths$1 = [], opts) {
147
145
  console.log(`### Processing ${pkg}`);
148
146
  const success = await generateDocJson(pkg);
149
147
  if (success) {
150
- await cache.write(
151
- pkg,
152
- paths.paths.resolveTargetRoot(`dist-types`, pkg)
153
- );
148
+ await cache.write(pkg, cliCommon.targetPaths.resolveRoot(`dist-types`, pkg));
154
149
  }
155
150
  } catch (e) {
156
151
  console.error("Failed to generate docs for", pkg);
@@ -162,7 +157,7 @@ async function packageDocs(paths$1 = [], opts) {
162
157
  const generatedPackageDirs = [];
163
158
  for (const pkg of selectedPackageDirs) {
164
159
  try {
165
- const docsJsonPath = paths.paths.resolveTargetRoot(
160
+ const docsJsonPath = cliCommon.targetPaths.resolveRoot(
166
161
  `dist-types/${pkg}/docs.json`
167
162
  );
168
163
  const docsJson = JSON.parse(await promises.readFile(docsJsonPath, "utf-8"));
@@ -184,7 +179,7 @@ async function packageDocs(paths$1 = [], opts) {
184
179
  }
185
180
  const { stdout, stderr } = await execAsync(
186
181
  [
187
- paths.paths.resolveTargetRoot("node_modules/.bin/typedoc"),
182
+ cliCommon.targetPaths.resolveRoot("node_modules/.bin/typedoc"),
188
183
  "--entryPointStrategy",
189
184
  "merge",
190
185
  ...generatedPackageDirs.flatMap((pkg) => [
@@ -193,11 +188,11 @@ async function packageDocs(paths$1 = [], opts) {
193
188
  ]),
194
189
  ...HIGHLIGHT_LANGUAGES.flatMap((e) => ["--highlightLanguages", e]),
195
190
  "--out",
196
- paths.paths.resolveTargetRoot("type-docs"),
197
- ...fs.existsSync(paths.paths.resolveTargetRoot("typedoc.json")) ? ["--options", paths.paths.resolveTargetRoot("typedoc.json")] : []
191
+ cliCommon.targetPaths.resolveRoot("type-docs"),
192
+ ...fs.existsSync(cliCommon.targetPaths.resolveRoot("typedoc.json")) ? ["--options", cliCommon.targetPaths.resolveRoot("typedoc.json")] : []
198
193
  ].join(" "),
199
194
  {
200
- cwd: paths.paths.targetRoot
195
+ cwd: cliCommon.targetPaths.rootDir
201
196
  }
202
197
  );
203
198
  console.log(stdout);
@@ -1,14 +1,17 @@
1
1
  'use strict';
2
2
 
3
+ var cliCommon = require('@backstage/cli-common');
3
4
  var fs = require('fs-extra');
4
- var paths = require('../../lib/paths.cjs.js');
5
5
 
6
6
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
7
7
 
8
8
  var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
9
9
 
10
10
  async function createTemporaryTsConfig(dir) {
11
- const path = paths.paths.resolveOwnRoot(dir, "tsconfig.typedoc.tmp.json");
11
+ const path = cliCommon.findOwnPaths(__dirname).resolveRoot(
12
+ dir,
13
+ "tsconfig.typedoc.tmp.json"
14
+ );
12
15
  process.once("exit", () => {
13
16
  fs__default.default.removeSync(path);
14
17
  });
@@ -2,12 +2,12 @@
2
2
 
3
3
  var cliNode = require('@backstage/cli-node');
4
4
  var exec = require('../../../../lib/exec.cjs.js');
5
+ var cliCommon = require('@backstage/cli-common');
5
6
  var helpers = require('../../../../lib/openapi/optic/helpers.cjs.js');
6
- var paths = require('../../../../lib/paths.cjs.js');
7
7
  var constants = require('../../../../lib/openapi/constants.cjs.js');
8
8
 
9
9
  function cleanUpApiName(e) {
10
- e.apiName = e.apiName.replace(paths.paths.targetDir, "").replace(constants.YAML_SCHEMA_PATH, "");
10
+ e.apiName = e.apiName.replace(cliCommon.targetPaths.dir, "").replace(constants.YAML_SCHEMA_PATH, "");
11
11
  }
12
12
  async function command(opts) {
13
13
  let packages = await cliNode.PackageGraph.listTargetPackages();
@@ -21,7 +21,7 @@ async function command(opts) {
21
21
  since
22
22
  ]);
23
23
  const changedFiles = changedFilesRaw.toString().trim();
24
- const changedOpenApiSpecs = changedFiles.split("\n").filter((e) => e.endsWith(constants.YAML_SCHEMA_PATH)).map((e) => paths.paths.resolveTarget(e));
24
+ const changedOpenApiSpecs = changedFiles.split("\n").filter((e) => e.endsWith(constants.YAML_SCHEMA_PATH)).map((e) => cliCommon.targetPaths.resolve(e));
25
25
  packages = packages.filter(
26
26
  (pkg) => changedOpenApiSpecs.some((e) => e.startsWith(`${pkg.dir}/`))
27
27
  );
@@ -33,13 +33,14 @@ async function lint(directoryPath, config) {
33
33
  {
34
34
  extends: [spectralRulesets.oas, ruleset__default.default],
35
35
  rules: {
36
- "allow-reserved-in-params": {
37
- given: "$.paths..parameters[*]",
36
+ "allow-reserved-in-query-params": {
37
+ given: '$.paths..parameters[?(@.in == "query")]',
38
38
  then: {
39
39
  field: "allowReserved",
40
40
  function: spectralFunctions.truthy
41
41
  },
42
- severity: "error"
42
+ severity: "error",
43
+ message: "Query parameters must specify allowReserved (true or false)"
43
44
  }
44
45
  },
45
46
  overrides: [
@@ -3,9 +3,9 @@
3
3
  var fs = require('fs-extra');
4
4
  var path = require('node:path');
5
5
  var chalk = require('chalk');
6
+ var cliCommon = require('@backstage/cli-common');
6
7
  var runner = require('../../../../lib/runner.cjs.js');
7
8
  var constants = require('../../../../lib/openapi/constants.cjs.js');
8
- var paths = require('../../../../lib/paths.cjs.js');
9
9
  var exec = require('../../../../lib/exec.cjs.js');
10
10
  var helpers = require('../../../../lib/openapi/helpers.cjs.js');
11
11
 
@@ -27,7 +27,10 @@ async function test(directoryPath, { port }, options) {
27
27
  }
28
28
  let opticLocation = "";
29
29
  try {
30
- opticLocation = (await exec.exec(`yarn bin optic`, [], { cwd: paths.paths.ownRoot })).stdout;
30
+ opticLocation = (await exec.exec(`yarn bin optic`, [], {
31
+ /* eslint-disable-next-line no-restricted-syntax */
32
+ cwd: cliCommon.findOwnPaths(__dirname).rootDir
33
+ })).stdout;
31
34
  } catch (err) {
32
35
  throw new Error(
33
36
  `Failed to find an Optic CLI installation, ensure that you have @useoptic/optic installed in the root of your repo. If not, run yarn add @useoptic/optic from the root of your repo.`
@@ -55,7 +58,9 @@ async function test(directoryPath, { port }, options) {
55
58
  err.message = err.message.split("\n").map((e) => e.replace(/.{1} Sending requests to server/, "")).filter((e) => !e.includes("PASS")).filter((e) => e.trim()).join("\n");
56
59
  throw err;
57
60
  }
58
- if (await paths.paths.resolveTargetRoot("node_modules/.bin/prettier") && options?.update) {
61
+ if (await fs__default.default.pathExists(
62
+ cliCommon.targetPaths.resolveRoot("node_modules/.bin/prettier")
63
+ ) && options?.update) {
59
64
  await exec.exec(`yarn prettier`, ["--write", openapiPath]);
60
65
  }
61
66
  }
@@ -4,8 +4,8 @@ var fs = require('fs-extra');
4
4
  var lodash = require('lodash');
5
5
  var path = require('node:path');
6
6
  var chalk = require('chalk');
7
+ var cliCommon = require('@backstage/cli-common');
7
8
  var runner = require('../../../../lib/runner.cjs.js');
8
- var paths = require('../../../../lib/paths.cjs.js');
9
9
  var constants = require('../../../../lib/openapi/constants.cjs.js');
10
10
  var helpers = require('../../../../lib/openapi/helpers.cjs.js');
11
11
 
@@ -36,7 +36,7 @@ async function verify(directoryPath) {
36
36
  throw new Error(`\`${constants.TS_SCHEMA_PATH}\` needs to have a 'spec' export.`);
37
37
  }
38
38
  if (!lodash.isEqual(schema.spec, yaml)) {
39
- const path$1 = path.relative(paths.paths.targetRoot, directoryPath);
39
+ const path$1 = path.relative(cliCommon.targetPaths.rootDir, directoryPath);
40
40
  throw new Error(
41
41
  `\`${constants.YAML_SCHEMA_PATH}\` and \`${constants.TS_SCHEMA_PATH}\` do not match. Please run \`yarn backstage-repo-tools package schema openapi generate\` from '${path$1}' to regenerate \`${constants.TS_SCHEMA_PATH}\`.`
42
42
  );
@@ -1,53 +1,48 @@
1
1
  'use strict';
2
2
 
3
3
  var node_child_process = require('node:child_process');
4
+ var crypto = require('node:crypto');
5
+ var fs = require('node:fs');
4
6
  var os = require('node:os');
5
- var pLimit = require('p-limit');
7
+ var path = require('node:path');
6
8
 
7
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
8
-
9
- var os__default = /*#__PURE__*/_interopDefaultCompat(os);
10
- var pLimit__default = /*#__PURE__*/_interopDefaultCompat(pLimit);
11
-
12
- const limiter = pLimit__default.default(os__default.default.cpus().length);
13
- function createBinRunner(cwd, path) {
14
- return async (...command) => limiter(
15
- () => new Promise((resolve, reject) => {
16
- const args = path ? [path, ...command] : command;
17
- const child = node_child_process.spawn("node", args, {
9
+ const ansiPattern = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
10
+ function createBinRunner(cwd, path$1) {
11
+ return async (...command) => {
12
+ const args = path$1 ? [path$1, ...command] : command;
13
+ const outPath = path.join(os.tmpdir(), `backstage-cli-out-${crypto.randomUUID()}.txt`);
14
+ const outFd = fs.openSync(outPath, "w");
15
+ try {
16
+ const result = node_child_process.spawnSync("node", args, {
18
17
  cwd,
19
- stdio: ["ignore", "pipe", "pipe"]
20
- });
21
- let stdout = "";
22
- let stderr = "";
23
- child.stdout?.on("data", (data) => {
24
- stdout += data.toString();
18
+ env: { ...process.env, NO_COLOR: "1" },
19
+ stdio: ["ignore", outFd, "pipe"]
25
20
  });
26
- child.stderr?.on("data", (data) => {
27
- stderr += data.toString();
28
- });
29
- child.on("error", (err) => {
30
- reject(new Error(`Process error: ${err.message}`));
31
- });
32
- child.on("close", (code, signal) => {
33
- if (signal) {
34
- reject(
35
- new Error(
36
- `Process was killed with signal ${signal}
21
+ fs.closeSync(outFd);
22
+ const stdout = fs.readFileSync(outPath, "utf8").replace(ansiPattern, "");
23
+ if (result.error) {
24
+ throw new Error(`Process error: ${result.error.message}`);
25
+ }
26
+ const stderr = result.stderr?.toString() ?? "";
27
+ if (result.signal) {
28
+ throw new Error(
29
+ `Process was killed with signal ${result.signal}
37
30
  ${stderr}`
38
- )
39
- );
40
- } else if (code !== 0) {
41
- reject(new Error(`Process exited with code ${code}
42
- ${stderr}`));
43
- } else if (stderr.trim()) {
44
- reject(new Error(`Command printed error output: ${stderr}`));
45
- } else {
46
- resolve(stdout);
47
- }
48
- });
49
- })
50
- );
31
+ );
32
+ } else if (result.status !== 0) {
33
+ throw new Error(`Process exited with code ${result.status}
34
+ ${stderr}`);
35
+ } else if (stderr.trim()) {
36
+ throw new Error(`Command printed error output: ${stderr}`);
37
+ }
38
+ return stdout;
39
+ } finally {
40
+ try {
41
+ fs.unlinkSync(outPath);
42
+ } catch {
43
+ }
44
+ }
45
+ };
51
46
  }
52
47
 
53
48
  exports.createBinRunner = createBinRunner;
@@ -4,8 +4,8 @@ var Parser = require('@apidevtools/swagger-parser');
4
4
  var fs = require('fs-extra');
5
5
  var YAML = require('js-yaml');
6
6
  var lodash = require('lodash');
7
+ var cliCommon = require('@backstage/cli-common');
7
8
  var path = require('node:path');
8
- var paths = require('../paths.cjs.js');
9
9
  var constants = require('./constants.cjs.js');
10
10
 
11
11
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
@@ -18,7 +18,7 @@ const getPathToFile = async (directory, filename) => {
18
18
  return path.resolve(directory, filename);
19
19
  };
20
20
  const getRelativePathToFile = async (filename) => {
21
- return await getPathToFile(paths.paths.targetDir, filename);
21
+ return await getPathToFile(cliCommon.targetPaths.dir, filename);
22
22
  };
23
23
  const assertExists = async (path) => {
24
24
  if (!await fs.pathExists(path)) {
@@ -51,8 +51,31 @@ function toGeneratorAdditionalProperties({
51
51
  );
52
52
  return Object.entries(parsed).map(([key, value]) => `${key}=${value}`).join(",");
53
53
  }
54
+ async function getOpenApiGeneratorKey(specPath) {
55
+ const yaml = await loadAndValidateOpenApiYaml(specPath);
56
+ const version = yaml.openapi;
57
+ if (!version) {
58
+ throw new Error(`Could not determine OpenAPI version from ${specPath}`);
59
+ }
60
+ const semver = /^(\d+)\.(\d+)\.(\d+)(-.+)?$/.exec(version);
61
+ if (!semver) {
62
+ throw new Error(`Invalid OpenAPI version format ${version} in ${specPath}`);
63
+ }
64
+ const [, major, minor] = semver;
65
+ const supportedVersions = ["3.0", "3.1"];
66
+ const majorMinor = `${major}.${minor}`;
67
+ if (!supportedVersions.includes(majorMinor)) {
68
+ throw new Error(
69
+ `Unsupported OpenAPI version ${version} in ${specPath}. Supported versions are: ${supportedVersions.join(
70
+ ", "
71
+ )}`
72
+ );
73
+ }
74
+ return `v${majorMinor}`;
75
+ }
54
76
 
55
77
  exports.assertExists = assertExists;
78
+ exports.getOpenApiGeneratorKey = getOpenApiGeneratorKey;
56
79
  exports.getPathToCurrentOpenApiSpec = getPathToCurrentOpenApiSpec;
57
80
  exports.getPathToFile = getPathToFile;
58
81
  exports.getPathToOpenApiSpec = getPathToOpenApiSpec;
@@ -5,7 +5,6 @@ var cliNode = require('@backstage/cli-node');
5
5
  var minimatch = require('minimatch');
6
6
  var path = require('node:path');
7
7
 
8
- const paths = cliCommon.findPaths(__dirname);
9
8
  async function resolvePackagePaths(options = {}) {
10
9
  const { paths: providedPaths, include, exclude } = options;
11
10
  let packages = await cliNode.PackageGraph.listTargetPackages();
@@ -13,7 +12,7 @@ async function resolvePackagePaths(options = {}) {
13
12
  const invalidPaths = [];
14
13
  for (const path$1 of providedPaths) {
15
14
  const matches = packages.some(
16
- ({ dir }) => new minimatch.Minimatch(path$1).match(path.relative(paths.targetRoot, dir)) || isChildPath(dir, path$1)
15
+ ({ dir }) => new minimatch.Minimatch(path$1).match(path.relative(cliCommon.targetPaths.rootDir, dir)) || isChildPath(dir, path$1)
17
16
  );
18
17
  if (!matches) {
19
18
  invalidPaths.push(path$1);
@@ -26,14 +25,16 @@ async function resolvePackagePaths(options = {}) {
26
25
  if (providedPaths && providedPaths.length > 0) {
27
26
  packages = packages.filter(
28
27
  ({ dir }) => providedPaths.some(
29
- (path$1) => new minimatch.Minimatch(path$1).match(path.relative(paths.targetRoot, dir)) || isChildPath(dir, path$1)
28
+ (path$1) => new minimatch.Minimatch(path$1).match(path.relative(cliCommon.targetPaths.rootDir, dir)) || isChildPath(dir, path$1)
30
29
  )
31
30
  );
32
31
  }
33
32
  if (include) {
34
33
  packages = packages.filter(
35
34
  (pkg) => include.some(
36
- (pattern) => new minimatch.Minimatch(pattern).match(path.relative(paths.targetRoot, pkg.dir))
35
+ (pattern) => new minimatch.Minimatch(pattern).match(
36
+ path.relative(cliCommon.targetPaths.rootDir, pkg.dir)
37
+ )
37
38
  )
38
39
  );
39
40
  }
@@ -41,12 +42,12 @@ async function resolvePackagePaths(options = {}) {
41
42
  packages = packages.filter(
42
43
  (pkg) => exclude.some(
43
44
  (pattern) => !new minimatch.Minimatch(pattern).match(
44
- path.relative(paths.targetRoot, pkg.dir)
45
+ path.relative(cliCommon.targetPaths.rootDir, pkg.dir)
45
46
  )
46
47
  )
47
48
  );
48
49
  }
49
- return packages.map((pkg) => path.relative(paths.targetRoot, pkg.dir));
50
+ return packages.map((pkg) => path.relative(cliCommon.targetPaths.rootDir, pkg.dir));
50
51
  }
51
52
  function isChildPath(base, path$1) {
52
53
  const relative = path.relative(base, path$1);
@@ -59,6 +60,5 @@ function isChildPath(base, path$1) {
59
60
  }
60
61
 
61
62
  exports.isChildPath = isChildPath;
62
- exports.paths = paths;
63
63
  exports.resolvePackagePaths = resolvePackagePaths;
64
64
  //# sourceMappingURL=paths.cjs.js.map
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var cliCommon = require('@backstage/cli-common');
3
4
  var paths = require('./paths.cjs.js');
4
5
  var pLimit = require('p-limit');
5
6
  var path = require('node:path');
@@ -35,7 +36,7 @@ async function runner(paths$1, command, options) {
35
36
  resultText = err.message;
36
37
  }
37
38
  return {
38
- relativeDir: path.relative(paths.paths.targetRoot, pkg),
39
+ relativeDir: path.relative(cliCommon.targetPaths.rootDir, pkg),
39
40
  resultText
40
41
  };
41
42
  })
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var version = "0.16.5";
3
+ var version = "0.17.0-next.1";
4
4
 
5
5
  exports.version = version;
6
6
  //# sourceMappingURL=package.json.cjs.js.map
package/openapitools.json CHANGED
@@ -2,6 +2,6 @@
2
2
  "$schema": "../../node_modules/@openapitools/openapi-generator-cli/config.schema.json",
3
3
  "spaces": 2,
4
4
  "generator-cli": {
5
- "version": "6.5.0"
5
+ "version": "7.18.0"
6
6
  }
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/repo-tools",
3
- "version": "0.16.5",
3
+ "version": "0.17.0-next.1",
4
4
  "description": "CLI for Backstage repo tooling ",
5
5
  "backstage": {
6
6
  "role": "cli"
@@ -43,12 +43,12 @@
43
43
  "dependencies": {
44
44
  "@apidevtools/swagger-parser": "^10.1.0",
45
45
  "@apisyouwonthate/style-guide": "^1.4.0",
46
- "@backstage/backend-plugin-api": "^1.7.0",
47
- "@backstage/catalog-model": "^1.7.6",
48
- "@backstage/cli-common": "^0.1.18",
49
- "@backstage/cli-node": "^0.2.18",
50
- "@backstage/config-loader": "^1.10.8",
51
- "@backstage/errors": "^1.2.7",
46
+ "@backstage/backend-plugin-api": "1.7.1-next.0",
47
+ "@backstage/catalog-model": "1.7.6",
48
+ "@backstage/cli-common": "0.2.0-next.1",
49
+ "@backstage/cli-node": "0.2.19-next.1",
50
+ "@backstage/config-loader": "1.10.9-next.0",
51
+ "@backstage/errors": "1.2.7",
52
52
  "@electric-sql/pglite": "^0.3.0",
53
53
  "@manypkg/get-packages": "^1.1.3",
54
54
  "@microsoft/api-documenter": "^7.28.1",
@@ -67,7 +67,7 @@
67
67
  "chokidar": "^3.5.3",
68
68
  "codeowners-utils": "^1.0.2",
69
69
  "command-exists": "^1.2.9",
70
- "commander": "^12.0.0",
70
+ "commander": "^14.0.3",
71
71
  "fs-extra": "^11.2.0",
72
72
  "glob": "^8.0.3",
73
73
  "globby": "^11.0.0",
@@ -78,7 +78,7 @@
78
78
  "knex-pglite": "^0.11.0",
79
79
  "knip": "^5.42.0",
80
80
  "lodash": "^4.17.21",
81
- "minimatch": "^9.0.0",
81
+ "minimatch": "^10.2.1",
82
82
  "p-limit": "^3.0.2",
83
83
  "portfinder": "^1.0.32",
84
84
  "tar": "^7.5.6",
@@ -87,9 +87,9 @@
87
87
  "zod": "^3.25.76"
88
88
  },
89
89
  "devDependencies": {
90
- "@backstage/backend-test-utils": "^1.11.0",
91
- "@backstage/cli": "^0.35.4",
92
- "@backstage/types": "^1.2.2",
90
+ "@backstage/backend-test-utils": "1.11.1-next.1",
91
+ "@backstage/cli": "0.36.0-next.1",
92
+ "@backstage/types": "1.2.2",
93
93
  "@types/is-glob": "^4.0.2",
94
94
  "@types/node": "^22.13.14",
95
95
  "@types/prettier": "^2.0.0",