@backstage/repo-tools 0.16.6-next.0 → 0.17.0-next.2
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 +26 -0
- package/dist/commands/api-reports/cli-reports/runCliExtraction.cjs.js +14 -5
- package/dist/commands/index.cjs.js +1 -1
- package/dist/commands/package/schema/openapi/generate/client.cjs.js +7 -1
- package/dist/commands/package/schema/openapi/generate/server.cjs.js +7 -1
- package/dist/commands/repo/schema/openapi/lint.cjs.js +4 -3
- package/dist/commands/util.cjs.js +37 -42
- package/dist/lib/openapi/helpers.cjs.js +23 -0
- package/dist/package.json.cjs.js +1 -1
- package/openapitools.json +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @backstage/repo-tools
|
|
2
2
|
|
|
3
|
+
## 0.17.0-next.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/backend-plugin-api@1.8.0-next.1
|
|
9
|
+
- @backstage/cli-common@0.2.0-next.2
|
|
10
|
+
|
|
11
|
+
## 0.17.0-next.1
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 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.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 426edbe: Fixed `generate-catalog-info` command failing with "too many arguments" when invoked by lint-staged via the pre-commit hook.
|
|
20
|
+
- d5779e5: Updated the CLI report parser to support cleye-style help output, and strip ANSI escape codes from captured output.
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @backstage/cli-common@0.2.0-next.1
|
|
23
|
+
- @backstage/cli-node@0.2.19-next.1
|
|
24
|
+
- @backstage/backend-plugin-api@1.7.1-next.0
|
|
25
|
+
- @backstage/catalog-model@1.7.6
|
|
26
|
+
- @backstage/config-loader@1.10.9-next.0
|
|
27
|
+
- @backstage/errors@1.2.7
|
|
28
|
+
|
|
3
29
|
## 0.16.6-next.0
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
|
@@ -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
|
-
|
|
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
|
|
36
|
+
if (sectionName === "options:" || sectionName === "flags:") {
|
|
33
37
|
options = sectionItems;
|
|
34
|
-
} else if (sectionName
|
|
38
|
+
} else if (sectionName === "commands:") {
|
|
35
39
|
commands = sectionItems;
|
|
36
|
-
} else if (sectionName
|
|
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
|
}
|
|
@@ -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"
|
|
@@ -24,6 +24,7 @@ async function generate(outputDirectory, clientAdditionalProperties, abortSignal
|
|
|
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
|
-
|
|
50
|
+
generatorKey,
|
|
50
51
|
additionalProperties ? `--additional-properties=${additionalProperties}` : ""
|
|
51
52
|
],
|
|
52
53
|
{
|
|
@@ -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
|
|
@@ -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
|
-
|
|
88
|
+
generatorKey,
|
|
88
89
|
additionalProperties ? `--additional-properties=${additionalProperties}` : ""
|
|
89
90
|
],
|
|
90
91
|
{
|
|
@@ -116,6 +117,11 @@ async function generate(serverAdditionalProperties, abortSignal) {
|
|
|
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
|
|
@@ -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:
|
|
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: [
|
|
@@ -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
|
|
7
|
+
var path = require('node:path');
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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;
|
|
@@ -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;
|
package/dist/package.json.cjs.js
CHANGED
package/openapitools.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/repo-tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0-next.2",
|
|
4
4
|
"description": "CLI for Backstage repo tooling ",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "cli"
|
|
@@ -43,10 +43,10 @@
|
|
|
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.
|
|
46
|
+
"@backstage/backend-plugin-api": "1.8.0-next.1",
|
|
47
47
|
"@backstage/catalog-model": "1.7.6",
|
|
48
|
-
"@backstage/cli-common": "0.2.0-next.
|
|
49
|
-
"@backstage/cli-node": "0.2.19-next.
|
|
48
|
+
"@backstage/cli-common": "0.2.0-next.2",
|
|
49
|
+
"@backstage/cli-node": "0.2.19-next.1",
|
|
50
50
|
"@backstage/config-loader": "1.10.9-next.0",
|
|
51
51
|
"@backstage/errors": "1.2.7",
|
|
52
52
|
"@electric-sql/pglite": "^0.3.0",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"zod": "^3.25.76"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@backstage/backend-test-utils": "1.11.1-next.
|
|
91
|
-
"@backstage/cli": "0.
|
|
90
|
+
"@backstage/backend-test-utils": "1.11.1-next.2",
|
|
91
|
+
"@backstage/cli": "0.36.0-next.2",
|
|
92
92
|
"@backstage/types": "1.2.2",
|
|
93
93
|
"@types/is-glob": "^4.0.2",
|
|
94
94
|
"@types/node": "^22.13.14",
|