cli: use PackageRoles for role detection and remove redundant import --pattern

Uses PackageRoles.getRoleInfo from cli-node to determine frontend packages
by platform instead of a hardcoded role list. Removes the --pattern option
from the import command since the pattern is always read from the manifest.

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Patrik Oldsberg
2026-02-18 12:22:26 +01:00
parent fd50cb3401
commit a808c9ef3f
4 changed files with 22 additions and 27 deletions
+6 -5
View File
@@ -474,15 +474,16 @@ manifest and translated message files produced by `translations export`, and
generates a TypeScript module that creates `TranslationResource` objects for each
translated ref.
The file pattern used during export is stored in the manifest and automatically
used by the import command.
```text
Usage: backstage-cli translations import [options]
Options:
--input <dir> Input directory containing the manifest and translated message files (default: "translations")
--output <path> Output path for the generated wiring module (default: "src/translations/resources.ts")
--pattern <pattern> File path pattern for message files, with {id} and {lang}
placeholders (default: "{id}.{lang}.json")
-h, --help display help for command
--input <dir> Input directory containing the manifest and translated message files (default: "translations")
--output <path> Output path for the generated wiring module (default: "src/translations/resources.ts")
-h, --help display help for command
```
### Examples
@@ -31,7 +31,6 @@ import {
interface ImportOptions {
input: string;
output: string;
pattern: string;
}
interface ManifestRefEntry {
@@ -69,8 +68,12 @@ export default async (options: ImportOptions) => {
const manifest: Manifest = await fs.readJson(manifestPath);
// Use the pattern from manifest if available, falling back to the CLI default
const pattern = manifest.pattern ?? options.pattern;
if (!manifest.pattern) {
throw new Error(
'No pattern found in manifest.json. Re-run "backstage-cli translations export" to regenerate it.',
);
}
const pattern = manifest.pattern;
const parsePath = createMessagePathParser(pattern);
@@ -65,12 +65,6 @@ export default createCliPlugin({
default: 'src/translations/resources.ts',
description: 'Output path for the generated wiring module',
},
pattern: {
type: 'string',
default: DEFAULT_MESSAGE_PATTERN,
description:
'File path pattern for message files, with {id} and {lang} placeholders',
},
})
.help()
.parse(args);
@@ -17,22 +17,11 @@
import {
BackstagePackageJson,
PackageGraph,
PackageRole,
PackageRoles,
} from '@backstage/cli-node';
import { dirname, resolve as resolvePath } from 'node:path';
import fs from 'fs-extra';
/**
* Package roles that can contain frontend translation refs.
*/
const FRONTEND_ROLES: PackageRole[] = [
'frontend',
'frontend-plugin',
'frontend-plugin-module',
'web-library',
'common-library',
];
/** A discovered package with its entry points resolved to file paths. */
export interface DiscoveredPackage {
/** The package name, e.g. '@backstage/plugin-org' */
@@ -141,7 +130,7 @@ export async function discoverFrontendPackages(
}
const role = depPkgJson.backstage?.role;
if (role && FRONTEND_ROLES.includes(role)) {
if (role && isFrontendRole(role)) {
const entryPoints = resolveEntryPoints(depPkgJson, depDir, isWorkspace);
if (entryPoints.size > 0) {
result.push({ name: depName, dir: depDir, entryPoints });
@@ -208,3 +197,11 @@ function resolveEntryPoints(
return entryPoints;
}
function isFrontendRole(role: string): boolean {
try {
return PackageRoles.getRoleInfo(role).platform === 'web';
} catch {
return false;
}
}