Merge branch 'master' into timbonicus/docker-tweaks
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
---
|
||||
|
||||
k8s plugin now surfaces k8s components with only label selector query annotation.
|
||||
Previously backstage.io/kubernetes-label-selector catalog entity annotation would only work if you also included backstage.io/kubernetes-id.
|
||||
But backstage.io/kubernetes-id value was ignored
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-circleci': patch
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
'@backstage/plugin-github-actions': patch
|
||||
---
|
||||
|
||||
Use Breadcrumbs from @backstage/core rather than material-ui
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Move logic for constructing the template form to the backend, using a new `./parameter-schema` endpoint that returns the form schema for a given template.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Bump `@svgr/webpack` from `5.4.x` to `5.5.x`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
---
|
||||
|
||||
Forward authorization header on backend request if present
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
GithubDiscoveryProcessor outputs locations as optional to avoid outputting errors for missing locations (see https://github.com/backstage/backstage/issues/4730).
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Update messaging when no entities are in a table.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Make the external `createComponent` route optional, hiding the "Create Component" button if it isn't bound.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@backstage/catalog-model': patch
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Add version `backstage.io/v1beta2` schema for Template entities.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
---
|
||||
|
||||
Collect all available metric types if the number exceeds the default page size of 100.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Add optional `logClientErrors` to errorHandler to log 4XX errors
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-proxy-backend': patch
|
||||
---
|
||||
|
||||
Added a verification for well formed URLs when processing proxy targets. Otherwise users gets a cryptic error message thrown from Express which makes it hard to debug.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Consider both authentication methods for both `onprem` and `cloud` BitBucket
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
---
|
||||
|
||||
Use external url for static docs
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
'@backstage/techdocs-common': patch
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
'@backstage/plugin-kafka-backend': patch
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
---
|
||||
|
||||
remove usage of res.send() for res.json() and res.end() to ensure content types are more consistently application/json on backend responses and error cases
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Change debug log format to print as color grey
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Tweak the template cards to be even more compliant with MUI examples, and a little bit more dense.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Add organization name to the API Explorer page title
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
The api-docs plugin has been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page.
|
||||
|
||||
If you want to have a button that links to the scaffolder plugin from the API explorer, apply the following changes to `packages/app/src/App.tsx`:
|
||||
|
||||
```diff
|
||||
+ import { apiDocsPlugin } from '@backstage/plugin-api-docs';
|
||||
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
|
||||
|
||||
const app = createApp({
|
||||
// ...
|
||||
bindRoutes({ bind }) {
|
||||
+ bind(apiDocsPlugin.externalRoutes, {
|
||||
+ createComponent: scaffolderPlugin.routes.root,
|
||||
+ });
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you choose to not bind the routes, the button to create new APIs is not displayed.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
---
|
||||
|
||||
Allow apps to pass in a KubernetesClustersSupplier
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
---
|
||||
|
||||
Support AWS auth provider on kubernetes FE plugin
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-proxy-backend': patch
|
||||
---
|
||||
|
||||
Fix for proxy-backend plugin when global-agent is enabled
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Use entity relation for the owner of an entity in the catalog entity page header.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Bump `@testing-library/react` in the plugin template from `^10.4.1` to `^11.2.5`. To apply this to an existing plugin, update the dependency in your `package.json`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': minor
|
||||
---
|
||||
|
||||
Add authorization header on techdocs api requests. Breaking change as clients now needs the Identity API.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Fixed an issue where the `backend:dev` command would get stuck executing the backend process multiple times, causing port conflict issues.
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': minor
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
The scaffolder has been updated to support the new `v1beta2` template schema which allows for custom template actions!
|
||||
|
||||
See documentation for more information how to create and register new template actions.
|
||||
|
||||
**Breaking changes**
|
||||
|
||||
The backend scaffolder plugin now needs a `UrlReader` which can be pulled from the PluginEnvironment.
|
||||
|
||||
The following change is required in `backend/src/plugins/scaffolder.ts`
|
||||
|
||||
```diff
|
||||
export default async function createPlugin({
|
||||
logger,
|
||||
config,
|
||||
database,
|
||||
+ reader,
|
||||
}: PluginEnvironment): Promise<Router> {
|
||||
|
||||
// omitted code
|
||||
|
||||
return await createRouter({
|
||||
preparers,
|
||||
templaters,
|
||||
publishers,
|
||||
logger,
|
||||
config,
|
||||
dockerClient,
|
||||
database,
|
||||
catalogClient,
|
||||
+ reader,
|
||||
});
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
---
|
||||
|
||||
Bump react-hook-form version constraint to "^6.15.4"
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/core-api': patch
|
||||
'@backstage/core': patch
|
||||
---
|
||||
|
||||
Added support for optional external route references. By setting `optional: true` when creating an `ExternalRouteRef` it is no longer a requirement to bind the route in the app. If the app isn't bound `useRouteRef` will return `undefined`.
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
The api-docs plugin has been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the api docs plugin to use the new extension components, as well as bind the external route.
|
||||
|
||||
To bind the external route from the api docs plugin to the scaffolder template index page, make sure you have the appropriate imports and add the following to the `createApp` call:
|
||||
|
||||
```ts
|
||||
import { apiDocsPlugin } from '@backstage/plugin-api-docs';
|
||||
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
|
||||
|
||||
const app = createApp({
|
||||
// ...
|
||||
bindRoutes({ bind }) {
|
||||
bind(apiDocsPlugin.externalRoutes, {
|
||||
createComponent: scaffolderPlugin.routes.root,
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you choose to not bind the routes, the button to create new APIs is not displayed.
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
'@backstage/core-api': patch
|
||||
'@backstage/core': patch
|
||||
---
|
||||
|
||||
Internal refactor of how component data is access to avoid polluting components and make it possible to bridge across versions.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core': patch
|
||||
---
|
||||
|
||||
Improve rendering of multiple support item links in the `SupportButton`
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
---
|
||||
|
||||
Display '-' instead of 'undefined' if no code coverage is reported.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
New config command to export the configuration schema. When running backstage-cli with yarn, consider using `yarn --silent backstage-cli config:schema` to get a clean output on `stdout`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core': patch
|
||||
---
|
||||
|
||||
Added the color prop to TrendLine from the Sparklines props types to be able to have custom colors.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core': patch
|
||||
---
|
||||
|
||||
Added a new useSupportConfig hook that reads a new `app.support` config key. Also updated the SupportButton and ErrorPage components to use the new config.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Fixed file path resolution for templates with a file location
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
'@backstage/core': minor
|
||||
'@backstage/plugin-pagerduty': patch
|
||||
---
|
||||
|
||||
- Adds onClick and other props to IconLinkVertical;
|
||||
- Allows TriggerButton component to render when pager duty key is missing;
|
||||
- Refactors TriggerButton and PagerDutyCard not to have shared state;
|
||||
- Removes the `action` prop of the IconLinkVertical component while adding `onClick`.
|
||||
|
||||
Instead of having an action including a button with onClick, now the whole component can be clickable making it easier to implement and having a better UX.
|
||||
|
||||
Before:
|
||||
|
||||
```ts
|
||||
const myLink: IconLinkVerticalProps = {
|
||||
label: 'Click me',
|
||||
action: <Button onClick={myAction} />,
|
||||
icon: <MyIcon onClick={myAction} />,
|
||||
};
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```ts
|
||||
const myLink: IconLinkVerticalProps = {
|
||||
label: 'Click me',
|
||||
onClick: myAction,
|
||||
icon: <MyIcon />,
|
||||
};
|
||||
```
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
Removed support for deprecated publisher auth configuration within the `scaffolder` configuration block, such as `scaffolder.github.token`. Access should instead be configured through `integrations` configuration.
|
||||
|
||||
For example, replace the following configuration in `app-config.yaml`
|
||||
|
||||
```yaml
|
||||
scaffolder:
|
||||
github:
|
||||
token: my-token
|
||||
```
|
||||
|
||||
with
|
||||
|
||||
```yaml
|
||||
integrations:
|
||||
github:
|
||||
- host: github.com
|
||||
token: my-token
|
||||
```
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Migrated away from using deprecated routes and router components at top-level in the app, and instead use routable extension pages.
|
||||
|
||||
To apply this change to an existing app, make the following changes to `packages/app/src/App.tsx`:
|
||||
|
||||
Update imports and remove the usage of the deprecated `app.getRoutes()`.
|
||||
|
||||
```diff
|
||||
-import { Router as DocsRouter } from '@backstage/plugin-techdocs';
|
||||
+import { TechdocsPage } from '@backstage/plugin-techdocs';
|
||||
import { CatalogImportPage } from '@backstage/plugin-catalog-import';
|
||||
-import { Router as TechRadarRouter } from '@backstage/plugin-tech-radar';
|
||||
-import { SearchPage as SearchRouter } from '@backstage/plugin-search';
|
||||
-import { Router as SettingsRouter } from '@backstage/plugin-user-settings';
|
||||
+import { TechRadarPage } from '@backstage/plugin-tech-radar';
|
||||
+import { SearchPage } from '@backstage/plugin-search';
|
||||
+import { UserSettingsPage } from '@backstage/plugin-user-settings';
|
||||
+import { ApiExplorerPage } from '@backstage/plugin-api-docs';
|
||||
import { EntityPage } from './components/catalog/EntityPage';
|
||||
import { scaffolderPlugin, ScaffolderPage } from '@backstage/plugin-scaffolder';
|
||||
|
||||
|
||||
const AppProvider = app.getProvider();
|
||||
const AppRouter = app.getRouter();
|
||||
-const deprecatedAppRoutes = app.getRoutes();
|
||||
```
|
||||
|
||||
As well as update or add the following routes:
|
||||
|
||||
```diff
|
||||
<Route path="/create" element={<ScaffolderPage />} />
|
||||
- <Route path="/docs" element={<DocsRouter />} />
|
||||
+ <Route path="/docs" element={<TechdocsPage />} />
|
||||
+ <Route path="/api-docs" element={<ApiExplorerPage />} />
|
||||
<Route
|
||||
path="/tech-radar"
|
||||
- element={<TechRadarRouter width={1500} height={800} />}
|
||||
+ element={<TechRadarPage width={1500} height={800} />}
|
||||
/>
|
||||
<Route path="/catalog-import" element={<CatalogImportPage />} />
|
||||
- <Route
|
||||
- path="/search"
|
||||
- element={<SearchRouter/>}
|
||||
- />
|
||||
- <Route path="/settings" element={<SettingsRouter />} />
|
||||
- {deprecatedAppRoutes}
|
||||
+ <Route path="/search" element={<SearchPage />} />
|
||||
+ <Route path="/settings" element={<UserSettingsPage />} />
|
||||
```
|
||||
|
||||
If you have added additional plugins with registered routes or are using `Router` components from other plugins, these should be migrated to use the `*Page` components as well. See [this commit](https://github.com/backstage/backstage/commit/abd655e42d4ed416b70848ffdb1c4b99d189f13b) for more examples of how to migrate.
|
||||
|
||||
For more information and the background to this change, see the [composability system migration docs](https://backstage.io/docs/plugins/composability).
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
---
|
||||
|
||||
Change terminology for cloudbuild
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Updated the default `App` test to work better on Windows.
|
||||
|
||||
To apply this change to an existing app, replace the `process.env.APP_CONFIG` definition in `packages/app/src/App.test.tsx` with the following:
|
||||
|
||||
```ts
|
||||
process.env = {
|
||||
NODE_ENV: 'test',
|
||||
APP_CONFIG: [
|
||||
{
|
||||
data: {
|
||||
app: { title: 'Test' },
|
||||
backend: { baseUrl: 'http://localhost:7000' },
|
||||
techdocs: {
|
||||
storageUrl: 'http://localhost:7000/api/techdocs/static/docs',
|
||||
},
|
||||
},
|
||||
context: 'test',
|
||||
},
|
||||
] as any,
|
||||
};
|
||||
```
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
Expose a configuration option for the oidc scope
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog': patch
|
||||
---
|
||||
|
||||
Removed fullScreen property from UnregisterEntity Dialog modal.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-github-actions': patch
|
||||
---
|
||||
|
||||
Use Breadcrumbs from @backstage/core
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-jenkins': patch
|
||||
---
|
||||
|
||||
- Add Jenkins logo to project page.
|
||||
- Move to new Backstage breadcrumb component.
|
||||
- Change references of deprecated "Job" terminology to "Project" per [Jenkins Glossary](https://www.jenkins.io/doc/book/glossary/).
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Bump `ts-loader` dependency range from `^7.0.4` to `^8.0.17`.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Fixed EntityProvider setting 'loading' bool erroneously to true
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-lighthouse': patch
|
||||
---
|
||||
|
||||
Change setup wording of intro card to latest
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/techdocs-common': patch
|
||||
---
|
||||
|
||||
Remove read-store-upload loop when uploading S3 objects for TechDocs
|
||||
@@ -1,5 +1,74 @@
|
||||
# example-app
|
||||
|
||||
## 0.2.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [ba21797ca]
|
||||
- Updated dependencies [b2a5320a4]
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [507513fed]
|
||||
- Updated dependencies [32a003973]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [cfc83cac1]
|
||||
- Updated dependencies [bc327dc42]
|
||||
- Updated dependencies [2386de1d3]
|
||||
- Updated dependencies [42c8ebb79]
|
||||
- Updated dependencies [10362e9eb]
|
||||
- Updated dependencies [e37d2de99]
|
||||
- Updated dependencies [813c6a4f2]
|
||||
- Updated dependencies [11c6208fe]
|
||||
- Updated dependencies [8106c9528]
|
||||
- Updated dependencies [05183f202]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [f71589800]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- Updated dependencies [bece09057]
|
||||
- Updated dependencies [d4f0a1406]
|
||||
- Updated dependencies [169f48deb]
|
||||
- Updated dependencies [8a1566719]
|
||||
- Updated dependencies [9d455f69a]
|
||||
- Updated dependencies [4c049a1a1]
|
||||
- Updated dependencies [d21058c34]
|
||||
- Updated dependencies [b33e553b2]
|
||||
- Updated dependencies [04667f571]
|
||||
- Updated dependencies [b93538acc]
|
||||
- Updated dependencies [0452ba238]
|
||||
- Updated dependencies [8871e7523]
|
||||
- Updated dependencies [02816ecd7]
|
||||
- Updated dependencies [dbea11072]
|
||||
- @backstage/plugin-kubernetes@0.3.12
|
||||
- @backstage/plugin-circleci@0.2.11
|
||||
- @backstage/plugin-cloudbuild@0.2.12
|
||||
- @backstage/plugin-github-actions@0.3.5
|
||||
- @backstage/plugin-scaffolder@0.7.0
|
||||
- @backstage/cli@0.6.3
|
||||
- @backstage/plugin-api-docs@0.4.8
|
||||
- @backstage/plugin-catalog@0.4.1
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/plugin-explore@0.3.0
|
||||
- @backstage/plugin-techdocs@0.6.0
|
||||
- @backstage/plugin-catalog-import@0.4.3
|
||||
- @backstage/core@0.7.0
|
||||
- @backstage/plugin-catalog-react@0.1.1
|
||||
- @backstage/plugin-pagerduty@0.3.2
|
||||
- @backstage/plugin-jenkins@0.3.12
|
||||
- @backstage/plugin-lighthouse@0.2.13
|
||||
- @backstage/plugin-cost-insights@0.8.3
|
||||
- @backstage/plugin-gcp-projects@0.2.5
|
||||
- @backstage/plugin-gitops-profiles@0.2.6
|
||||
- @backstage/plugin-graphiql@0.2.8
|
||||
- @backstage/plugin-kafka@0.2.5
|
||||
- @backstage/plugin-newrelic@0.2.6
|
||||
- @backstage/plugin-org@0.3.9
|
||||
- @backstage/plugin-register-component@0.2.12
|
||||
- @backstage/plugin-rollbar@0.3.3
|
||||
- @backstage/plugin-search@0.3.3
|
||||
- @backstage/plugin-sentry@0.3.8
|
||||
- @backstage/plugin-tech-radar@0.3.7
|
||||
- @backstage/plugin-user-settings@0.2.7
|
||||
|
||||
## 0.2.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+32
-32
@@ -1,39 +1,39 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.17",
|
||||
"version": "0.2.18",
|
||||
"private": true,
|
||||
"bundled": true,
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/core": "^0.6.3",
|
||||
"@backstage/plugin-api-docs": "^0.4.7",
|
||||
"@backstage/plugin-catalog": "^0.4.0",
|
||||
"@backstage/plugin-catalog-import": "^0.4.2",
|
||||
"@backstage/plugin-catalog-react": "^0.1.0",
|
||||
"@backstage/plugin-circleci": "^0.2.10",
|
||||
"@backstage/plugin-cloudbuild": "^0.2.11",
|
||||
"@backstage/plugin-cost-insights": "^0.8.2",
|
||||
"@backstage/plugin-explore": "^0.2.7",
|
||||
"@backstage/plugin-gcp-projects": "^0.2.4",
|
||||
"@backstage/plugin-github-actions": "^0.3.4",
|
||||
"@backstage/plugin-gitops-profiles": "^0.2.5",
|
||||
"@backstage/plugin-graphiql": "^0.2.7",
|
||||
"@backstage/plugin-jenkins": "^0.3.11",
|
||||
"@backstage/plugin-kafka": "^0.2.4",
|
||||
"@backstage/plugin-kubernetes": "^0.3.11",
|
||||
"@backstage/plugin-lighthouse": "^0.2.12",
|
||||
"@backstage/plugin-newrelic": "^0.2.5",
|
||||
"@backstage/plugin-org": "^0.3.8",
|
||||
"@backstage/plugin-pagerduty": "0.3.1",
|
||||
"@backstage/plugin-register-component": "^0.2.11",
|
||||
"@backstage/plugin-rollbar": "^0.3.2",
|
||||
"@backstage/plugin-scaffolder": "^0.6.0",
|
||||
"@backstage/plugin-sentry": "^0.3.7",
|
||||
"@backstage/plugin-search": "^0.3.2",
|
||||
"@backstage/plugin-tech-radar": "^0.3.6",
|
||||
"@backstage/plugin-techdocs": "^0.5.8",
|
||||
"@backstage/plugin-user-settings": "^0.2.6",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@backstage/plugin-api-docs": "^0.4.8",
|
||||
"@backstage/plugin-catalog": "^0.4.1",
|
||||
"@backstage/plugin-catalog-import": "^0.4.3",
|
||||
"@backstage/plugin-catalog-react": "^0.1.1",
|
||||
"@backstage/plugin-circleci": "^0.2.11",
|
||||
"@backstage/plugin-cloudbuild": "^0.2.12",
|
||||
"@backstage/plugin-cost-insights": "^0.8.3",
|
||||
"@backstage/plugin-explore": "^0.3.0",
|
||||
"@backstage/plugin-gcp-projects": "^0.2.5",
|
||||
"@backstage/plugin-github-actions": "^0.3.5",
|
||||
"@backstage/plugin-gitops-profiles": "^0.2.6",
|
||||
"@backstage/plugin-graphiql": "^0.2.8",
|
||||
"@backstage/plugin-jenkins": "^0.3.12",
|
||||
"@backstage/plugin-kafka": "^0.2.5",
|
||||
"@backstage/plugin-kubernetes": "^0.3.12",
|
||||
"@backstage/plugin-lighthouse": "^0.2.13",
|
||||
"@backstage/plugin-newrelic": "^0.2.6",
|
||||
"@backstage/plugin-org": "^0.3.9",
|
||||
"@backstage/plugin-pagerduty": "0.3.2",
|
||||
"@backstage/plugin-register-component": "^0.2.12",
|
||||
"@backstage/plugin-rollbar": "^0.3.3",
|
||||
"@backstage/plugin-scaffolder": "^0.7.0",
|
||||
"@backstage/plugin-sentry": "^0.3.8",
|
||||
"@backstage/plugin-search": "^0.3.3",
|
||||
"@backstage/plugin-tech-radar": "^0.3.7",
|
||||
"@backstage/plugin-techdocs": "^0.6.0",
|
||||
"@backstage/plugin-user-settings": "^0.2.7",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -41,7 +41,7 @@
|
||||
"@roadiehq/backstage-plugin-buildkite": "^0.1.3",
|
||||
"@roadiehq/backstage-plugin-github-insights": "^0.2.16",
|
||||
"@roadiehq/backstage-plugin-github-pull-requests": "^0.7.6",
|
||||
"@roadiehq/backstage-plugin-travis-ci": "^0.2.8",
|
||||
"@roadiehq/backstage-plugin-travis-ci": "^0.4.5",
|
||||
"history": "^5.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
CostInsightsPage,
|
||||
CostInsightsProjectGrowthInstructionsPage,
|
||||
} from '@backstage/plugin-cost-insights';
|
||||
import { ExplorePage } from '@backstage/plugin-explore';
|
||||
import { ExplorePage, explorePlugin } from '@backstage/plugin-explore';
|
||||
import { GcpProjectsPage } from '@backstage/plugin-gcp-projects';
|
||||
import { GraphiQLPage } from '@backstage/plugin-graphiql';
|
||||
import { LighthousePage } from '@backstage/plugin-lighthouse';
|
||||
@@ -79,6 +79,9 @@ const app = createApp({
|
||||
bind(apiDocsPlugin.externalRoutes, {
|
||||
createComponent: scaffolderPlugin.routes.root,
|
||||
});
|
||||
bind(explorePlugin.externalRoutes, {
|
||||
catalogEntity: catalogPlugin.routes.catalogEntity,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/backend-common
|
||||
|
||||
## 0.5.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 497859088: Add optional `logClientErrors` to errorHandler to log 4XX errors
|
||||
- 8adb48df4: Change debug log format to print as color grey
|
||||
|
||||
## 0.5.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.5.4",
|
||||
"version": "0.5.5",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -68,7 +68,7 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.1",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/test-utils": "^0.1.7",
|
||||
"@types/archiver": "^5.1.0",
|
||||
"@types/compression": "^1.7.0",
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
# example-backend
|
||||
|
||||
## 0.2.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [52b5bc3e2]
|
||||
- Updated dependencies [ecdd407b1]
|
||||
- Updated dependencies [4fbc9df79]
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [497859088]
|
||||
- Updated dependencies [1987c9341]
|
||||
- Updated dependencies [f31b76b44]
|
||||
- Updated dependencies [15eee03bc]
|
||||
- Updated dependencies [f43192207]
|
||||
- Updated dependencies [8adb48df4]
|
||||
- Updated dependencies [e3adec2bd]
|
||||
- Updated dependencies [9ce68b677]
|
||||
- Updated dependencies [8106c9528]
|
||||
- Updated dependencies [d0ed25196]
|
||||
- Updated dependencies [96ccc8f69]
|
||||
- Updated dependencies [3af994c81]
|
||||
- @backstage/plugin-scaffolder-backend@0.9.0
|
||||
- @backstage/plugin-techdocs-backend@0.6.3
|
||||
- @backstage/plugin-catalog-backend@0.6.4
|
||||
- @backstage/plugin-kafka-backend@0.2.1
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/backend-common@0.5.5
|
||||
- @backstage/plugin-proxy-backend@0.2.5
|
||||
- @backstage/plugin-auth-backend@0.3.3
|
||||
- @backstage/plugin-kubernetes-backend@0.2.8
|
||||
- example-app@0.2.18
|
||||
|
||||
## 0.2.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend",
|
||||
"version": "0.2.17",
|
||||
"version": "0.2.18",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -27,25 +27,25 @@
|
||||
"migrate:create": "knex migrate:make -x ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.5.3",
|
||||
"@backstage/backend-common": "^0.5.5",
|
||||
"@backstage/catalog-client": "^0.3.6",
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@backstage/plugin-app-backend": "^0.3.8",
|
||||
"@backstage/plugin-auth-backend": "^0.3.2",
|
||||
"@backstage/plugin-catalog-backend": "^0.6.3",
|
||||
"@backstage/plugin-auth-backend": "^0.3.3",
|
||||
"@backstage/plugin-catalog-backend": "^0.6.4",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.5",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.2.7",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.0",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.4",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.2.8",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.1",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.5",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.7",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.8.0",
|
||||
"@backstage/plugin-techdocs-backend": "^0.6.2",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.9.0",
|
||||
"@backstage/plugin-techdocs-backend": "^0.6.3",
|
||||
"@gitbeaker/node": "^28.0.2",
|
||||
"@octokit/rest": "^18.0.12",
|
||||
"azure-devops-node-api": "^10.1.1",
|
||||
"dockerode": "^3.2.1",
|
||||
"example-app": "^0.2.17",
|
||||
"example-app": "^0.2.18",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^3.0.3",
|
||||
"knex": "^0.21.6",
|
||||
@@ -55,7 +55,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@types/dockerode": "^3.2.1",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/express-serve-static-core": "^4.17.5"
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @backstage/catalog-model
|
||||
|
||||
## 0.7.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 12d8f27a6: Add version `backstage.io/v1beta2` schema for Template entities.
|
||||
|
||||
## 0.7.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/catalog-model",
|
||||
"version": "0.7.2",
|
||||
"version": "0.7.3",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -39,7 +39,7 @@
|
||||
"yup": "^0.29.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/lodash": "^4.14.151",
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# @backstage/cli
|
||||
|
||||
## 0.6.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 507513fed: Bump `@svgr/webpack` from `5.4.x` to `5.5.x`.
|
||||
- e37d2de99: Bump `@testing-library/react` in the plugin template from `^10.4.1` to `^11.2.5`. To apply this to an existing plugin, update the dependency in your `package.json`.
|
||||
- 11c6208fe: Fixed an issue where the `backend:dev` command would get stuck executing the backend process multiple times, causing port conflict issues.
|
||||
- d4f0a1406: New config command to export the configuration schema. When running backstage-cli with yarn, consider using `yarn --silent backstage-cli config:schema` to get a clean output on `stdout`.
|
||||
- b93538acc: Fix for type declaration input being required for build even if types aren't being built.
|
||||
- 8871e7523: Bump `ts-loader` dependency range from `^7.0.4` to `^8.0.17`.
|
||||
|
||||
## 0.6.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/cli",
|
||||
"description": "CLI for developing Backstage plugins and apps",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -117,10 +117,10 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-common": "^0.5.4",
|
||||
"@backstage/backend-common": "^0.5.5",
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@backstage/core": "^0.6.3",
|
||||
"@backstage/dev-utils": "^0.1.12",
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@types/diff": "^5.0.0",
|
||||
|
||||
@@ -36,22 +36,6 @@ import { svgrTemplate } from '../svgrTemplate';
|
||||
export const makeConfigs = async (
|
||||
options: BuildOptions,
|
||||
): Promise<RollupOptions[]> => {
|
||||
const typesInput = paths.resolveTargetRoot(
|
||||
'dist-types',
|
||||
relativePath(paths.targetRoot, paths.targetDir),
|
||||
'src/index.d.ts',
|
||||
);
|
||||
|
||||
const declarationsExist = await fs.pathExists(typesInput);
|
||||
if (!declarationsExist) {
|
||||
const path = relativePath(paths.targetDir, typesInput);
|
||||
throw new Error(
|
||||
`No declaration files found at ${path}, be sure to run ${chalk.bgRed.white(
|
||||
'yarn tsc',
|
||||
)} to generate .d.ts files before packaging`,
|
||||
);
|
||||
}
|
||||
|
||||
const configs = new Array<RollupOptions>();
|
||||
|
||||
if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) {
|
||||
@@ -112,6 +96,22 @@ export const makeConfigs = async (
|
||||
}
|
||||
|
||||
if (options.outputs.has(Output.types)) {
|
||||
const typesInput = paths.resolveTargetRoot(
|
||||
'dist-types',
|
||||
relativePath(paths.targetRoot, paths.targetDir),
|
||||
'src/index.d.ts',
|
||||
);
|
||||
|
||||
const declarationsExist = await fs.pathExists(typesInput);
|
||||
if (!declarationsExist) {
|
||||
const path = relativePath(paths.targetDir, typesInput);
|
||||
throw new Error(
|
||||
`No declaration files found at ${path}, be sure to run ${chalk.bgRed.white(
|
||||
'yarn tsc',
|
||||
)} to generate .d.ts files before packaging`,
|
||||
);
|
||||
}
|
||||
|
||||
configs.push({
|
||||
input: typesInput,
|
||||
output: {
|
||||
|
||||
+3
-4
@@ -1,11 +1,10 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { ExampleComponent } from './ExampleComponent';
|
||||
import { ThemeProvider } from '@material-ui/core';
|
||||
import { lightTheme } from '@backstage/theme';
|
||||
import { rest } from 'msw';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { msw } from '@backstage/test-utils';
|
||||
import { msw, renderInTestApp } from '@backstage/test-utils';
|
||||
|
||||
describe('ExampleComponent', () => {
|
||||
const server = setupServer();
|
||||
@@ -19,8 +18,8 @@ describe('ExampleComponent', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should render', () => {
|
||||
const rendered = render(
|
||||
it('should render', async () => {
|
||||
const rendered = await renderInTestApp(
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ExampleComponent />
|
||||
</ThemeProvider>,
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/core-api
|
||||
|
||||
## 0.2.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 40c0fdbaa: Added support for optional external route references. By setting `optional: true` when creating an `ExternalRouteRef` it is no longer a requirement to bind the route in the app. If the app isn't bound `useRouteRef` will return `undefined`.
|
||||
- 2a271d89e: Internal refactor of how component data is access to avoid polluting components and make it possible to bridge across versions.
|
||||
|
||||
## 0.2.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/core-api",
|
||||
"description": "Internal Core API used by Backstage plugins and apps",
|
||||
"version": "0.2.11",
|
||||
"version": "0.2.12",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -42,7 +42,7 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@backstage/test-utils-core": "^0.1.1",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
|
||||
@@ -50,23 +50,30 @@ describe('generateBoundRoutes', () => {
|
||||
|
||||
describe('Integration Test', () => {
|
||||
const plugin1RouteRef = createRouteRef({ path: '/blah1', title: '' });
|
||||
const plugin2RouteRef = createRouteRef({ path: '/blah2', title: '' });
|
||||
const externalRouteRef = createExternalRouteRef({ id: '3' });
|
||||
const optionalBarExternalRouteRef = createExternalRouteRef({
|
||||
id: 'bar',
|
||||
const plugin2RouteRef = createRouteRef({
|
||||
path: '/blah2',
|
||||
title: '',
|
||||
params: ['x'],
|
||||
});
|
||||
const err = createExternalRouteRef({ id: 'err' });
|
||||
const errParams = createExternalRouteRef({ id: 'errParams', params: ['x'] });
|
||||
const errOptional = createExternalRouteRef({
|
||||
id: 'errOptional',
|
||||
optional: true,
|
||||
});
|
||||
const optionalBazExternalRouteRef = createExternalRouteRef({
|
||||
id: 'baz',
|
||||
const errParamsOptional = createExternalRouteRef({
|
||||
id: 'errParamsOptional',
|
||||
optional: true,
|
||||
params: ['x'],
|
||||
});
|
||||
|
||||
const plugin1 = createPlugin({
|
||||
id: 'blob',
|
||||
externalRoutes: {
|
||||
foo: externalRouteRef,
|
||||
bar: optionalBarExternalRouteRef,
|
||||
baz: optionalBazExternalRouteRef,
|
||||
err,
|
||||
errParams,
|
||||
errOptional,
|
||||
errParamsOptional,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -85,14 +92,19 @@ describe('Integration Test', () => {
|
||||
createRoutableExtension({
|
||||
component: () =>
|
||||
Promise.resolve((_: PropsWithChildren<{ path?: string }>) => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const externalLink = useRouteRef(externalRouteRef);
|
||||
const barLink = useRouteRef(optionalBarExternalRouteRef);
|
||||
const bazLink = useRouteRef(optionalBazExternalRouteRef);
|
||||
const errLink = useRouteRef(err);
|
||||
const errParamsLink = useRouteRef(errParams);
|
||||
const errOptionalLink = useRouteRef(errOptional);
|
||||
const errParamsOptionalLink = useRouteRef(errParamsOptional);
|
||||
return (
|
||||
<div>
|
||||
Our routes are: {externalLink()}, bar: {barLink?.() ?? 'none'},
|
||||
baz: {bazLink?.() ?? 'none'}
|
||||
<span>err: {errLink()}</span>
|
||||
<span>errParams: {errParamsLink({ x: 'a' })}</span>
|
||||
<span>errOptional: {errOptionalLink?.() ?? '<none>'}</span>
|
||||
<span>
|
||||
errParamsOptional:{' '}
|
||||
{errParamsOptionalLink?.({ x: 'b' }) ?? '<none>'}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}),
|
||||
@@ -100,14 +112,14 @@ describe('Integration Test', () => {
|
||||
}),
|
||||
);
|
||||
|
||||
it('runs happy paths', async () => {
|
||||
const components = {
|
||||
NotFoundErrorPage: () => null,
|
||||
BootErrorPage: () => null,
|
||||
Progress: () => null,
|
||||
Router: BrowserRouter,
|
||||
};
|
||||
const components = {
|
||||
NotFoundErrorPage: () => null,
|
||||
BootErrorPage: () => null,
|
||||
Progress: () => null,
|
||||
Router: BrowserRouter,
|
||||
};
|
||||
|
||||
it('runs happy paths', async () => {
|
||||
const app = new PrivateAppImpl({
|
||||
apis: [],
|
||||
defaultApis: [],
|
||||
@@ -124,8 +136,10 @@ describe('Integration Test', () => {
|
||||
components,
|
||||
bindRoutes: ({ bind }) => {
|
||||
bind(plugin1.externalRoutes, {
|
||||
foo: plugin2RouteRef,
|
||||
bar: plugin2RouteRef,
|
||||
err: plugin1RouteRef,
|
||||
errParams: plugin2RouteRef,
|
||||
errOptional: plugin1RouteRef,
|
||||
errParamsOptional: plugin2RouteRef,
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -138,25 +152,19 @@ describe('Integration Test', () => {
|
||||
<Router>
|
||||
<Routes>
|
||||
<ExposedComponent path="/" />
|
||||
<HiddenComponent path="/foo/bar" />
|
||||
<HiddenComponent path="/foo" />
|
||||
</Routes>
|
||||
</Router>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
expect(
|
||||
screen.getByText('Our routes are: /foo/bar, bar: /foo/bar, baz: none'),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText('err: /')).toBeInTheDocument();
|
||||
expect(screen.getByText('errParams: /foo')).toBeInTheDocument();
|
||||
expect(screen.getByText('errOptional: /')).toBeInTheDocument();
|
||||
expect(screen.getByText('errParamsOptional: /foo')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should throw some error when the route has duplicate params', () => {
|
||||
const components = {
|
||||
NotFoundErrorPage: () => null,
|
||||
BootErrorPage: () => null,
|
||||
Progress: () => null,
|
||||
Router: BrowserRouter,
|
||||
};
|
||||
|
||||
it('runs happy paths without optional routes', async () => {
|
||||
const app = new PrivateAppImpl({
|
||||
apis: [],
|
||||
defaultApis: [],
|
||||
@@ -172,7 +180,53 @@ describe('Integration Test', () => {
|
||||
plugins: [],
|
||||
components,
|
||||
bindRoutes: ({ bind }) => {
|
||||
bind(plugin1.externalRoutes, { foo: plugin2RouteRef });
|
||||
bind(plugin1.externalRoutes, {
|
||||
err: plugin1RouteRef,
|
||||
errParams: plugin2RouteRef,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const Provider = app.getProvider();
|
||||
const Router = app.getRouter();
|
||||
|
||||
await renderWithEffects(
|
||||
<Provider>
|
||||
<Router>
|
||||
<Routes>
|
||||
<ExposedComponent path="/" />
|
||||
<HiddenComponent path="/foo" />
|
||||
</Routes>
|
||||
</Router>
|
||||
</Provider>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('err: /')).toBeInTheDocument();
|
||||
expect(screen.getByText('errParams: /foo')).toBeInTheDocument();
|
||||
expect(screen.getByText('errOptional: <none>')).toBeInTheDocument();
|
||||
expect(screen.getByText('errParamsOptional: <none>')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should throw some error when the route has duplicate params', () => {
|
||||
const app = new PrivateAppImpl({
|
||||
apis: [],
|
||||
defaultApis: [],
|
||||
themes: [
|
||||
{
|
||||
id: 'light',
|
||||
title: 'Light Theme',
|
||||
variant: 'light',
|
||||
theme: lightTheme,
|
||||
},
|
||||
],
|
||||
icons: defaultSystemIcons,
|
||||
plugins: [],
|
||||
components,
|
||||
bindRoutes: ({ bind }) => {
|
||||
bind(plugin1.externalRoutes, {
|
||||
err: plugin1RouteRef,
|
||||
errParams: plugin2RouteRef,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -50,14 +50,14 @@ import {
|
||||
} from '../extensions/traversal';
|
||||
import { IconComponent, IconComponentMap, IconKey } from '../icons';
|
||||
import { BackstagePlugin } from '../plugin';
|
||||
import { RouteRef } from '../routing';
|
||||
import { AnyRoutes } from '../plugin/types';
|
||||
import { RouteRef, ExternalRouteRef } from '../routing';
|
||||
import {
|
||||
routeObjectCollector,
|
||||
routeParentCollector,
|
||||
routePathCollector,
|
||||
} from '../routing/collectors';
|
||||
import { RoutingProvider, validateRoutes } from '../routing/hooks';
|
||||
import { ExternalRouteRef } from '../routing/RouteRef';
|
||||
import { AppContextProvider } from './AppContext';
|
||||
import { AppIdentity } from './AppIdentity';
|
||||
import { AppThemeProvider } from './AppThemeProvider';
|
||||
@@ -78,7 +78,7 @@ export function generateBoundRoutes(
|
||||
const result = new Map<ExternalRouteRef, RouteRef>();
|
||||
|
||||
if (bindRoutes) {
|
||||
const bind: AppRouteBinder = (externalRoutes, targetRoutes) => {
|
||||
const bind: AppRouteBinder = (externalRoutes, targetRoutes: AnyRoutes) => {
|
||||
for (const [key, value] of Object.entries(targetRoutes)) {
|
||||
const externalRoute = externalRoutes[key];
|
||||
if (!externalRoute) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import { IconComponent, IconComponentMap, IconKey } from '../icons';
|
||||
import { BackstagePlugin } from '../plugin/types';
|
||||
import { AnyExternalRoutes, BackstagePlugin } from '../plugin/types';
|
||||
import { ExternalRouteRef, RouteRef } from '../routing';
|
||||
import { AnyApiFactory } from '../apis';
|
||||
import { AppTheme, ProfileInfo } from '../apis/definitions';
|
||||
@@ -79,49 +79,39 @@ export type AppComponents = {
|
||||
*/
|
||||
export type AppConfigLoader = () => Promise<AppConfig[]>;
|
||||
|
||||
/**
|
||||
* Extracts the Optional type of a map of ExternalRouteRefs, leaving only the boolean in place as value
|
||||
*/
|
||||
type ExternalRouteRefsToOptionalMap<
|
||||
T extends { [name in string]: ExternalRouteRef<boolean> }
|
||||
> = {
|
||||
[name in keyof T]: T[name] extends ExternalRouteRef<infer U> ? U : never;
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts a union of the keys in a map whose value extends the given type
|
||||
*/
|
||||
type ExtractKeysWithType<Obj extends { [key in string]: any }, Type> = {
|
||||
type KeysWithType<Obj extends { [key in string]: any }, Type> = {
|
||||
[key in keyof Obj]: Obj[key] extends Type ? key : never;
|
||||
}[keyof Obj];
|
||||
|
||||
/**
|
||||
* Given a map of boolean values denoting whether a route is optional, create a
|
||||
* map of needed RouteRefs.
|
||||
*
|
||||
* For example { foo: false, bar: true } gives { foo: RouteRef<any>, bar?: RouteRef<any> }
|
||||
* Takes a map Map required values and makes all keys matching Keys optional
|
||||
*/
|
||||
type CombineOptionalAndRequiredRoutes<
|
||||
OptionalMap extends { [key in string]: boolean }
|
||||
> = {
|
||||
[name in ExtractKeysWithType<OptionalMap, false>]: RouteRef<any>;
|
||||
} &
|
||||
{ [name in keyof OptionalMap]?: RouteRef<any> };
|
||||
type PartialKeys<
|
||||
Map extends { [name in string]: any },
|
||||
Keys extends keyof Map
|
||||
> = Partial<Pick<Map, Keys>> & Required<Omit<Map, Keys>>;
|
||||
|
||||
/**
|
||||
* Creates a map of required target routes based on whether the input external
|
||||
* routes are optional or not. The external routes that are marked as optional
|
||||
* will also be optional in the target routes map.
|
||||
* Creates a map of target routes with matching parameters based on a map of external routes.
|
||||
*/
|
||||
type TargetRoutesMap<
|
||||
T extends { [name in string]: ExternalRouteRef<boolean> }
|
||||
> = CombineOptionalAndRequiredRoutes<ExternalRouteRefsToOptionalMap<T>>;
|
||||
type TargetRouteMap<ExternalRoutes extends AnyExternalRoutes> = {
|
||||
[name in keyof ExternalRoutes]: ExternalRoutes[name] extends ExternalRouteRef<
|
||||
infer Params,
|
||||
any
|
||||
>
|
||||
? RouteRef<Params>
|
||||
: never;
|
||||
};
|
||||
|
||||
export type AppRouteBinder = <
|
||||
ExternalRoutes extends { [name in string]: ExternalRouteRef<boolean> }
|
||||
>(
|
||||
export type AppRouteBinder = <ExternalRoutes extends AnyExternalRoutes>(
|
||||
externalRoutes: ExternalRoutes,
|
||||
targetRoutes: TargetRoutesMap<ExternalRoutes>,
|
||||
targetRoutes: PartialKeys<
|
||||
TargetRouteMap<ExternalRoutes>,
|
||||
KeysWithType<ExternalRoutes, ExternalRouteRef<any, true>>
|
||||
>,
|
||||
) => void;
|
||||
|
||||
export type AppOptions = {
|
||||
|
||||
@@ -100,19 +100,16 @@ describe('elementData', () => {
|
||||
const element = <Component />;
|
||||
const container = (global as any)[
|
||||
'__@backstage/component-data-store__'
|
||||
].store.get(element.type);
|
||||
].get(element.type);
|
||||
expect(container.map.get('my-data')).toBe(data);
|
||||
});
|
||||
|
||||
it('should should be able to attach data for newer versions', () => {
|
||||
const data = { foo: 'bar' };
|
||||
const Component = () => null;
|
||||
(global as any)['__@backstage/component-data-store__'].store.set(
|
||||
Component,
|
||||
{
|
||||
map: new Map([['my-data', data]]),
|
||||
},
|
||||
);
|
||||
(global as any)['__@backstage/component-data-store__'].set(Component, {
|
||||
map: new Map([['my-data', data]]),
|
||||
});
|
||||
|
||||
const element = <Component />;
|
||||
expect(getComponentData(element, 'my-data')).toBe(data);
|
||||
|
||||
@@ -33,9 +33,10 @@ type MaybeComponentNode = ReactNode & {
|
||||
};
|
||||
|
||||
// The store is bridged across versions using the global object
|
||||
const { store } = getGlobalSingleton('component-data-store', () => ({
|
||||
store: new WeakMap<ComponentType<any>, DataContainer>(),
|
||||
}));
|
||||
const store = getGlobalSingleton(
|
||||
'component-data-store',
|
||||
() => new WeakMap<ComponentType<any>, DataContainer>(),
|
||||
);
|
||||
|
||||
export function attachComponentData<P>(
|
||||
component: ComponentType<P>,
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import { RouteRef } from '../routing';
|
||||
import { RouteRef, ExternalRouteRef } from '../routing';
|
||||
import { AnyApiFactory } from '../apis/system';
|
||||
import { ExternalRouteRef } from '../routing/RouteRef';
|
||||
|
||||
export type RouteOptions = {
|
||||
// Whether the route path must match exactly, defaults to true.
|
||||
|
||||
@@ -14,19 +14,40 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { RouteRef } from './types';
|
||||
import {
|
||||
RouteRef,
|
||||
ExternalRouteRef,
|
||||
routeRefType,
|
||||
AnyParams,
|
||||
ParamKeys,
|
||||
} from './types';
|
||||
import { IconComponent } from '../icons';
|
||||
|
||||
export type RouteRefConfig<Params extends { [param in string]: string }> = {
|
||||
params?: Array<keyof Params>;
|
||||
/** @deprecated Route refs no longer decide their own path */
|
||||
// TODO(Rugvip): Remove this once we get rid of the deprecated fields, it's not exported
|
||||
export type RouteRefConfig<Params extends AnyParams> = {
|
||||
params?: ParamKeys<Params>;
|
||||
path?: string;
|
||||
icon?: IconComponent;
|
||||
title: string;
|
||||
};
|
||||
|
||||
export class AbsoluteRouteRef<Params extends { [param in string]: string }> {
|
||||
constructor(private readonly config: RouteRefConfig<Params>) {}
|
||||
class RouteRefBase {
|
||||
constructor(type: string, id: string) {
|
||||
this.toString = () => `routeRef{type=${type},id=${id}}`;
|
||||
}
|
||||
}
|
||||
|
||||
export class RouteRefImpl<Params extends AnyParams> extends RouteRefBase
|
||||
implements RouteRef<Params> {
|
||||
readonly [routeRefType] = 'absolute';
|
||||
|
||||
constructor(private readonly config: RouteRefConfig<Params>) {
|
||||
super('absolute', config.title);
|
||||
}
|
||||
|
||||
get params(): ParamKeys<Params> {
|
||||
return this.config.params as any;
|
||||
}
|
||||
|
||||
get icon() {
|
||||
return this.config.icon;
|
||||
@@ -40,12 +61,12 @@ export class AbsoluteRouteRef<Params extends { [param in string]: string }> {
|
||||
get title() {
|
||||
return this.config.title;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `routeRef{title=${this.title}}`;
|
||||
}
|
||||
}
|
||||
|
||||
type OptionalParams<
|
||||
Params extends { [param in string]: string }
|
||||
> = Params[keyof Params] extends never ? undefined : Params;
|
||||
|
||||
export function createRouteRef<
|
||||
// Params is the type that we care about and the one to be embedded in the route ref.
|
||||
// For example, given the params ['name', 'kind'], Params will be {name: string, kind: string}
|
||||
@@ -58,27 +79,47 @@ export function createRouteRef<
|
||||
params?: ParamKey[];
|
||||
/** @deprecated Route refs no longer decide their own path */
|
||||
path?: string;
|
||||
/** @deprecated Route refs no longer decide their own icon */
|
||||
icon?: IconComponent;
|
||||
/** @deprecated Route refs no longer decide their own title */
|
||||
title: string;
|
||||
}): RouteRef<Params> {
|
||||
return new AbsoluteRouteRef<Params>(config);
|
||||
}): RouteRef<OptionalParams<Params>> {
|
||||
return new RouteRefImpl<OptionalParams<Params>>({
|
||||
...config,
|
||||
params: (config.params ?? []) as ParamKeys<OptionalParams<Params>>,
|
||||
});
|
||||
}
|
||||
|
||||
export class ExternalRouteRef<Optional extends boolean = true> {
|
||||
readonly optional: boolean;
|
||||
export class ExternalRouteRefImpl<
|
||||
Params extends AnyParams,
|
||||
Optional extends boolean
|
||||
> extends RouteRefBase implements ExternalRouteRef<Params, Optional> {
|
||||
readonly [routeRefType] = 'external';
|
||||
|
||||
private constructor({ id, optional }: ExternalRouteRefOptions<Optional>) {
|
||||
this.toString = () => `externalRouteRef{${id}}`;
|
||||
this.optional = Boolean(optional);
|
||||
constructor(
|
||||
id: string,
|
||||
readonly params: ParamKeys<Params>,
|
||||
readonly optional: Optional,
|
||||
) {
|
||||
super('external', id);
|
||||
}
|
||||
}
|
||||
|
||||
export type ExternalRouteRefOptions<Optional extends boolean = false> = {
|
||||
export function createExternalRouteRef<
|
||||
Params extends { [param in ParamKey]: string },
|
||||
Optional extends boolean = false,
|
||||
ParamKey extends string = never
|
||||
>(options: {
|
||||
/**
|
||||
* An identifier for this route, used to identify it in error messages
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* The parameters that will be provided to the external route reference.
|
||||
*/
|
||||
params?: ParamKey[];
|
||||
|
||||
/**
|
||||
* Whether or not this route is optional, defaults to false.
|
||||
*
|
||||
@@ -86,14 +127,10 @@ export type ExternalRouteRefOptions<Optional extends boolean = false> = {
|
||||
* if they aren't, `useRouteRef` will return `undefined`.
|
||||
*/
|
||||
optional?: Optional;
|
||||
};
|
||||
|
||||
export function createExternalRouteRef<Optional extends boolean = false>(
|
||||
options: ExternalRouteRefOptions<Optional>,
|
||||
): ExternalRouteRef<Optional> {
|
||||
return new ((ExternalRouteRef as unknown) as {
|
||||
new (options: ExternalRouteRefOptions<Optional>): ExternalRouteRef<
|
||||
Optional
|
||||
>;
|
||||
})(options);
|
||||
}): ExternalRouteRef<OptionalParams<Params>, Optional> {
|
||||
return new ExternalRouteRefImpl<OptionalParams<Params>, Optional>(
|
||||
options.id,
|
||||
(options.params ?? []) as ParamKeys<OptionalParams<Params>>,
|
||||
Boolean(options.optional) as Optional,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -38,10 +38,9 @@ import {
|
||||
import {
|
||||
createRouteRef,
|
||||
createExternalRouteRef,
|
||||
ExternalRouteRef,
|
||||
RouteRefConfig,
|
||||
} from './RouteRef';
|
||||
import { AnyRouteRef, RouteRef } from './types';
|
||||
import { AnyRouteRef, RouteRef, ExternalRouteRef } from './types';
|
||||
|
||||
const mockConfig = (extra?: Partial<RouteRefConfig<{}>>) => ({
|
||||
path: '/unused',
|
||||
@@ -58,12 +57,19 @@ const ref1 = createRouteRef(mockConfig({ path: '/wat1' }));
|
||||
const ref2 = createRouteRef(mockConfig({ path: '/wat2' }));
|
||||
const ref3 = createRouteRef(mockConfig({ path: '/wat3' }));
|
||||
const ref4 = createRouteRef(mockConfig({ path: '/wat4' }));
|
||||
const ref5 = createRouteRef(mockConfig({ path: '/wat5' }));
|
||||
const ref5 = createRouteRef({
|
||||
...mockConfig({ path: '/wat5' }),
|
||||
params: ['x'],
|
||||
});
|
||||
const eRefA = createExternalRouteRef({ id: '1' });
|
||||
const eRefB = createExternalRouteRef({ id: '2' });
|
||||
const eRefC = createExternalRouteRef({ id: '3' });
|
||||
const eRefC = createExternalRouteRef({ id: '3', params: ['y'] });
|
||||
const eRefD = createExternalRouteRef({ id: '4', optional: true });
|
||||
const eRefE = createExternalRouteRef({ id: '5', optional: true });
|
||||
const eRefE = createExternalRouteRef({
|
||||
id: '5',
|
||||
optional: true,
|
||||
params: ['z'],
|
||||
});
|
||||
|
||||
const MockRouteSource = <T extends { [name in string]: string }>(props: {
|
||||
path?: string;
|
||||
|
||||
@@ -15,19 +15,22 @@
|
||||
*/
|
||||
|
||||
import React, { createContext, ReactNode, useContext, useMemo } from 'react';
|
||||
import { AnyRouteRef, BackstageRouteObject, RouteRef } from './types';
|
||||
import {
|
||||
AnyRouteRef,
|
||||
BackstageRouteObject,
|
||||
RouteRef,
|
||||
ExternalRouteRef,
|
||||
AnyParams,
|
||||
} from './types';
|
||||
import { generatePath, matchRoutes, useLocation } from 'react-router-dom';
|
||||
import { ExternalRouteRef } from './RouteRef';
|
||||
|
||||
// The extra TS magic here is to require a single params argument if the RouteRef
|
||||
// had at least one param defined, but require 0 arguments if there are no params defined.
|
||||
// Without this we'd have to pass in empty object to all parameter-less RouteRefs
|
||||
// just to make TypeScript happy, or we would have to make the argument optional in
|
||||
// which case you might forget to pass it in when it is actually required.
|
||||
export type RouteFunc<Params extends { [param in string]: string }> = (
|
||||
...[params]: Params[keyof Params] extends never
|
||||
? readonly []
|
||||
: readonly [Params]
|
||||
export type RouteFunc<Params extends AnyParams> = (
|
||||
...[params]: Params extends undefined ? readonly [] : readonly [Params]
|
||||
) => string;
|
||||
|
||||
class RouteResolver {
|
||||
@@ -38,8 +41,8 @@ class RouteResolver {
|
||||
private readonly routeBindings: Map<RouteRef | ExternalRouteRef, RouteRef>,
|
||||
) {}
|
||||
|
||||
resolve<Params extends { [param in string]: string }>(
|
||||
routeRefOrExternalRouteRef: RouteRef<Params> | ExternalRouteRef,
|
||||
resolve<Params extends AnyParams>(
|
||||
routeRefOrExternalRouteRef: RouteRef<Params> | ExternalRouteRef<Params>,
|
||||
sourceLocation: ReturnType<typeof useLocation>,
|
||||
): RouteFunc<Params> | undefined {
|
||||
const routeRef =
|
||||
@@ -112,14 +115,14 @@ class RouteResolver {
|
||||
|
||||
const RoutingContext = createContext<RouteResolver | undefined>(undefined);
|
||||
|
||||
export function useRouteRef<Optional extends boolean>(
|
||||
routeRef: ExternalRouteRef<Optional>,
|
||||
): Optional extends true ? RouteFunc<{}> | undefined : RouteFunc<{}>;
|
||||
export function useRouteRef<Params extends { [param in string]: string } = {}>(
|
||||
export function useRouteRef<Optional extends boolean, Params extends AnyParams>(
|
||||
routeRef: ExternalRouteRef<Params, Optional>,
|
||||
): Optional extends true ? RouteFunc<Params> | undefined : RouteFunc<Params>;
|
||||
export function useRouteRef<Params extends AnyParams>(
|
||||
routeRef: RouteRef<Params>,
|
||||
): RouteFunc<Params>;
|
||||
export function useRouteRef<Params extends { [param in string]: string } = {}>(
|
||||
routeRef: RouteRef<Params> | ExternalRouteRef,
|
||||
export function useRouteRef<Params extends AnyParams>(
|
||||
routeRef: RouteRef<Params> | ExternalRouteRef<Params, any>,
|
||||
): RouteFunc<Params> | undefined {
|
||||
const sourceLocation = useLocation();
|
||||
const resolver = useContext(RoutingContext);
|
||||
|
||||
@@ -19,12 +19,9 @@ export type {
|
||||
AbsoluteRouteRef,
|
||||
ConcreteRoute,
|
||||
MutableRouteRef,
|
||||
ExternalRouteRef,
|
||||
} from './types';
|
||||
export { FlatRoutes } from './FlatRoutes';
|
||||
export {
|
||||
createRouteRef,
|
||||
createExternalRouteRef,
|
||||
ExternalRouteRef,
|
||||
} from './RouteRef';
|
||||
export { createRouteRef, createExternalRouteRef } from './RouteRef';
|
||||
export type { RouteRefConfig } from './RouteRef';
|
||||
export { useRouteRef } from './hooks';
|
||||
|
||||
@@ -15,35 +15,51 @@
|
||||
*/
|
||||
|
||||
import { IconComponent } from '../icons';
|
||||
import { ExternalRouteRef } from './RouteRef';
|
||||
import { getGlobalSingleton } from '../lib/globalObject';
|
||||
|
||||
// @ts-ignore, we're just embedding the Params type for usage in other places
|
||||
export type RouteRef<Params extends { [param in string]: string } = {}> = {
|
||||
// TODO(Rugvip): Remove path, look up via registry instead
|
||||
export type AnyParams = { [param in string]: string } | undefined;
|
||||
export type ParamKeys<Params extends AnyParams> = keyof Params extends never
|
||||
? []
|
||||
: (keyof Params)[];
|
||||
|
||||
export const routeRefType: unique symbol = getGlobalSingleton<any>(
|
||||
'route-ref-type',
|
||||
() => Symbol('route-ref-type'),
|
||||
);
|
||||
|
||||
export type RouteRef<Params extends AnyParams = any> = {
|
||||
readonly [routeRefType]: 'absolute';
|
||||
|
||||
params: ParamKeys<Params>;
|
||||
|
||||
// TODO(Rugvip): Remove all of these once plugins don't rely on the path
|
||||
/** @deprecated paths are no longer accessed directly from RouteRefs, use useRouteRef instead */
|
||||
path: string;
|
||||
/** @deprecated icons are no longer accessed via RouteRefs */
|
||||
icon?: IconComponent;
|
||||
title: string;
|
||||
/** @deprecated titles are no longer accessed via RouteRefs */
|
||||
title?: string;
|
||||
};
|
||||
|
||||
export type AnyRouteRef = RouteRef<any> | ExternalRouteRef<any>;
|
||||
export type ExternalRouteRef<
|
||||
Params extends AnyParams = any,
|
||||
Optional extends boolean = any
|
||||
> = {
|
||||
readonly [routeRefType]: 'external';
|
||||
|
||||
/**
|
||||
* This type should not be used
|
||||
* @deprecated
|
||||
*/
|
||||
params: ParamKeys<Params>;
|
||||
|
||||
optional?: Optional;
|
||||
};
|
||||
|
||||
export type AnyRouteRef = RouteRef<any> | ExternalRouteRef<any, any>;
|
||||
|
||||
// TODO(Rugvip): None of these should be found in the wild anymore, remove in next minor release
|
||||
/** @deprecated */
|
||||
export type ConcreteRoute = {};
|
||||
|
||||
/**
|
||||
* This type should not be used, use RouteRef instead
|
||||
* @deprecated
|
||||
*/
|
||||
/** @deprecated */
|
||||
export type AbsoluteRouteRef = RouteRef<{}>;
|
||||
|
||||
/**
|
||||
* This type should not be used, use RouteRef instead
|
||||
* @deprecated
|
||||
*/
|
||||
/** @deprecated */
|
||||
export type MutableRouteRef = RouteRef<{}>;
|
||||
|
||||
// A duplicate of the react-router RouteObject, but with routeRef added
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
# @backstage/core
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 4c049a1a1: - Adds onClick and other props to IconLinkVertical;
|
||||
|
||||
- Allows TriggerButton component to render when pager duty key is missing;
|
||||
- Refactors TriggerButton and PagerDutyCard not to have shared state;
|
||||
- Removes the `action` prop of the IconLinkVertical component while adding `onClick`.
|
||||
|
||||
Instead of having an action including a button with onClick, now the whole component can be clickable making it easier to implement and having a better UX.
|
||||
|
||||
Before:
|
||||
|
||||
```ts
|
||||
const myLink: IconLinkVerticalProps = {
|
||||
label: 'Click me',
|
||||
action: <Button onClick={myAction} />,
|
||||
icon: <MyIcon onClick={myAction} />,
|
||||
};
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```ts
|
||||
const myLink: IconLinkVerticalProps = {
|
||||
label: 'Click me',
|
||||
onClick: myAction,
|
||||
icon: <MyIcon />,
|
||||
};
|
||||
```
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 40c0fdbaa: Added support for optional external route references. By setting `optional: true` when creating an `ExternalRouteRef` it is no longer a requirement to bind the route in the app. If the app isn't bound `useRouteRef` will return `undefined`.
|
||||
- 2a271d89e: Internal refactor of how component data is access to avoid polluting components and make it possible to bridge across versions.
|
||||
- bece09057: Improve rendering of multiple support item links in the `SupportButton`
|
||||
- 169f48deb: Added the color prop to TrendLine from the Sparklines props types to be able to have custom colors.
|
||||
- 8a1566719: Added a new useSupportConfig hook that reads a new `app.support` config key. Also updated the SupportButton and ErrorPage components to use the new config.
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- @backstage/core-api@0.2.12
|
||||
|
||||
## 0.6.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/core",
|
||||
"description": "Core API used by Backstage plugins and apps",
|
||||
"version": "0.6.3",
|
||||
"version": "0.7.0",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@backstage/core-api": "^0.2.11",
|
||||
"@backstage/core-api": "^0.2.12",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -68,7 +68,7 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
||||
@@ -1,5 +1,167 @@
|
||||
# @backstage/create-app
|
||||
|
||||
## 0.3.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f71589800: The api-docs plugin has been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page.
|
||||
|
||||
If you want to have a button that links to the scaffolder plugin from the API explorer, apply the following changes to `packages/app/src/App.tsx`:
|
||||
|
||||
```diff
|
||||
+ import { apiDocsPlugin } from '@backstage/plugin-api-docs';
|
||||
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
|
||||
|
||||
const app = createApp({
|
||||
// ...
|
||||
bindRoutes({ bind }) {
|
||||
+ bind(apiDocsPlugin.externalRoutes, {
|
||||
+ createComponent: scaffolderPlugin.routes.root,
|
||||
+ });
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you choose to not bind the routes, the button to create new APIs is not displayed.
|
||||
|
||||
- 7a1b2ba0e: Migrated away from using deprecated routes and router components at top-level in the app, and instead use routable extension pages.
|
||||
|
||||
To apply this change to an existing app, make the following changes to `packages/app/src/App.tsx`:
|
||||
|
||||
Update imports and remove the usage of the deprecated `app.getRoutes()`.
|
||||
|
||||
```diff
|
||||
-import { Router as DocsRouter } from '@backstage/plugin-techdocs';
|
||||
+import { TechdocsPage } from '@backstage/plugin-techdocs';
|
||||
import { CatalogImportPage } from '@backstage/plugin-catalog-import';
|
||||
-import { Router as TechRadarRouter } from '@backstage/plugin-tech-radar';
|
||||
-import { SearchPage as SearchRouter } from '@backstage/plugin-search';
|
||||
-import { Router as SettingsRouter } from '@backstage/plugin-user-settings';
|
||||
+import { TechRadarPage } from '@backstage/plugin-tech-radar';
|
||||
+import { SearchPage } from '@backstage/plugin-search';
|
||||
+import { UserSettingsPage } from '@backstage/plugin-user-settings';
|
||||
+import { ApiExplorerPage } from '@backstage/plugin-api-docs';
|
||||
import { EntityPage } from './components/catalog/EntityPage';
|
||||
import { scaffolderPlugin, ScaffolderPage } from '@backstage/plugin-scaffolder';
|
||||
```
|
||||
|
||||
const AppProvider = app.getProvider();
|
||||
const AppRouter = app.getRouter();
|
||||
-const deprecatedAppRoutes = app.getRoutes();
|
||||
|
||||
````
|
||||
|
||||
As well as update or add the following routes:
|
||||
|
||||
```diff
|
||||
<Route path="/create" element={<ScaffolderPage />} />
|
||||
- <Route path="/docs" element={<DocsRouter />} />
|
||||
+ <Route path="/docs" element={<TechdocsPage />} />
|
||||
+ <Route path="/api-docs" element={<ApiExplorerPage />} />
|
||||
<Route
|
||||
path="/tech-radar"
|
||||
- element={<TechRadarRouter width={1500} height={800} />}
|
||||
+ element={<TechRadarPage width={1500} height={800} />}
|
||||
/>
|
||||
<Route path="/catalog-import" element={<CatalogImportPage />} />
|
||||
- <Route
|
||||
- path="/search"
|
||||
- element={<SearchRouter/>}
|
||||
- />
|
||||
- <Route path="/settings" element={<SettingsRouter />} />
|
||||
- {deprecatedAppRoutes}
|
||||
+ <Route path="/search" element={<SearchPage />} />
|
||||
+ <Route path="/settings" element={<UserSettingsPage />} />
|
||||
````
|
||||
|
||||
If you have added additional plugins with registered routes or are using `Router` components from other plugins, these should be migrated to use the `*Page` components as well. See [this commit](https://github.com/backstage/backstage/commit/abd655e42d4ed416b70848ffdb1c4b99d189f13b) for more examples of how to migrate.
|
||||
|
||||
For more information and the background to this change, see the [composability system migration docs](https://backstage.io/docs/plugins/composability).
|
||||
|
||||
- 415a3a42d: Updated the default `App` test to work better on Windows.
|
||||
|
||||
To apply this change to an existing app, replace the `process.env.APP_CONFIG` definition in `packages/app/src/App.test.tsx` with the following:
|
||||
|
||||
```ts
|
||||
process.env = {
|
||||
NODE_ENV: 'test',
|
||||
APP_CONFIG: [
|
||||
{
|
||||
data: {
|
||||
app: { title: 'Test' },
|
||||
backend: { baseUrl: 'http://localhost:7000' },
|
||||
techdocs: {
|
||||
storageUrl: 'http://localhost:7000/api/techdocs/static/docs',
|
||||
},
|
||||
},
|
||||
context: 'test',
|
||||
},
|
||||
] as any,
|
||||
};
|
||||
```
|
||||
|
||||
- Updated dependencies [b2a5320a4]
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [507513fed]
|
||||
- Updated dependencies [52b5bc3e2]
|
||||
- Updated dependencies [ecdd407b1]
|
||||
- Updated dependencies [32a003973]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [497859088]
|
||||
- Updated dependencies [1987c9341]
|
||||
- Updated dependencies [f31b76b44]
|
||||
- Updated dependencies [15eee03bc]
|
||||
- Updated dependencies [f43192207]
|
||||
- Updated dependencies [cfc83cac1]
|
||||
- Updated dependencies [8adb48df4]
|
||||
- Updated dependencies [bc327dc42]
|
||||
- Updated dependencies [2386de1d3]
|
||||
- Updated dependencies [9ce68b677]
|
||||
- Updated dependencies [10362e9eb]
|
||||
- Updated dependencies [e37d2de99]
|
||||
- Updated dependencies [813c6a4f2]
|
||||
- Updated dependencies [11c6208fe]
|
||||
- Updated dependencies [8106c9528]
|
||||
- Updated dependencies [05183f202]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [f71589800]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- Updated dependencies [bece09057]
|
||||
- Updated dependencies [d4f0a1406]
|
||||
- Updated dependencies [169f48deb]
|
||||
- Updated dependencies [8a1566719]
|
||||
- Updated dependencies [d0ed25196]
|
||||
- Updated dependencies [4c049a1a1]
|
||||
- Updated dependencies [96ccc8f69]
|
||||
- Updated dependencies [3af994c81]
|
||||
- Updated dependencies [b33e553b2]
|
||||
- Updated dependencies [04667f571]
|
||||
- Updated dependencies [b93538acc]
|
||||
- Updated dependencies [8871e7523]
|
||||
- Updated dependencies [dbea11072]
|
||||
- @backstage/plugin-circleci@0.2.11
|
||||
- @backstage/plugin-github-actions@0.3.5
|
||||
- @backstage/plugin-scaffolder@0.7.0
|
||||
- @backstage/plugin-scaffolder-backend@0.9.0
|
||||
- @backstage/cli@0.6.3
|
||||
- @backstage/plugin-techdocs-backend@0.6.3
|
||||
- @backstage/plugin-catalog-backend@0.6.4
|
||||
- @backstage/plugin-api-docs@0.4.8
|
||||
- @backstage/plugin-catalog@0.4.1
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/backend-common@0.5.5
|
||||
- @backstage/plugin-proxy-backend@0.2.5
|
||||
- @backstage/plugin-auth-backend@0.3.3
|
||||
- @backstage/plugin-explore@0.3.0
|
||||
- @backstage/plugin-techdocs@0.6.0
|
||||
- @backstage/plugin-catalog-import@0.4.3
|
||||
- @backstage/core@0.7.0
|
||||
- @backstage/plugin-lighthouse@0.2.13
|
||||
- @backstage/plugin-search@0.3.3
|
||||
- @backstage/plugin-tech-radar@0.3.7
|
||||
- @backstage/plugin-user-settings@0.2.7
|
||||
|
||||
## 0.3.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/create-app",
|
||||
"description": "Create app package for Backstage",
|
||||
"version": "0.3.11",
|
||||
"version": "0.3.12",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @backstage/dev-utils
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- Updated dependencies [bece09057]
|
||||
- Updated dependencies [169f48deb]
|
||||
- Updated dependencies [8a1566719]
|
||||
- Updated dependencies [9d455f69a]
|
||||
- Updated dependencies [4c049a1a1]
|
||||
- Updated dependencies [02816ecd7]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/core@0.7.0
|
||||
- @backstage/plugin-catalog-react@0.1.1
|
||||
|
||||
## 0.1.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/dev-utils",
|
||||
"description": "Utilities for developing Backstage plugins.",
|
||||
"version": "0.1.12",
|
||||
"version": "0.1.13",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -29,9 +29,9 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core": "^0.6.3",
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/plugin-catalog-react": "^0.1.0",
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/plugin-catalog-react": "^0.1.1",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
@@ -47,7 +47,7 @@
|
||||
"react-router-dom": "6.0.0-beta.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^12.0.0"
|
||||
},
|
||||
|
||||
@@ -42,33 +42,44 @@ const templatePackagePaths = [
|
||||
];
|
||||
|
||||
export async function run() {
|
||||
const rootDir = await fs.mkdtemp(resolvePath(os.tmpdir(), 'backstage-e2e-'));
|
||||
print(`CLI E2E test root: ${rootDir}\n`);
|
||||
try {
|
||||
const rootDir = await fs.mkdtemp(
|
||||
resolvePath(os.tmpdir(), 'backstage-e2e-'),
|
||||
);
|
||||
print(`CLI E2E test root: ${rootDir}\n`);
|
||||
|
||||
print('Building dist workspace');
|
||||
const workspaceDir = await buildDistWorkspace('workspace', rootDir);
|
||||
print('Building dist workspace');
|
||||
const workspaceDir = await buildDistWorkspace('workspace', rootDir);
|
||||
|
||||
const isPostgres = Boolean(process.env.POSTGRES_USER);
|
||||
print('Creating a Backstage App');
|
||||
const appDir = await createApp('test-app', isPostgres, workspaceDir, rootDir);
|
||||
const isPostgres = Boolean(process.env.POSTGRES_USER);
|
||||
print('Creating a Backstage App');
|
||||
const appDir = await createApp(
|
||||
'test-app',
|
||||
isPostgres,
|
||||
workspaceDir,
|
||||
rootDir,
|
||||
);
|
||||
|
||||
print('Creating a Backstage Plugin');
|
||||
const pluginName = await createPlugin('test-plugin', appDir);
|
||||
print('Creating a Backstage Plugin');
|
||||
const pluginName = await createPlugin('test-plugin', appDir);
|
||||
|
||||
print('Creating a Backstage Backend Plugin');
|
||||
await createPlugin('test-plugin', appDir, ['--backend']);
|
||||
print('Creating a Backstage Backend Plugin');
|
||||
await createPlugin('test-plugin', appDir, ['--backend']);
|
||||
|
||||
print('Starting the app');
|
||||
await testAppServe(pluginName, appDir);
|
||||
print('Starting the app');
|
||||
await testAppServe(pluginName, appDir);
|
||||
|
||||
print('Testing the backend startup');
|
||||
await testBackendStart(appDir, isPostgres);
|
||||
print('Testing the backend startup');
|
||||
await testBackendStart(appDir, isPostgres);
|
||||
|
||||
print('All tests successful, removing test dir');
|
||||
await fs.remove(rootDir);
|
||||
print('All tests successful, removing test dir');
|
||||
await fs.remove(rootDir);
|
||||
|
||||
// Just in case some child process was left hanging
|
||||
process.exit(0);
|
||||
// Just in case some child process was left hanging
|
||||
process.exit(0);
|
||||
} catch {
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @backstage/techdocs-common
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f43192207: remove usage of res.send() for res.json() and res.end() to ensure content types are more consistently application/json on backend responses and error cases
|
||||
- 61299519f: Remove read-store-upload loop when uploading S3 objects for TechDocs
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [497859088]
|
||||
- Updated dependencies [8adb48df4]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/backend-common@0.5.5
|
||||
|
||||
## 0.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -17,11 +17,13 @@ import type {
|
||||
BlobUploadCommonResponse,
|
||||
ContainerGetPropertiesResponse,
|
||||
} from '@azure/storage-blob';
|
||||
import { EventEmitter } from 'events';
|
||||
import fs from 'fs-extra';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
const rootDir = os.platform() === 'win32' ? 'C:\\rootDir' : '/rootDir';
|
||||
|
||||
/**
|
||||
* @param sourceFile Relative path to entity root dir. Contains either / or \ as file separator
|
||||
* depending upon the OS.
|
||||
@@ -48,6 +50,9 @@ export class BlockBlobClient {
|
||||
}
|
||||
|
||||
uploadFile(source: string): Promise<BlobUploadCommonResponse> {
|
||||
if (!fs.existsSync(source)) {
|
||||
return Promise.reject(new Error(`The file ${source} does not exist`));
|
||||
}
|
||||
return Promise.resolve({
|
||||
_response: {
|
||||
request: {
|
||||
@@ -62,6 +67,25 @@ export class BlockBlobClient {
|
||||
exists() {
|
||||
return checkFileExists(this.blobName);
|
||||
}
|
||||
|
||||
download() {
|
||||
const filePath = path.join(rootDir, this.blobName);
|
||||
const emitter = new EventEmitter();
|
||||
process.nextTick(() => {
|
||||
if (fs.existsSync(filePath)) {
|
||||
emitter.emit('data', Buffer.from(fs.readFileSync(filePath)));
|
||||
emitter.emit('end');
|
||||
} else {
|
||||
emitter.emit(
|
||||
'error',
|
||||
new Error(`The file ${filePath} does not exist !`),
|
||||
);
|
||||
}
|
||||
});
|
||||
return Promise.resolve({
|
||||
readableStreamBody: emitter,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class BlockBlobClientFailUpload extends BlockBlobClient {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/techdocs-common",
|
||||
"description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.3",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -38,8 +38,8 @@
|
||||
"dependencies": {
|
||||
"@azure/identity": "^1.2.2",
|
||||
"@azure/storage-blob": "^12.4.0",
|
||||
"@backstage/backend-common": "^0.5.4",
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/backend-common": "^0.5.5",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@backstage/integration": "^0.5.0",
|
||||
"@google-cloud/storage": "^5.6.0",
|
||||
@@ -60,7 +60,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@types/fs-extra": "^9.0.5",
|
||||
"@types/git-url-parse": "^9.0.0",
|
||||
"@types/js-yaml": "^3.12.5",
|
||||
|
||||
@@ -14,13 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { getVoidLogger } from '@backstage/backend-common';
|
||||
import { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model';
|
||||
import {
|
||||
Entity,
|
||||
EntityName,
|
||||
ENTITY_DEFAULT_NAMESPACE,
|
||||
} from '@backstage/catalog-model';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import mockFs from 'mock-fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { AzureBlobStoragePublish } from './azureBlobStorage';
|
||||
import { PublisherBase } from './types';
|
||||
import { PublisherBase, TechDocsMetadata } from './types';
|
||||
|
||||
// NOTE: /packages/techdocs-common/__mocks__ is being used to mock Azure client library
|
||||
|
||||
@@ -38,7 +42,14 @@ const createMockEntity = (annotations = {}) => {
|
||||
};
|
||||
};
|
||||
|
||||
const createMockEntityName = (): EntityName => ({
|
||||
kind: 'TestKind',
|
||||
name: 'test-component-name',
|
||||
namespace: 'test-namespace',
|
||||
});
|
||||
|
||||
const rootDir = os.platform() === 'win32' ? 'C:\\rootDir' : '/rootDir';
|
||||
|
||||
const getEntityRootDir = (entity: Entity) => {
|
||||
const {
|
||||
kind,
|
||||
@@ -163,6 +174,72 @@ describe('publishing with valid credentials', () => {
|
||||
expect(await publisher.hasDocsBeenGenerated(entity)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetchTechDocsMetadata', () => {
|
||||
it('should return tech docs metadata', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'techdocs_metadata.json':
|
||||
'{"site_name": "backstage", "site_description": "site_content"}',
|
||||
},
|
||||
});
|
||||
const expectedMetadata: TechDocsMetadata = {
|
||||
site_name: 'backstage',
|
||||
site_description: 'site_content',
|
||||
};
|
||||
expect(
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock),
|
||||
).toStrictEqual(expectedMetadata);
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should return tech docs metadata when json encoded with single quotes', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'techdocs_metadata.json': `{'site_name': 'backstage', 'site_description': 'site_content'}`,
|
||||
},
|
||||
});
|
||||
|
||||
const expectedMetadata: TechDocsMetadata = {
|
||||
site_name: 'backstage',
|
||||
site_description: 'site_content',
|
||||
};
|
||||
expect(
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock),
|
||||
).toStrictEqual(expectedMetadata);
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should return an error if the techdocs_metadata.json file is not present', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
let error;
|
||||
try {
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error).toEqual(
|
||||
new Error(
|
||||
`TechDocs metadata fetch failed, The file ${path.join(
|
||||
entityRootDir,
|
||||
'techdocs_metadata.json',
|
||||
)} does not exist !`,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('error reporting', () => {
|
||||
@@ -255,4 +332,63 @@ describe('error reporting', () => {
|
||||
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
describe('fetchTechDocsMetadata', () => {
|
||||
it('should return tech docs metadata', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'techdocs_metadata.json':
|
||||
'{"site_name": "backstage", "site_description": "site_content"}',
|
||||
},
|
||||
});
|
||||
const expectedMetadata: TechDocsMetadata = {
|
||||
site_name: 'backstage',
|
||||
site_description: 'site_content',
|
||||
};
|
||||
expect(
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock),
|
||||
).toStrictEqual(expectedMetadata);
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should return tech docs metadata when json encoded with single quotes', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
const entity = createMockEntity();
|
||||
const entityRootDir = getEntityRootDir(entity);
|
||||
|
||||
mockFs({
|
||||
[entityRootDir]: {
|
||||
'techdocs_metadata.json': `{'site_name': 'backstage', 'site_description': 'site_content'}`,
|
||||
},
|
||||
});
|
||||
|
||||
const expectedMetadata: TechDocsMetadata = {
|
||||
site_name: 'backstage',
|
||||
site_description: 'site_content',
|
||||
};
|
||||
expect(
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock),
|
||||
).toStrictEqual(expectedMetadata);
|
||||
mockFs.restore();
|
||||
});
|
||||
|
||||
it('should return an error if the techdocs_metadata.json file is not present', async () => {
|
||||
const entityNameMock = createMockEntityName();
|
||||
|
||||
let error;
|
||||
try {
|
||||
await publisher.fetchTechDocsMetadata(entityNameMock);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(
|
||||
expect.stringContaining('TechDocs metadata fetch'),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -201,10 +201,7 @@ export class AzureBlobStoragePublish implements PublisherBase {
|
||||
return;
|
||||
}
|
||||
body
|
||||
.on('error', e => {
|
||||
this.logger.error(e.message);
|
||||
reject(e.message);
|
||||
})
|
||||
.on('error', reject)
|
||||
.on('data', chunk => {
|
||||
fileStreamChunks.push(chunk);
|
||||
})
|
||||
@@ -220,16 +217,21 @@ export class AzureBlobStoragePublish implements PublisherBase {
|
||||
): Promise<TechDocsMetadata> {
|
||||
const entityRootDir = `${entityName.namespace}/${entityName.kind}/${entityName.name}`;
|
||||
try {
|
||||
return await new Promise<TechDocsMetadata>(resolve => {
|
||||
const download = this.download(
|
||||
this.containerName,
|
||||
`${entityRootDir}/techdocs_metadata.json`,
|
||||
const techdocsMetadataJson = await this.download(
|
||||
this.containerName,
|
||||
`${entityRootDir}/techdocs_metadata.json`,
|
||||
);
|
||||
if (!techdocsMetadataJson) {
|
||||
throw new Error(
|
||||
`Unable to parse the techdocs metadata file ${entityRootDir}/techdocs_metadata.json.`,
|
||||
);
|
||||
resolve(JSON5.parse(download.toString()));
|
||||
});
|
||||
}
|
||||
const techdocsMetadata = JSON5.parse(
|
||||
techdocsMetadataJson.toString('utf-8'),
|
||||
);
|
||||
return techdocsMetadata;
|
||||
} catch (e) {
|
||||
this.logger.error(e.message);
|
||||
throw e;
|
||||
throw new Error(`TechDocs metadata fetch failed, ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,44 @@
|
||||
# @backstage/plugin-api-docs
|
||||
|
||||
## 0.4.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 32a003973: Update messaging when no entities are in a table.
|
||||
- 2386de1d3: Add organization name to the API Explorer page title
|
||||
- f71589800: The api-docs plugin has been migrated to use an [external route reference](https://backstage.io/docs/plugins/composability#binding-external-routes-in-the-app) to dynamically link to the create component page. This means you need to migrate the api docs plugin to use the new extension components, as well as bind the external route.
|
||||
|
||||
To bind the external route from the api docs plugin to the scaffolder template index page, make sure you have the appropriate imports and add the following to the `createApp` call:
|
||||
|
||||
```ts
|
||||
import { apiDocsPlugin } from '@backstage/plugin-api-docs';
|
||||
import { scaffolderPlugin } from '@backstage/plugin-scaffolder';
|
||||
|
||||
const app = createApp({
|
||||
// ...
|
||||
bindRoutes({ bind }) {
|
||||
bind(apiDocsPlugin.externalRoutes, {
|
||||
createComponent: scaffolderPlugin.routes.root,
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
If you choose to not bind the routes, the button to create new APIs is not displayed.
|
||||
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- Updated dependencies [bece09057]
|
||||
- Updated dependencies [169f48deb]
|
||||
- Updated dependencies [8a1566719]
|
||||
- Updated dependencies [9d455f69a]
|
||||
- Updated dependencies [4c049a1a1]
|
||||
- Updated dependencies [02816ecd7]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/core@0.7.0
|
||||
- @backstage/plugin-catalog-react@0.1.1
|
||||
|
||||
## 0.4.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -23,6 +23,68 @@ Other formats are displayed as plain text, but this can easily be extended.
|
||||
To fill the catalog with APIs, [provide entities of kind API](https://backstage.io/docs/features/software-catalog/descriptor-format#kind-api).
|
||||
To link that a component provides or consumes an API, see the [`providesApis`](https://backstage.io/docs/features/software-catalog/descriptor-format#specprovidesapis-optional) and [`consumesApis`](https://backstage.io/docs/features/software-catalog/descriptor-format#specconsumesapis-optional) properties on the Component kind.
|
||||
|
||||
## Implementing OAuth 2 Authorization Code flow with Swagger UI
|
||||
|
||||
### Adding `oauth2-redirect.html` to support OAuth2 `redirect_uri` route
|
||||
|
||||
The Swagger UI package by expects to have a route to `/oauth2-redirect.html` which processes
|
||||
the redirect callback for the OAuth2 Authorization Code flow, however, this file is not installed
|
||||
by this plugin.
|
||||
|
||||
Grab a copy of [oauth2-redirect.html](https://github.com/swagger-api/swagger-ui/blob/master/dist/oauth2-redirect.html)
|
||||
and put it in the `app/public/` directory in order to enable Swagger UI to complete this redirection.
|
||||
|
||||
### Configuring your OAuth2 Client
|
||||
|
||||
You'll need to make sure your OAuth2 client has been registered in your OAuth2 Authentication Server (AS)
|
||||
with the appropriate `redirect_uris`, `scopes` and `grant_types`. For example, if your AS supports
|
||||
the [OAuth 2.0 Dynamic Client Registration Protocol](https://tools.ietf.org/html/rfc7591), an example
|
||||
POST request body would look like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"client_name": "Example Backstage api-docs plugin Swagger UI Client",
|
||||
"redirect_uris": [
|
||||
"https://www.getpostman.com/oauth2/callback",
|
||||
"http://localhost:3000/oauth2-redirect.html"
|
||||
"https://<yourhost>/oauth2-redirect.html"
|
||||
],
|
||||
"scope": "read_pets write_pets",
|
||||
"grant_types": [
|
||||
"authorization_code"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The above `redirect_uris` are:
|
||||
|
||||
- [Postman](https://www.postman.com/) testing: `https://www.getpostman.com/oauth2/callback`
|
||||
- Local Backstage app development: `http://localhost:3000/oauth2-redirect.html`
|
||||
- Backstage app production: `https://<yourhost>/oauth2-redirect.html`
|
||||
|
||||
### Configuring OAuth2 in your OpenAPI 3.0 schema
|
||||
|
||||
To configure [OAuth 2 Authorization Code](https://swagger.io/docs/specification/authentication/oauth2/) flow
|
||||
in your OpenAPI 3.0 schema you'll need something like this snippet:
|
||||
|
||||
```yaml
|
||||
components:
|
||||
securitySchemes:
|
||||
oauth:
|
||||
type: oauth2
|
||||
description: OAuth2 service
|
||||
flows:
|
||||
authorizationCode:
|
||||
authorizationUrl: https://api.example.com/oauth2/authorize
|
||||
tokenUrl: https://api.example.com/oauth2/token
|
||||
scopes:
|
||||
read_pets: read your pets
|
||||
write_pets: modify pets in your account
|
||||
security:
|
||||
oauth:
|
||||
- [read_pets, write_pets]
|
||||
```
|
||||
|
||||
## Links
|
||||
|
||||
- [The Backstage homepage](https://backstage.io)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-api-docs",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,9 +30,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@asyncapi/react-component": "^0.19.2",
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/core": "^0.6.3",
|
||||
"@backstage/plugin-catalog-react": "^0.1.0",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@backstage/plugin-catalog-react": "^0.1.1",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-icons/font": "^1.0.2",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
@@ -49,8 +49,8 @@
|
||||
"swagger-ui-react": "^3.37.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/dev-utils": "^0.1.12",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @backstage/plugin-auth-backend
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f43192207: remove usage of res.send() for res.json() and res.end() to ensure content types are more consistently application/json on backend responses and error cases
|
||||
- 3af994c81: Expose a configuration option for the oidc scope
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [497859088]
|
||||
- Updated dependencies [8adb48df4]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/backend-common@0.5.5
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-auth-backend",
|
||||
"version": "0.3.2",
|
||||
"version": "0.3.3",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -29,9 +29,9 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.5.4",
|
||||
"@backstage/backend-common": "^0.5.5",
|
||||
"@backstage/catalog-client": "^0.3.6",
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@types/express": "^4.17.6",
|
||||
@@ -67,7 +67,7 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@types/body-parser": "^1.19.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express-session": "^1.17.2",
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @backstage/plugin-catalog-backend
|
||||
|
||||
## 0.6.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ecdd407b1: GithubDiscoveryProcessor outputs locations as optional to avoid outputting errors for missing locations (see https://github.com/backstage/backstage/issues/4730).
|
||||
- 12d8f27a6: Add version `backstage.io/v1beta2` schema for Template entities.
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [497859088]
|
||||
- Updated dependencies [8adb48df4]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/backend-common@0.5.5
|
||||
|
||||
## 0.6.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-catalog-backend",
|
||||
"version": "0.6.3",
|
||||
"version": "0.6.4",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,8 +30,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/msal-node": "^1.0.0-beta.3",
|
||||
"@backstage/backend-common": "^0.5.4",
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/backend-common": "^0.5.5",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/config": "^0.1.3",
|
||||
"@backstage/integration": "^0.5.0",
|
||||
"@octokit/graphql": "^4.5.8",
|
||||
@@ -59,7 +59,7 @@
|
||||
"yup": "^0.29.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@types/core-js": "^2.5.4",
|
||||
"@types/git-url-parse": "^9.0.0",
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @backstage/plugin-catalog-import
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 05183f202: Bump react-hook-form version constraint to "^6.15.4"
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- Updated dependencies [bece09057]
|
||||
- Updated dependencies [169f48deb]
|
||||
- Updated dependencies [8a1566719]
|
||||
- Updated dependencies [9d455f69a]
|
||||
- Updated dependencies [4c049a1a1]
|
||||
- Updated dependencies [02816ecd7]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/core@0.7.0
|
||||
- @backstage/plugin-catalog-react@0.1.1
|
||||
|
||||
## 0.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-catalog-import",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.3",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,11 +30,11 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/catalog-client": "^0.3.6",
|
||||
"@backstage/core": "^0.6.3",
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@backstage/integration": "^0.5.0",
|
||||
"@backstage/plugin-catalog-react": "^0.1.0",
|
||||
"@backstage/plugin-catalog-react": "^0.1.1",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -51,8 +51,8 @@
|
||||
"yaml": "^1.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/dev-utils": "^0.1.12",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @backstage/plugin-catalog-react
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 9d455f69a: Introduce parameters for namespace, kind, and name to `entityRouteRef`.
|
||||
- 02816ecd7: Fixed EntityProvider setting 'loading' bool erroneously to true
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- Updated dependencies [bece09057]
|
||||
- Updated dependencies [169f48deb]
|
||||
- Updated dependencies [8a1566719]
|
||||
- Updated dependencies [4c049a1a1]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/core@0.7.0
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-catalog-react",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -29,8 +29,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-client": "^0.3.6",
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/core": "^0.6.3",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@types/react": "^16.9",
|
||||
"react": "^16.13.1",
|
||||
@@ -39,8 +39,8 @@
|
||||
"react-use": "^15.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.2",
|
||||
"@backstage/dev-utils": "^0.1.12",
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @backstage/plugin-catalog
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 32a003973: Update messaging when no entities are in a table.
|
||||
- 40c0fdbaa: Make the external `createComponent` route optional, hiding the "Create Component" button if it isn't bound.
|
||||
- 10362e9eb: Use entity relation for the owner of an entity in the catalog entity page header.
|
||||
- b33e553b2: Removed fullScreen property from UnregisterEntity Dialog modal.
|
||||
- Updated dependencies [12d8f27a6]
|
||||
- Updated dependencies [40c0fdbaa]
|
||||
- Updated dependencies [2a271d89e]
|
||||
- Updated dependencies [bece09057]
|
||||
- Updated dependencies [169f48deb]
|
||||
- Updated dependencies [8a1566719]
|
||||
- Updated dependencies [9d455f69a]
|
||||
- Updated dependencies [4c049a1a1]
|
||||
- Updated dependencies [02816ecd7]
|
||||
- @backstage/catalog-model@0.7.3
|
||||
- @backstage/core@0.7.0
|
||||
- @backstage/plugin-catalog-react@0.1.1
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user