docs/releases/v1.36.0-next.0-changelog.md
Upgrade Helper: https://backstage.github.io/upgrade-helper/?to=1.36.0-next.0
auditor service implementation details.require for lazy-loading dependency.PermissionsRegistryService.auditor service definition.PermissionsRegistryService that is used by plugins to register permissions, resource types, and rules into the permission system. This replaces the existing createPermissionIntegrationRouter from @backstage/plugin-permission-node.PermissionsRegistryService.auditor service.require for lazy-loading dependency.@backstage/backend-app-api.cb76663: BREAKING: Add support for native ESM in Node.js code. This changes the behavior of dynamic import expressions in Node.js code. Typically this can be fixed by replacing import(...) with require(...), with an as typeof import(...) cast if needed for types. This is because dynamic imports will no longer be transformed to require(...) calls, but instead be left as-is. This in turn allows you to load ESM modules from CommonJS code using import(...).
This change adds support for the following in Node.js packages, across type checking, package builds, runtime transforms and Jest tests:
.mjs and .mts files as explicit ESM files, as well as .cjs and .cts as explicit CommonJS files."type": "module" field in package.json to indicate that the package is an ESM package.There are a few caveats to be aware of:
--experimental-vm-modules flag enabled, typically via NODE_OPTIONS='--experimental-vm-modules'."type": "module" in package.json is supported, but in tests it will cause all local transitive dependencies to also be treated as ESM, regardless of whether they declare "type": "module" or not..cts or .cjs extension. This is because the interoperability layer is not fully compatible with the NPM ecosystem, and would break package if it was enabled for .js files.require, or to use the explicit CommonJS extensions as mentioned above. If you do need to dynamically import CommonJS packages, avoid using default exports, as the shape of them vary across different environments and you would otherwise need to manually unwrap the import based on the shape of the module object.PermissionsRegistryService, which can be used to add custom permission rules.auditor service into the Catalog plugin.refresh_state_references for entity processors and providers that are no longer in control of a refresh_state row for entityauditor service into the Scaffolder plugin.taskId property to TaskContext.type field to BackstagePackageJson type.require for lazy-loading dependency.getNodesByRoutePath method to the AppTreeApi.getNodesByRoutePath method to the AppTreeApi.api-reports command is now also able to generate SQL reports, enabled by the --sql-reports flag.resolveUrl for split openapi definition relative pathPermissionsRegistryService instead of the deprecated catalogPermissionExtensionPoint.catalogPermissionExtensionPoint and related types, since the same functionality is now available via the new PermissionsRegistryService.secrets to fetch from the kubernetes api by adding option to specify additional Objects which are not part of Default Objectssecrets to fetch from the kubernetes api by adding option to specify additional Objects which are not part of Default Objectssecrets to fetch from the kubernetes api by adding option to specify additional Objects which are not part of Default ObjectscreatePermissionIntegrationRouter is now mutable, allowing for permissions and resources to be added after creation of the router.makeFieldSchema function returnmakeFieldSchema function returnSearchFilterBlueprint and SearchFilterResultTypeBlueprintencodeURIComponent. This enhancement improves the safety and reliability of the URL.SearchFilterBlueprint and SearchFilterResultTypeBlueprintf4be934: Changed the base URL in addLinkClickListener from window.location.origin to app.baseUrl for improved path handling. This fixes an issue where Backstage, when running on a subpath, was unable to handle non-Backstage URLs of the same origin correctly.
1f40e6b: Add optional props to TechDocCustomHome to allow for more flexibility:
import { TechDocsCustomHome } from '@backstage/plugin-techdocs';
//...
const options = { emptyRowsWhenPaging: false };
const linkDestination = (entity: Entity): string | undefined => {
return entity.metadata.annotations?.['external-docs'];
};
const techDocsTabsConfig = [
{
label: 'Recommended Documentation',
panels: [
{
title: 'Golden Path',
description: 'Documentation about standards to follow',
panelType: 'DocsCardGrid',
panelProps: { CustomHeader: () => <ContentHeader title='Golden Path'/> },
filterPredicate: entity =>
entity?.metadata?.tags?.includes('golden-path') ?? false,
},
{
title: 'Recommended',
description: 'Useful documentation',
panelType: 'InfoCardGrid',
panelProps: {
CustomHeader: () => <ContentHeader title='Recommended' />
linkDestination: linkDestination,
},
filterPredicate: entity =>
entity?.metadata?.tags?.includes('recommended') ?? false,
},
],
},
{
label: 'Browse All',
panels: [
{
description: 'Browse all docs',
filterPredicate: filterEntity,
panelType: 'TechDocsIndexPage',
title: 'All',
panelProps: { PageWrapper: React.Fragment, CustomHeader: React.Fragment, options: options },
},
],
},
];
const AppRoutes = () => {
<FlatRoutes>
<Route
path="/docs"
element={
<TechDocsCustomHome
tabsConfig={techDocsTabsConfig}
filter={{
kind: ['Location', 'Resource', 'Component'],
'metadata.annotations.featured-docs': CATALOG_FILTER_EXISTS,
}}
CustomPageWrapper={({ children }: React.PropsWithChildren<{}>) => (<PageWithHeader title="Docs" themeId="documentation">{children}</PageWithHeader>)}
/>
}
/>
</FlatRoutes>;
};
Add new Grid option called InfoCardGrid which is a more customizable card option for the Docs grid.
<InfoCardGrid
entities={entities}
linkContent="Learn more"
linkDestination={entity => entity.metadata['external-docs']}
/>
Expose existing CustomDocsPanel so that it can be used independently if desired.
const panels: PanelConfig[] = [
{
description: '',
filterPredicate: entity => {},
panelType: 'InfoCardGrid',
title: 'Standards',
panelProps: {
CustomHeader: () => <ContentHeader title='Recommended' />
linkDestination: linkDestination,
},
},
{
description: '',
filterPredicate: entity => {},
panelType: 'DocsCardGrid',
title: 'Contribute',
},
];
{
panels.map((config, index) => (
<CustomDocsPanel
key={index}
config={config}
entities={!!entities ? entities : []}
index={index}
/>
));
}
Updated dependencies