Merge branch 'master' into xcmetrics-dashboard-mvp

This commit is contained in:
Niklas Granander
2021-07-14 10:00:12 +02:00
371 changed files with 13658 additions and 7429 deletions
+16
View File
@@ -0,0 +1,16 @@
---
'@backstage/backend-common': patch
---
Support a `ensureExists` config option to skip ensuring a configured database exists. This allows deployment scenarios where
limited permissions are given for provisioned databases without privileges to create new databases. If set to `false`, the
database connection will not be validated prior to use which means the backend will not attempt to create the database if it
doesn't exist. You can configure this in your app-config.yaml:
```yaml
backend:
database:
ensureExists: false
```
This defaults to `true` if unspecified. You can also configure this per plugin connection and will override the base option.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/integration': patch
---
Do not throw in `ScmIntegration` `byUrl` for invalid URLs
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog': patch
---
Add unstable prop for disabling unregister entity menu
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Improve UX of the Sidebar by adding SidebarScrollWrapper component allowing the user to scroll through Plugins & Shortcuts on smaller screens. Prevent the Sidebar from opening on click on small devices
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-pagerduty': patch
---
Update README
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
add default branch property for publish GitLab, Bitbucket and Azure actions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Store filter values set in `EntityListProvider` in query parameters. This allows selected filters to be restored when returning to pages that list catalog entities.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Added filesystem remove/rename built-in actions
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-import': patch
---
More helpful error message when trying to import by folder from non-github
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/core-components': patch
'@backstage/plugin-explore': patch
---
- Enhanced core `Button` component to open external links in new tab.
- Replaced the use of `Button` component from material by `core-components` in tools card.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/catalog-model': minor
---
Changed the regex to validate names following the Kubernetes validation rule, this allow to be more permissive validating the name of the object in Backstage.
-68
View File
@@ -1,68 +0,0 @@
---
'@backstage/catalog-model': minor
'@backstage/plugin-catalog-backend': minor
'@backstage/plugin-scaffolder': minor
'@backstage/plugin-scaffolder-backend': minor
'@backstage/create-app': patch
---
Support for `Template` kinds with version `backstage.io/v1alpha1` has now been removed. This means that the old method of running templates with `Preparers`, `Templaters` and `Publishers` has also been removed. If you had any logic in these abstractions, they should now be moved to `actions` instead, and you can find out more about those in the [documentation](https://backstage.io/docs/features/software-templates/writing-custom-actions)
If you need any help migrating existing templates, there's a [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1alpha1-to-v1beta2). Reach out to us on Discord in the #support channel if you're having problems.
The `scaffolder-backend` now no longer requires these `Preparers`, `Templaters`, and `Publishers` to be passed in, now all it needs is the `containerRunner`.
Please update your `packages/backend/src/plugins/scaffolder.ts` like the following
```diff
- import {
- DockerContainerRunner,
- SingleHostDiscovery,
- } from '@backstage/backend-common';
+ import { DockerContainerRunner } from '@backstage/backend-common';
import { CatalogClient } from '@backstage/catalog-client';
- import {
- CookieCutter,
- CreateReactAppTemplater,
- createRouter,
- Preparers,
- Publishers,
- Templaters,
- } from '@backstage/plugin-scaffolder-backend';
+ import { createRouter } from '@backstage/plugin-scaffolder-backend';
import Docker from 'dockerode';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
export default async function createPlugin({
config,
database,
reader,
+ discovery,
}: PluginEnvironment): Promise<Router> {
const dockerClient = new Docker();
const containerRunner = new DockerContainerRunner({ dockerClient });
- const cookiecutterTemplater = new CookieCutter({ containerRunner });
- const craTemplater = new CreateReactAppTemplater({ containerRunner });
- const templaters = new Templaters();
- templaters.register('cookiecutter', cookiecutterTemplater);
- templaters.register('cra', craTemplater);
-
- const preparers = await Preparers.fromConfig(config, { logger });
- const publishers = await Publishers.fromConfig(config, { logger });
- const discovery = SingleHostDiscovery.fromConfig(config);
const catalogClient = new CatalogClient({ discoveryApi: discovery });
return await createRouter({
- preparers,
- templaters,
- publishers,
+ containerRunner,
logger,
config,
database,
```
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/techdocs-common': patch
---
Fix openStack swift publisher encoding issue. Remove utf8 forced encoding on binary files
-10
View File
@@ -1,10 +0,0 @@
---
'@backstage/plugin-scaffolder': patch
---
Added a `context` parameter to validator functions, letting them have access to
the API holder.
If you have implemented custom validators and use `createScaffolderFieldExtension`,
your `validation` function can now optionally accept a third parameter,
`context: { apiHolder: ApiHolder }`.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-react': patch
---
Fix `EntityTypeFilter` so it produces unique case-insensitive set of available types
+10
View File
@@ -0,0 +1,10 @@
---
'@backstage/plugin-catalog-react': minor
'@backstage/plugin-scaffolder': patch
---
Updated the software templates list page (`ScaffolderPage`) to use the `useEntityListProvider` hook from #5643. This reduces the code footprint, making it easier to customize the display of this page, and consolidates duplicate approaches to querying the catalog with filters.
- The `useEntityTypeFilter` hook has been updated along with the underlying `EntityTypeFilter` to work with multiple values, to allow more flexibility for different user interfaces. It's unlikely that this change affects you; however, if you're using either of these directly, you'll need to update your usage.
- `SearchToolbar` was renamed to `EntitySearchBar` and moved to `catalog-react` to be usable by other entity list pages
- `UserListPicker` now has an `availableTypes` prop to restrict which user-related options to present
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog': patch
---
Change catalog page layout to use Grid components to improve responsiveness
-7
View File
@@ -1,7 +0,0 @@
---
'@backstage/backend-test-utils': patch
'@backstage/create-app': patch
'@backstage/plugin-catalog-backend': patch
---
bump sqlite3 to 5.0.1
-54
View File
@@ -1,54 +0,0 @@
---
'@backstage/backend-common': patch
---
Added a `readUrl` method to the `UrlReader` interface that allows for complex response objects and is intended to replace the `read` method. This new method is currently optional to implement which allows for a soft migration to `readUrl` instead of `read` in the future.
The main use case for `readUrl` returning an object instead of solely a read buffer is to allow for additional metadata such as ETag, which is a requirement for more efficient catalog processing.
The `GithubUrlReader` and `GitlabUrlReader` readers fully implement `readUrl`. The other existing readers implement the new method but do not propagate or return ETags.
While the `readUrl` method is not yet required, it will be in the future, and we already log deprecation warnings when custom `UrlReader` implementations that do not implement `readUrl` are used. We therefore recommend that any existing custom implementations are migrated to implement `readUrl`.
The old `read` and the new `readUrl` methods can easily be implemented using one another, but we recommend moving the chunk of the implementation to the new `readUrl` method as `read` is being removed, for example this:
```ts
class CustomUrlReader implements UrlReader {
read(url: string): Promise<Buffer> {
const res = await fetch(url);
if (!res.ok) {
// error handling ...
}
return Buffer.from(await res.text());
}
}
```
Can be migrated to something like this:
```ts
class CustomUrlReader implements UrlReader {
read(url: string): Promise<Buffer> {
const res = await this.readUrl(url);
return res.buffer();
}
async readUrl(
url: string,
_options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
const res = await fetch(url);
if (!res.ok) {
// error handling ...
}
const buffer = Buffer.from(await res.text());
return { buffer: async () => buffer };
}
}
```
While there is no usage of the ETag capability yet in the main Backstage packages, you can already add it to your custom implementations. To do so, refer to the documentation of the `readUrl` method and surrounding types, and the existing implementation in `packages/backend-common/src/reading/GithubUrlReader.ts`.
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/plugin-catalog-backend-module-ldap': minor
---
Add extension points to the `LdapOrgReaderProcessor` to make it possible to do more advanced modifications
of the ingested users and groups.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Show scroll bar of the sidebar wrapper only on hover
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Updating fs-extra to 10.0.0 to handle broken symbolic links correctly
+9
View File
@@ -0,0 +1,9 @@
---
'@backstage/plugin-catalog-backend': patch
---
The codeowners processor extracts the username of the primary owner and uses this as the owner field.
Given the kind isn't specified this is assumed to be a group and so the link to the owner in the about card
doesn't work. This change specifies the kind where the entity is a user. e.g:
`@iain-b` -> `user:iain-b`
-24
View File
@@ -1,24 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Adding `config: Config` as a required argument to `createBuiltinActions` and downstream methods in order to support configuration of the default git author used for Scaffolder commits.
The affected methods are:
- `createBuiltinActions`
- `createPublishGithubAction`
- `createPublishGitlabAction`
- `createPublishBitbucketAction`
- `createPublishAzureAction`
Call sites to these methods will need to be migrated to include the new `config` argument. See `createRouter` in `plugins/scaffolder-backend/src/service/router.ts` for an example of adding this new argument.
To configure the default git author, use the `defaultAuthor` key under `scaffolder` in `app-config.yaml`:
```yaml
scaffolder:
defaultAuthor:
name: Example
email: example@example.com
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-user-settings': minor
---
Exported and renamed components from the `@backstage/plugin-user-settings` plugin , to be able to use it in the consumer side and customize the `SettingPage`
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend-module-rails': patch
---
updated paths to consider differences between platform (windows corrected)
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Add new `fetch:template` action which handles the same responsibilities as `fetch:cookiecutter` without the external dependency on `cookiecutter`. For information on migrating from `fetch:cookiecutter` to `fetch:template`, see the [migration guide](https://backstage.io/docs/features/software-templates/builtin-actions#migrating-from-fetch-cookiecutter-to-fetch-template) in the docs.
+12
View File
@@ -0,0 +1,12 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Scaffolder: Added an 'eq' handlebars helper for use in software template YAML files. This can be used to execute a step depending on the value of an input, e.g.:
```yaml
steps:
id: 'conditional-step'
action: 'custom-action'
if: '{{ eq parameters.myvalue "custom" }}',
```
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': patch
---
Add Sign In and Handler resolver for Microsoft provider
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder': patch
---
add support for uiSchema on dependent form fields
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-ilert': patch
---
chore: bump `@date-io/luxon` from 1.3.13 to 2.10.11
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-catalog-backend': patch
---
Make use of the new `readUrl` method on `UrlReader` from `@backstage/backend-common`.
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/plugin-search-backend-node': minor
---
Change return value of `SearchEngine.index` to `Promise<void>` to support
implementation of external search engines.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/integration': patch
---
Fix downloads from repositories located at bitbucket.org
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Handle empty code blocks in markdown files so they don't fail rendering
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend-module-ldap': patch
---
Expose missing types used by the custom transformers
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/create-app': patch
---
Use SidebarScrollWrapper to improve responsiveness of the current sidebar. Change: Wrap a section of SidebarItems with this component to enable scroll for smaller screens. It can also be used in sidebar plugins (see shortcuts plugin for an example).
+7
View File
@@ -0,0 +1,7 @@
---
'@backstage/plugin-scaffolder-backend': minor
---
Updated inputs for the `publish:github:pull-request` action.
Now requires a `repoUrl` instead of separate `owner` and `repo` inputs. This aligns with the output of the `RepoUrlPicker` ui field used by the pull-request sample template.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Fix error in error panel, and console warnings about DOM nesting pre inside p
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/core-components': patch
'@backstage/plugin-org': patch
---
Add edit button to Group Profile Card
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
bump azure-devops-node to 10.2.2
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder': patch
---
Pass through the `idToken` in `Authorization` Header for `listActions` request
-8
View File
@@ -1,8 +0,0 @@
---
'@backstage/plugin-search-backend-node': patch
---
Change search scheduler from starting indexing in a fixed interval (for example
every 60 seconds), to wait a fixed time between index runs.
This makes sure that no second index process for the same document type is
started when the previous one is still running.
@@ -0,0 +1,7 @@
---
'@backstage/plugin-techdocs-backend': patch
---
It is no longer required to provide a generator and a preparer to the TechDocs
router factory when running TechDocs in the "recommended" (e.g. externally
prepared and generated docs) configuration.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
Export the `fetchContents` from scaffolder-backend
-6
View File
@@ -1,6 +0,0 @@
---
'@backstage/backend-common': patch
'@backstage/plugin-scaffolder-backend': patch
---
add defaultBranch property for publish GitHub action
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/plugin-scaffolder-backend': patch
---
removing mandatory of protection for the default branch, that could be handled by the GitHub automation in async manner, thus throwing floating errors
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Document the default behavior of `statusCheck` option in `createStatusCheckRouter`.
-5
View File
@@ -1,5 +0,0 @@
---
'@backstage/core-components': patch
---
Add custom styles to scroll bar of the sidebar wrapper to fix flaky behaviour
+16
View File
@@ -0,0 +1,16 @@
---
'@backstage/backend-common': patch
'@backstage/cli': patch
'@backstage/config-loader': patch
'@backstage/create-app': patch
'@backstage/techdocs-common': patch
'@backstage/plugin-app-backend': patch
'@backstage/plugin-auth-backend': patch
'@backstage/plugin-catalog-backend': patch
'@backstage/plugin-kubernetes-backend': patch
'@backstage/plugin-rollbar-backend': patch
'@backstage/plugin-scaffolder-backend': patch
'@backstage/plugin-techdocs-backend': patch
---
Revert the upgrade to `fs-extra@10.0.0` as that seemed to have broken all installs inexplicably.
+2
View File
@@ -169,6 +169,7 @@ nohoist
nonces
noop
npm
nunjucks
nvarchar
nvm
OAuth
@@ -274,6 +275,7 @@ touchpoints
transpilation
transpiled
truthy
typeahead
ui
unbreak
unmanaged
+1 -1
View File
@@ -60,6 +60,6 @@ Check out [the documentation](https://backstage.io/docs/getting-started) on how
## License
Copyright 2020-2021 © Backstage Project Authors. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: https://www.linuxfoundation.org/trademark-usage
Copyright 2020-2021 © The Backstage Authors. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: https://www.linuxfoundation.org/trademark-usage
Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
+5 -7
View File
@@ -142,7 +142,6 @@ export default async function createPlugin({
const indexBuilder = new IndexBuilder({ logger, searchEngine });
indexBuilder.addCollator({
type: 'software-catalog',
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({ discovery }),
});
@@ -262,21 +261,21 @@ const indexBuilder = new IndexBuilder({ logger, searchEngine });
```
Backstage Search can be used to power search of anything! Plugins like the
Catalog offer default [collators](./concepts.md#collators) which are responsible
for providing documents [to be indexed](./concepts.md#documents-and-indices).
You can register any number of collators with the `IndexBuilder` like this:
Catalog offer default [collators](./concepts.md#collators) (e.g.
[DefaultCatalogCollator](https://github.com/backstage/backstage/blob/df12cc25aa4934a98bc42ed03c07f64a1a0a9d72/plugins/catalog-backend/src/search/DefaultCatalogCollator.ts))
which are responsible for providing documents
[to be indexed](./concepts.md#documents-and-indices). You can register any
number of collators with the `IndexBuilder` like this:
```typescript
const indexBuilder = new IndexBuilder({ logger, searchEngine });
indexBuilder.addCollator({
type: 'software-catalog',
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({ discovery }),
});
indexBuilder.addCollator({
type: 'my-custom-stuff',
defaultRefreshIntervalSeconds: 3600,
collator: new MyCustomCollator(),
});
@@ -290,7 +289,6 @@ its `defaultRefreshIntervalSeconds` value, like this:
```typescript {3}
indexBuilder.addCollator({
type: 'software-catalog',
defaultRefreshIntervalSeconds: 600,
collator: new DefaultCatalogCollator({ discovery }),
});
@@ -654,7 +654,7 @@ spec:
steps:
- id: fetch-base
name: Fetch Base
action: fetch:cookiecutter
action: fetch:template
input:
url: ./template
values:
@@ -51,7 +51,7 @@ spec:
steps:
- id: fetch-base
name: Fetch Base
action: fetch:cookiecutter
action: fetch:template
input:
url: ./template
values:
@@ -14,3 +14,54 @@ Azure, GitLab and Bitbucket.
A list of all registered actions can be found under `/create/actions`. For local
development you should be able to reach them at
`http://localhost:3000/create/actions`.
### Migrating from `fetch:cookiecutter` to `fetch:template`
The `fetch:template` action is a new action with a similar API to
`fetch:cookiecutter` but no dependency on `cookiecutter`. There are two options
for migrating templates that use `fetch:cookiecutter` to use `fetch:template`:
#### Using `cookiecutterCompat` mode
The new `fetch:template` action has a `cookiecutterCompat` flag which should
allow most templates built for `fetch:cookiecutter` to work without any changes.
1. Update action name in `template.yaml`. The name should be changed from
`fetch:cookiecutter` to `fetch:template`.
2. Set `cookiecutterCompat` to `true` in the `fetch:template` step input in
`template.yaml`.
```diff
steps:
- id: fetch-base
name: Fetch Base
- action: fetch:cookiecutter
+ action: fetch:template
input:
url: ./skeleton
+ cookiecutterCompat: true
values:
```
#### Manual migration
If you prefer, you can manually migrate your templates to avoid the need for
enabling cookiecutter compatibility mode, which will result in slightly less
verbose template variables expressions.
1. Update action name in `template.yaml`. The name should be changed from
`fetch:cookiecutter` to `fetch:template`.
2. Update variable syntax in file names and content. `fetch:cookiecutter`
expects variables to be enclosed in `{{` `}}` and prefixed with
`cookiecutter.`, while `fetch:template` expects variables to be enclosed in
`${{` `}}` and prefixed with `values.`. For example, a reference to variable
`myInputVariable` would need to be migrated from
`{{ cookiecutter.myInputVariable }}` to `${{ values.myInputVariable }}`.
3. Replace uses of `jsonify` with `dump`. The
[`jsonify` filter](https://cookiecutter.readthedocs.io/en/latest/advanced/template_extensions.html#jsonify-extension)
is built in to `cookiecutter`, and is not available by default when using
`fetch:template`. The
[`dump` filter](https://mozilla.github.io/nunjucks/templating.html#dump) is
the equivalent filter in nunjucks, so an expression like
`{{ cookiecutter.myAwesomeList | jsonify }}` should be migrated to
`${{ values.myAwesomeList | dump }}`.
@@ -101,9 +101,7 @@ should have something similar to the below in
```ts
return await createRouter({
preparers,
templaters,
publishers,
containerRunner,
logger,
config,
database,
@@ -118,9 +116,7 @@ will set the available actions that the scaffolder has access to.
```ts
const actions = [createNewFileAction()];
return await createRouter({
preparers,
templaters,
publishers,
containerRunner,
logger,
config,
database,
@@ -137,18 +133,17 @@ want to have those as well as your new one, you'll need to do the following:
import { createBuiltinActions } from '@backstage/plugin-scaffolder-backend';
const builtInActions = createBuiltinActions({
containerRunner,
integrations,
config,
catalogClient,
templaters,
reader,
});
const actions = [...builtInActions, createNewFileAction()];
return await createRouter({
preparers,
templaters,
publishers,
containerRunner,
logger,
config,
database,
@@ -62,7 +62,7 @@ spec:
steps:
- id: fetch-base
name: Fetch Base
action: fetch:cookiecutter
action: fetch:template
input:
url: ./template
values:
@@ -289,8 +289,8 @@ template. These follow the same standard format:
- id: fetch-base # A unique id for the step
name: Fetch Base # A title displayed in the frontend
if: '{{ parameters.name }}' # Optional condition, skip the step if not truthy
action: fetch:cookiecutter # an action to call
input: # input that is passed as arguments to the action handler
action: fetch:template # An action to call
input: # Input that is passed as arguments to the action handler
url: ./template
values:
name: '{{ parameters.name }}'
@@ -317,20 +317,20 @@ output:
### The templating syntax
You might have noticed in the examples that there are `{{ }}`, and these are a
`handlebars` templates for linking and glueing all these different parts of
`yaml` together. All the form inputs from the `parameters` section, when passed
to the steps will be available by using the template syntax
`{{ parameters.something }}`. This is great for passing the values from the form
into different steps and reusing these input variables. To pass arrays or
objects use the syntax `{{ json paramaters.something }}` where
`paramaters.something` is of type `object` or `array` in the `jsonSchema`, such
as the `nicknames` parameter in the previous example.
You might have noticed variables wrapped in `{{ }}` in the examples. These are
`handlebars` template strings for linking and gluing the different parts of the
template together. All the form inputs from the `parameters` section will be
available by using this template syntax (for example,
`{{ parameters.firstName }}` inserts the value of `firstName` from the
parameters). This is great for passing the values from the form into different
steps and reusing these input variables. To pass arrays or objects use the
`json` custom [helper](https://handlebarsjs.com/guide/expressions.html#helpers).
For example, `{{ json parameters.nicknames }}` will insert the result of calling
`JSON.stringify` on the value of the `nicknames` parameter.
As you can see above in the `Outputs` section, `actions` and `steps` can also
output things. So you can grab that output by using
`steps.$stepId.output.$property`.
output things. You can grab that output using `steps.$stepId.output.$property`.
You can read more about all the `inputs` and `outputs` defined in the actions in
code part of the `JSONSchema` or you can read more about our built in ones
code part of the `JSONSchema`, or you can read more about our built in ones
[here](./builtin-actions.md).
+1 -2
View File
@@ -332,8 +332,7 @@ Stability: `1`
The backend scaffolder plugin that provides an implementation for templates in
the catalog.
Stability: `1`. There is planned work to rework the scaffolder in
https://github.com/backstage/backstage/issues/2771.
Stability: `2`.
### `tech-radar` [GitHub](https://github.com/backstage/backstage/tree/master/plugins/tech-radar/)
@@ -132,4 +132,4 @@ Integrating infrastructure of this size and complexity can seem overwhelming. It
## More questions about adopting Backstage?
[Contact the Backstage team at Spotify.](https://calendly.com/spotify-backstage) Well share more about what weve learned from our experience here at Spotify — and from other companies who are already using Backstage to transform their developer experience.
[Contact the Backstage team at Spotify.](https://backstage.spotify.com/) Well share more about what weve learned from our experience here at Spotify — and from other companies who are already using Backstage to transform their developer experience.
+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 250 250"><defs><style>.cls-1{fill:none;stroke:#7df3e1;stroke-linejoin:round;stroke-width:1.25px}</style></defs><polyline points="79.08 24.38 79.08 218.83 79.08 245.06" class="cls-1"/><polyline points="63.67 235.75 63.67 209.52 63.67 24.38" class="cls-1"/><path d="M189.83,220h0l0,0Z" class="cls-1"/><path d="M145.5,88.07c-16.61-12.31-5.42-21.25-22-33.56s-27.8-3.37-44.4-15.68v116.3c16.6,12.31,27.79,3.37,44.4,15.68s5.41,21.25,22,33.56,27.76,3.38,44.33,15.63l0-116.27C173.28,91.43,162.09,100.37,145.5,88.07Zm-7.78,66.36v0a23.17,23.17,0,0,1-16.43-6.81l-7,7,7-7a23.16,23.16,0,0,1-6.8-16.43h0a23.18,23.18,0,0,1,6.8-16.43l-7-7,7,7a23.2,23.2,0,0,1,16.43-6.8v0a23.16,23.16,0,0,1,16.43,6.8l7-7-7,7A23.15,23.15,0,0,1,161,131.19h0a23.13,23.13,0,0,1-6.81,16.43l7,7-7-7A23.13,23.13,0,0,1,137.72,154.43Z" class="cls-1"/><path d="M137.72,124.67V108a23.2,23.2,0,0,0-16.43,6.8l11.82,11.82A6.5,6.5,0,0,1,137.72,124.67Z" class="cls-1"/><path d="M144.24,131.19H161a23.15,23.15,0,0,0-6.81-16.43l-11.82,11.82A6.5,6.5,0,0,1,144.24,131.19Z" class="cls-1"/><path d="M133.11,126.58l-11.82-11.82a23.18,23.18,0,0,0-6.8,16.43H131.2A6.5,6.5,0,0,1,133.11,126.58Z" class="cls-1"/><path d="M142.33,126.58l11.82-11.82a23.16,23.16,0,0,0-16.43-6.8v16.71A6.5,6.5,0,0,1,142.33,126.58Z" class="cls-1"/><path d="M131.2,131.19H114.49a23.16,23.16,0,0,0,6.8,16.43l11.82-11.82A6.5,6.5,0,0,1,131.2,131.19Z" class="cls-1"/><path d="M137.72,137.71v16.72a23.13,23.13,0,0,0,16.43-6.81L142.33,135.8A6.5,6.5,0,0,1,137.72,137.71Z" class="cls-1"/><path d="M161,131.19H144.24a6.5,6.5,0,0,1-1.91,4.61l11.82,11.82A23.13,23.13,0,0,0,161,131.19Z" class="cls-1"/><path d="M133.11,135.8l-11.82,11.82a23.17,23.17,0,0,0,16.43,6.81V137.71A6.5,6.5,0,0,1,133.11,135.8Z" class="cls-1"/><path d="M82.63,16.19a11.26,11.26,0,1,0-19,8.19h0a11.23,11.23,0,0,0,15.41,0h0A11.21,11.21,0,0,0,82.63,16.19Z" class="cls-1"/></svg>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250"><defs><style>.cls-1{fill:none;stroke:#7df3e1;stroke-linejoin:round;stroke-width:2.5px;}</style></defs><polyline class="cls-1" points="79.08 24.38 79.08 218.83 79.08 245.06"/><polyline class="cls-1" points="63.67 235.75 63.67 209.52 63.67 24.38"/><path class="cls-1" d="M189.83,220h0l0,0Z"/><path class="cls-1" d="M145.5,88.07c-16.61-12.31-5.42-21.25-22-33.56s-27.8-3.37-44.4-15.68v116.3c16.6,12.31,27.79,3.37,44.4,15.68s5.41,21.25,22,33.56,27.76,3.38,44.33,15.63l0-116.27C173.28,91.43,162.09,100.37,145.5,88.07Z"/><path class="cls-1" d="M137.72,124.67V108a23.2,23.2,0,0,0-16.43,6.8l11.82,11.82A6.5,6.5,0,0,1,137.72,124.67Z"/><path class="cls-1" d="M144.24,131.19H161a23.15,23.15,0,0,0-6.81-16.43l-11.82,11.82A6.5,6.5,0,0,1,144.24,131.19Z"/><path class="cls-1" d="M133.11,126.58l-11.82-11.82a23.18,23.18,0,0,0-6.8,16.43H131.2A6.5,6.5,0,0,1,133.11,126.58Z"/><path class="cls-1" d="M142.33,126.58l11.82-11.82a23.16,23.16,0,0,0-16.43-6.8v16.71A6.5,6.5,0,0,1,142.33,126.58Z"/><path class="cls-1" d="M131.2,131.19H114.49a23.16,23.16,0,0,0,6.8,16.43l11.82-11.82A6.5,6.5,0,0,1,131.2,131.19Z"/><path class="cls-1" d="M137.72,137.71v16.72a23.13,23.13,0,0,0,16.43-6.81L142.33,135.8A6.5,6.5,0,0,1,137.72,137.71Z"/><path class="cls-1" d="M161,131.19H144.24a6.5,6.5,0,0,1-1.91,4.61l11.82,11.82A23.13,23.13,0,0,0,161,131.19Z"/><path class="cls-1" d="M133.11,135.8l-11.82,11.82a23.17,23.17,0,0,0,16.43,6.81V137.71A6.5,6.5,0,0,1,133.11,135.8Z"/><path class="cls-1" d="M82.63,16.19a11.26,11.26,0,1,0-19,8.19h0a11.23,11.23,0,0,0,15.41,0h0A11.21,11.21,0,0,0,82.63,16.19Z"/><line class="cls-1" x1="154.15" y1="147.62" x2="161.15" y2="154.62"/><line class="cls-1" x1="160.96" y1="131.19" x2="170.85" y2="131.19"/><line class="cls-1" x1="154.15" y1="114.76" x2="161.15" y2="107.77"/><line class="cls-1" x1="137.72" y1="107.96" x2="137.72" y2="98.06"/><line class="cls-1" x1="121.29" y1="114.76" x2="114.3" y2="107.77"/><line class="cls-1" x1="114.49" y1="131.19" x2="104.6" y2="131.19"/><line class="cls-1" x1="121.29" y1="147.62" x2="114.3" y2="154.62"/><line class="cls-1" x1="137.72" y1="154.43" x2="137.72" y2="164.32"/></svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 250 250"><defs><style>.cls-1,.cls-2,.cls-3{fill:none;stroke:#7df3e1}.cls-1{stroke-linecap:round}.cls-1,.cls-3{stroke-linejoin:round;stroke-width:1.25px}.cls-2{stroke-miterlimit:10}</style></defs><path d="M22.08,87.32c-1.64-3.26-2-6.12-1-8.45C24.64,70.6,45,70.7,73.39,77.6" class="cls-1"/><circle cx="31.13" cy="100.9" r="15.94" class="cls-2"/><path d="M88,136.33c-17.15-8.82-32-17.87-43.33-26.3" class="cls-1"/><path d="M198.45,131.52c25,16.22,39.43,31.24,35.81,39.61-4.72,10.91-38.57,7.26-81.64-7.33" class="cls-1"/><path d="M91.39,129.7C49,85.89,23.62,45.42,33.42,35.14c6.72-7,28.38,1.71,56.08,20.9" class="cls-1"/><path d="M193,153c23.35,29.29,36,54.36,28.87,61.87-8.5,8.92-40.94-7.48-79.25-38.28" class="cls-1"/><path d="M128.76,182.48c20.74,32.14,40.49,51.49,50,46.81" class="cls-3"/><path d="M76.52,20.71C64.08,26.81,73.27,71.5,96.9,123.56" class="cls-3"/><circle cx="111.23" cy="46.18" r="23.7" class="cls-2"/><path d="M133.76,53.58a71,71,0,1,1-39.92,8.47" class="cls-3"/><path d="M128.76,182.48c20.74,32.14,40.49,51.49,50,46.81,8.24-4,7-25-1.67-53.87" class="cls-3"/><path d="M95.51,28.62c-7.92-7.07-14.56-10.08-19-7.91C64.08,26.81,73.27,71.5,96.9,123.56" class="cls-3"/><circle cx="120.99" cy="148.62" r="34.89" class="cls-2"/></svg>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250"><defs><style>.cls-1,.cls-2,.cls-3{fill:none;stroke:#7df3e1;stroke-width:2.5px;}.cls-1{stroke-linecap:round;}.cls-1,.cls-3{stroke-linejoin:round;}.cls-2{stroke-miterlimit:10;}</style></defs><path class="cls-1" d="M22.08,87.32c-1.64-3.26-2-6.12-1-8.45C24.64,70.6,45,70.7,73.39,77.6"/><circle class="cls-2" cx="31.13" cy="100.9" r="15.94"/><path class="cls-1" d="M88,136.33c-17.15-8.82-32-17.87-43.33-26.3"/><path class="cls-1" d="M198.45,131.52c25,16.22,39.43,31.24,35.81,39.61-4.72,10.91-38.57,7.26-81.64-7.33"/><path class="cls-1" d="M91.39,129.7C49,85.89,23.62,45.42,33.42,35.14c6.72-7,28.38,1.71,56.08,20.9"/><path class="cls-1" d="M193,153c23.35,29.29,36,54.36,28.87,61.87-8.5,8.92-40.94-7.48-79.25-38.28"/><path class="cls-3" d="M128.76,182.48c20.74,32.14,40.49,51.49,50,46.81"/><path class="cls-3" d="M76.52,20.71C64.08,26.81,73.27,71.5,96.9,123.56"/><circle class="cls-2" cx="111.23" cy="46.18" r="23.7"/><path class="cls-3" d="M133.76,53.58a71,71,0,1,1-39.92,8.47"/><path class="cls-3" d="M128.76,182.48c20.74,32.14,40.49,51.49,50,46.81,8.24-4,7-25-1.67-53.87"/><path class="cls-3" d="M95.51,28.62c-7.92-7.07-14.56-10.08-19-7.91C64.08,26.81,73.27,71.5,96.9,123.56"/><circle class="cls-2" cx="120.99" cy="148.62" r="34.89"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 250 250"><defs><style>.cls-1{fill:none;stroke:#7df3e1;stroke-linejoin:round;stroke-width:1.25px}</style></defs><path d="M157.82,203.89a5.28,5.28,0,0,1-.67,3.09c-3.75,6.21-21.45,2.39-39.54-8.53C101.87,189,91,177.23,90.93,170.25c-7.27-.67-12.6.66-14.77,4.26-5.58,9.25,11.76,29.94,38.74,46.21s53.36,22,58.94,12.72C177.61,227.18,170.9,215.7,157.82,203.89Z" class="cls-1"/><path d="M157.82,203.89c-.3-5.42-6.78-13.52-16.86-21.24,0,0,0,.09-.05.13C139,185.93,130,184,120.77,178.43c-6.92-4.17-12-9.2-13.27-12.78-7.89-2-13.88-1.51-15.88,1.81a5.24,5.24,0,0,0-.69,2.79" class="cls-1"/><path d="M90.93,170.25c.09,7,10.94,18.71,26.68,28.2,18.09,10.92,35.79,14.74,39.54,8.53a5.28,5.28,0,0,0,.67-3.09" class="cls-1"/><path d="M141,182.65c1.69-3.22-4.19-10.17-13.28-15.66s-18.23-7.5-20.14-4.34a3.49,3.49,0,0,0,0,3" class="cls-1"/><path d="M107.5,165.65c1.29,3.58,6.35,8.61,13.27,12.78,9.22,5.56,18.23,7.5,20.14,4.35,0,0,0-.09.05-.13" class="cls-1"/><path d="M117.79,126a6.09,6.09,0,0,0,0,2.58l6.36,27,7.2-21.89a9.86,9.86,0,0,0,.45-4.26" class="cls-1"/><path d="M154.88,109V75.86a82.39,82.39,0,0,0-28-61.9l-2.08-1.83A45.42,45.42,0,0,0,94.7,54.89V94h0c-.64,9.87,5.75,21.3,17.08,28.72a44.56,44.56,0,0,0,6,3.28,6.16,6.16,0,0,1,9.26-4.09h0a10.13,10.13,0,0,1,4.8,7.57c8.51.37,16.05-2.61,20.12-8.83a18.2,18.2,0,0,0,2.88-8.6h0v-.38A20,20,0,0,0,154.88,109Z" class="cls-1"/><path d="M131.85,129.49a10.13,10.13,0,0,0-4.8-7.57h0a6.16,6.16,0,0,0-9.26,4.09" class="cls-1"/><path d="M173.76,96.66V86.55h0c.19-3.07-1.79-6.62-5.32-8.93-4.67-3.06-10.27-2.77-12.5.64a5.58,5.58,0,0,0-.89,2.68h0V81a5.89,5.89,0,0,0,0,.84v3.26h0v21.36h0v10.11h0c-.2,3.08,1.79,6.63,5.31,8.94,4.67,3.06,10.27,2.77,12.5-.64a5.71,5.71,0,0,0,.9-2.68h0v-.12c0-.27,0-.55,0-.83V118h0V96.66Z" class="cls-1"/><path d="M94.66,59.93a5.75,5.75,0,0,0,0-.83V59h0a5.63,5.63,0,0,0-.9-2.67c-2.23-3.41-7.83-3.7-12.5-.65-3.52,2.31-5.51,5.87-5.31,8.94h0v1.19s0,.07,0,.1V93.64s0,.07,0,.1v1.19h0c-.2,3.08,1.79,6.63,5.31,8.94,4.67,3.06,10.27,2.77,12.5-.64a5.71,5.71,0,0,0,.9-2.68h0v-.12a5.75,5.75,0,0,0,0-.83V95.9h0V59.94Z" class="cls-1"/><ellipse cx="122.77" cy="62.49" class="cls-1" rx="10.06" ry="11.36"/></svg>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250"><defs><style>.cls-1{fill:none;stroke:#7df3e1;stroke-linejoin:round;stroke-width:2.5px;}</style></defs><path class="cls-1" d="M157.82,203.89a5.28,5.28,0,0,1-.67,3.09c-3.75,6.21-21.45,2.39-39.54-8.53C101.87,189,91,177.23,90.93,170.25c-7.27-.67-12.6.66-14.77,4.26-5.58,9.25,11.76,29.94,38.74,46.21s53.36,22,58.94,12.72C177.61,227.18,170.9,215.7,157.82,203.89Z"/><path class="cls-1" d="M157.82,203.89c-.3-5.42-6.78-13.52-16.86-21.24,0,0,0,.09-.05.13C139,185.93,130,184,120.77,178.43c-6.92-4.17-12-9.2-13.27-12.78-7.89-2-13.88-1.51-15.88,1.81a5.24,5.24,0,0,0-.69,2.79"/><path class="cls-1" d="M90.93,170.25c.09,7,10.94,18.71,26.68,28.2,18.09,10.92,35.79,14.74,39.54,8.53a5.28,5.28,0,0,0,.67-3.09"/><path class="cls-1" d="M141,182.65c1.69-3.22-4.19-10.17-13.28-15.66s-18.23-7.5-20.14-4.34a3.49,3.49,0,0,0,0,3"/><path class="cls-1" d="M107.5,165.65c1.29,3.58,6.35,8.61,13.27,12.78,9.22,5.56,18.23,7.5,20.14,4.35,0,0,0-.09.05-.13"/><path class="cls-1" d="M117.79,126a6.09,6.09,0,0,0,0,2.58l6.36,27,7.2-21.89a9.86,9.86,0,0,0,.45-4.26"/><path class="cls-1" d="M154.88,109V75.86a82.39,82.39,0,0,0-28-61.9l-2.08-1.83A45.42,45.42,0,0,0,94.7,54.89V94h0c-.64,9.87,5.75,21.3,17.08,28.72a44.56,44.56,0,0,0,6,3.28,6.16,6.16,0,0,1,9.26-4.09h0a10.13,10.13,0,0,1,4.8,7.57c8.51.37,16.05-2.61,20.12-8.83a18.2,18.2,0,0,0,2.88-8.6h0v-.38A20,20,0,0,0,154.88,109Z"/><path class="cls-1" d="M131.85,129.49a10.13,10.13,0,0,0-4.8-7.57h0a6.16,6.16,0,0,0-9.26,4.09"/><path class="cls-1" d="M173.76,96.66V86.55h0c.19-3.07-1.79-6.62-5.32-8.93-4.67-3.06-10.27-2.77-12.5.64a5.58,5.58,0,0,0-.89,2.68h0V81a5.89,5.89,0,0,0,0,.84v3.26h0v21.36h0v10.11h0c-.2,3.08,1.79,6.63,5.31,8.94,4.67,3.06,10.27,2.77,12.5-.64a5.71,5.71,0,0,0,.9-2.68h0v-.12c0-.27,0-.55,0-.83V118h0V96.66Z"/><path class="cls-1" d="M94.66,59.93a5.75,5.75,0,0,0,0-.83V59h0a5.63,5.63,0,0,0-.9-2.67c-2.23-3.41-7.83-3.7-12.5-.65-3.52,2.31-5.51,5.87-5.31,8.94h0v1.19s0,.07,0,.1V93.64s0,.07,0,.1v1.19h0c-.2,3.08,1.79,6.63,5.31,8.94,4.67,3.06,10.27,2.77,12.5-.64a5.71,5.71,0,0,0,.9-2.68h0v-.12a5.75,5.75,0,0,0,0-.83V95.9h0V59.94Z"/><ellipse class="cls-1" cx="122.77" cy="62.49" rx="10.06" ry="11.36"/></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 250 250"><defs><style>.cls-1{fill:none;stroke:#7df3e1;stroke-linejoin:round;stroke-width:1.25px}</style></defs><polygon points="210.2 178.75 210.2 96.75 186.09 44.02 136.67 12.26 136.67 134.08 210.2 178.75" class="cls-1"/><polygon points="113.33 237.75 113.33 118.51 39.8 71.25 39.8 193.07 113.33 237.75" class="cls-1"/><polyline points="69.73 136.22 58.56 147.39 68.59 167.84" class="cls-1"/><polyline points="82.96 176.15 93.08 166.03 82.67 143.81" class="cls-1"/><line x1="159.63" x2="122.15" y1="127.73" y2="165.96" class="cls-1"/><polyline points="136.74 165.96 122.15 165.96 122.15 151.37" class="cls-1"/><line x1="122.15" x2="159.51" y1="115.07" y2="77.07" class="cls-1"/><polyline points="144.92 77.07 159.51 77.07 159.51 91.66" class="cls-1"/><polygon points="186.03 81.26 210.13 96.75 186.03 44.1 186.03 81.26" class="cls-1"/></svg>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250"><defs><style>.cls-1{fill:none;stroke:#7df3e1;stroke-linejoin:round;stroke-width:2.5px;}</style></defs><polygon class="cls-1" points="210.2 178.75 210.2 96.75 186.09 44.02 136.67 12.26 136.67 134.08 210.2 178.75"/><polygon class="cls-1" points="113.33 237.75 113.33 118.51 39.8 71.25 39.8 193.07 113.33 237.75"/><polyline class="cls-1" points="69.73 136.22 58.56 147.39 68.59 167.84"/><polyline class="cls-1" points="82.96 176.15 93.08 166.03 82.67 143.81"/><line class="cls-1" x1="159.63" y1="127.73" x2="122.15" y2="165.96"/><polyline class="cls-1" points="136.74 165.96 122.15 165.96 122.15 151.37"/><line class="cls-1" x1="122.15" y1="115.07" x2="159.51" y2="77.07"/><polyline class="cls-1" points="144.92 77.07 159.51 77.07 159.51 91.66"/><polygon class="cls-1" points="186.03 81.26 210.13 96.75 186.03 44.1 186.03 81.26"/></svg>

Before

Width:  |  Height:  |  Size: 928 B

After

Width:  |  Height:  |  Size: 953 B

+5 -6
View File
@@ -9,7 +9,7 @@
"start": "yarn workspace example-app start",
"start-backend": "yarn workspace example-backend start",
"build": "lerna run build",
"build:api-reports": "tsc && yarn build:api-reports:only",
"build:api-reports": "yarn tsc:full && yarn build:api-reports:only",
"build:api-reports:only": "ts-node -T -P scripts/tsconfig.json scripts/api-extractor.ts",
"build:api-docs": "yarn build:api-reports --docs",
"tsc": "tsc",
@@ -44,15 +44,14 @@
"**/@roadiehq/**/@backstage/core": "*",
"**/@roadiehq/**/@backstage/plugin-catalog": "*",
"**/@roadiehq/**/@backstage/catalog-model": "*",
"**/@microsoft/api-extractor/typescript": "^4.0.3",
"graphql-language-service-interface": "2.8.2",
"graphql-language-service-parser": "1.9.0"
},
"version": "1.0.0",
"dependencies": {
"@microsoft/api-documenter": "^7.12.16",
"@microsoft/api-extractor": "7.13.2-pr1916.0",
"@microsoft/api-extractor-model": "^7.12.5"
"@microsoft/api-documenter": "^7.13.30",
"@microsoft/api-extractor": "^7.18.1",
"@microsoft/api-extractor-model": "^7.13.3"
},
"devDependencies": {
"@changesets/cli": "^2.14.0",
@@ -61,7 +60,7 @@
"command-exists": "^1.2.9",
"concurrently": "^6.0.0",
"eslint-plugin-notice": "^0.9.10",
"fs-extra": "^10.0.0",
"fs-extra": "9.1.0",
"husky": "^6.0.0",
"lerna": "^4.0.0",
"lint-staged": "^10.1.0",
+30
View File
@@ -1,5 +1,35 @@
# example-app
## 0.2.36
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.1.5
- @backstage/plugin-pagerduty@0.3.7
- @backstage/plugin-catalog-import@0.5.12
- @backstage/plugin-explore@0.3.9
- @backstage/catalog-model@0.9.0
- @backstage/plugin-scaffolder@0.10.0
- @backstage/plugin-catalog@0.6.6
- @backstage/plugin-org@0.3.16
- @backstage/plugin-techdocs@0.9.9
- @backstage/plugin-api-docs@0.6.1
- @backstage/plugin-badges@0.2.4
- @backstage/plugin-catalog-react@0.2.6
- @backstage/plugin-circleci@0.2.18
- @backstage/plugin-cloudbuild@0.2.18
- @backstage/plugin-code-coverage@0.1.6
- @backstage/plugin-github-actions@0.4.12
- @backstage/plugin-jenkins@0.4.7
- @backstage/plugin-kafka@0.2.10
- @backstage/plugin-kubernetes@0.4.7
- @backstage/plugin-lighthouse@0.2.19
- @backstage/plugin-rollbar@0.3.8
- @backstage/plugin-search@0.4.2
- @backstage/plugin-sentry@0.3.14
- @backstage/plugin-todo@0.1.4
## 0.2.34
### Patch Changes
+25 -25
View File
@@ -1,43 +1,43 @@
{
"name": "example-app",
"version": "0.2.34",
"version": "0.2.36",
"private": true,
"bundled": true,
"dependencies": {
"@backstage/catalog-model": "^0.8.4",
"@backstage/catalog-model": "^0.9.0",
"@backstage/cli": "^0.7.2",
"@backstage/core-app-api": "^0.1.3",
"@backstage/core-components": "^0.1.3",
"@backstage/core-components": "^0.1.5",
"@backstage/core-plugin-api": "^0.1.3",
"@backstage/integration-react": "^0.1.4",
"@backstage/plugin-api-docs": "^0.6.0",
"@backstage/plugin-badges": "^0.2.3",
"@backstage/plugin-catalog": "^0.6.4",
"@backstage/plugin-catalog-import": "^0.5.11",
"@backstage/plugin-catalog-react": "^0.2.4",
"@backstage/plugin-circleci": "^0.2.17",
"@backstage/plugin-cloudbuild": "^0.2.17",
"@backstage/plugin-code-coverage": "^0.1.5",
"@backstage/plugin-api-docs": "^0.6.1",
"@backstage/plugin-badges": "^0.2.4",
"@backstage/plugin-catalog": "^0.6.6",
"@backstage/plugin-catalog-import": "^0.5.12",
"@backstage/plugin-catalog-react": "^0.2.6",
"@backstage/plugin-circleci": "^0.2.18",
"@backstage/plugin-cloudbuild": "^0.2.18",
"@backstage/plugin-code-coverage": "^0.1.6",
"@backstage/plugin-cost-insights": "^0.11.0",
"@backstage/plugin-explore": "^0.3.7",
"@backstage/plugin-explore": "^0.3.9",
"@backstage/plugin-gcp-projects": "^0.3.0",
"@backstage/plugin-github-actions": "^0.4.10",
"@backstage/plugin-github-actions": "^0.4.12",
"@backstage/plugin-graphiql": "^0.2.12",
"@backstage/plugin-jenkins": "^0.4.6",
"@backstage/plugin-kafka": "^0.2.9",
"@backstage/plugin-kubernetes": "^0.4.6",
"@backstage/plugin-lighthouse": "^0.2.18",
"@backstage/plugin-jenkins": "^0.4.7",
"@backstage/plugin-kafka": "^0.2.10",
"@backstage/plugin-kubernetes": "^0.4.7",
"@backstage/plugin-lighthouse": "^0.2.19",
"@backstage/plugin-newrelic": "^0.3.0",
"@backstage/plugin-org": "^0.3.15",
"@backstage/plugin-pagerduty": "0.3.6",
"@backstage/plugin-rollbar": "^0.3.7",
"@backstage/plugin-scaffolder": "^0.9.9",
"@backstage/plugin-search": "^0.4.1",
"@backstage/plugin-sentry": "^0.3.13",
"@backstage/plugin-org": "^0.3.16",
"@backstage/plugin-pagerduty": "0.3.7",
"@backstage/plugin-rollbar": "^0.3.8",
"@backstage/plugin-scaffolder": "^0.10.0",
"@backstage/plugin-search": "^0.4.2",
"@backstage/plugin-sentry": "^0.3.14",
"@backstage/plugin-shortcuts": "^0.1.4",
"@backstage/plugin-tech-radar": "^0.4.1",
"@backstage/plugin-techdocs": "^0.9.7",
"@backstage/plugin-todo": "^0.1.3",
"@backstage/plugin-techdocs": "^0.9.9",
"@backstage/plugin-todo": "^0.1.4",
"@backstage/plugin-user-settings": "^0.2.12",
"@backstage/theme": "^0.2.8",
"@material-ui/core": "^4.11.0",
+60
View File
@@ -1,5 +1,65 @@
# @backstage/backend-common
## 0.8.5
### Patch Changes
- 09d3eb684: Added a `readUrl` method to the `UrlReader` interface that allows for complex response objects and is intended to replace the `read` method. This new method is currently optional to implement which allows for a soft migration to `readUrl` instead of `read` in the future.
The main use case for `readUrl` returning an object instead of solely a read buffer is to allow for additional metadata such as ETag, which is a requirement for more efficient catalog processing.
The `GithubUrlReader` and `GitlabUrlReader` readers fully implement `readUrl`. The other existing readers implement the new method but do not propagate or return ETags.
While the `readUrl` method is not yet required, it will be in the future, and we already log deprecation warnings when custom `UrlReader` implementations that do not implement `readUrl` are used. We therefore recommend that any existing custom implementations are migrated to implement `readUrl`.
The old `read` and the new `readUrl` methods can easily be implemented using one another, but we recommend moving the chunk of the implementation to the new `readUrl` method as `read` is being removed, for example this:
```ts
class CustomUrlReader implements UrlReader {
read(url: string): Promise<Buffer> {
const res = await fetch(url);
if (!res.ok) {
// error handling ...
}
return Buffer.from(await res.text());
}
}
```
Can be migrated to something like this:
```ts
class CustomUrlReader implements UrlReader {
read(url: string): Promise<Buffer> {
const res = await this.readUrl(url);
return res.buffer();
}
async readUrl(
url: string,
_options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
const res = await fetch(url);
if (!res.ok) {
// error handling ...
}
const buffer = Buffer.from(await res.text());
return { buffer: async () => buffer };
}
}
```
While there is no usage of the ETag capability yet in the main Backstage packages, you can already add it to your custom implementations. To do so, refer to the documentation of the `readUrl` method and surrounding types, and the existing implementation in `packages/backend-common/src/reading/GithubUrlReader.ts`.
- 6841e0113: fix minor version of git-url-parse as 11.5.x introduced a bug for Bitbucket Server
- c2db794f5: add defaultBranch property for publish GitHub action
- Updated dependencies
- @backstage/integration@0.5.8
## 0.8.4
### Patch Changes
+276 -214
View File
@@ -3,6 +3,8 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
/// <reference types="node" />
/// <reference types="webpack-env" />
import { AzureIntegration } from '@backstage/integration';
import { BitbucketIntegration } from '@backstage/integration';
@@ -32,105 +34,133 @@ import { Writable } from 'stream';
// @public (undocumented)
export class AzureUrlReader implements UrlReader {
constructor(integration: AzureIntegration, deps: {
treeResponseFactory: ReadTreeResponseFactory;
});
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, _options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
constructor(
integration: AzureIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, _options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class BitbucketUrlReader implements UrlReader {
constructor(integration: BitbucketIntegration, deps: {
treeResponseFactory: ReadTreeResponseFactory;
});
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, _options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
constructor(
integration: BitbucketIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, _options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export interface CacheClient {
delete(key: string): Promise<void>;
get(key: string): Promise<JsonValue | undefined>;
set(key: string, value: JsonValue, options?: CacheSetOptions): Promise<void>;
delete(key: string): Promise<void>;
get(key: string): Promise<JsonValue | undefined>;
set(key: string, value: JsonValue, options?: CacheSetOptions): Promise<void>;
}
// @public
export class CacheManager {
forPlugin(pluginId: string): PluginCacheManager;
static fromConfig(config: Config, options?: CacheManagerOptions): CacheManager;
}
forPlugin(pluginId: string): PluginCacheManager;
static fromConfig(
config: Config,
options?: CacheManagerOptions,
): CacheManager;
}
// @public (undocumented)
export const coloredFormat: winston.Logform.Format;
// @public (undocumented)
export interface ContainerRunner {
// (undocumented)
runContainer(opts: RunContainerOptions): Promise<void>;
// (undocumented)
runContainer(opts: RunContainerOptions): Promise<void>;
}
// @public @deprecated
export const createDatabase: typeof createDatabaseClient;
// @public
export function createDatabaseClient(dbConfig: Config, overrides?: Partial<Knex.Config>): Knex<any, unknown[]>;
export function createDatabaseClient(
dbConfig: Config,
overrides?: Partial<Knex.Config>,
): Knex<any, unknown[]>;
// @public (undocumented)
export function createRootLogger(options?: winston.LoggerOptions, env?: NodeJS.ProcessEnv): winston.Logger;
export function createRootLogger(
options?: winston.LoggerOptions,
env?: NodeJS.ProcessEnv,
): winston.Logger;
// @public
export function createServiceBuilder(_module: NodeModule): ServiceBuilderImpl;
// @public (undocumented)
export function createStatusCheckRouter(options: StatusCheckRouterOptions): Promise<express.Router>;
export function createStatusCheckRouter(
options: StatusCheckRouterOptions,
): Promise<express.Router>;
// @public (undocumented)
export class DatabaseManager {
forPlugin(pluginId: string): PluginDatabaseManager;
static fromConfig(config: Config): DatabaseManager;
}
forPlugin(pluginId: string): PluginDatabaseManager;
static fromConfig(config: Config): DatabaseManager;
}
// @public (undocumented)
export class DockerContainerRunner implements ContainerRunner {
constructor({ dockerClient }: {
dockerClient: Docker;
});
// (undocumented)
runContainer({ imageName, command, args, logStream, mountDirs, workingDir, envVars, }: RunContainerOptions): Promise<void>;
constructor({ dockerClient }: { dockerClient: Docker });
// (undocumented)
runContainer({
imageName,
command,
args,
logStream,
mountDirs,
workingDir,
envVars,
}: RunContainerOptions): Promise<void>;
}
// @public
export function ensureDatabaseExists(dbConfig: Config, ...databases: Array<string>): Promise<void>;
export function ensureDatabaseExists(
dbConfig: Config,
...databases: Array<string>
): Promise<void>;
// @public
export function errorHandler(options?: ErrorHandlerOptions): ErrorRequestHandler;
export function errorHandler(
options?: ErrorHandlerOptions,
): ErrorRequestHandler;
// @public (undocumented)
export type ErrorHandlerOptions = {
showStackTraces?: boolean;
logger?: Logger_2;
logClientErrors?: boolean;
showStackTraces?: boolean;
logger?: Logger_2;
logClientErrors?: boolean;
};
// @public (undocumented)
@@ -141,128 +171,154 @@ export function getVoidLogger(): winston.Logger;
// @public (undocumented)
export class Git {
// (undocumented)
add({ dir, filepath, }: {
dir: string;
filepath: string;
}): Promise<void>;
// (undocumented)
addRemote({ dir, url, remote, }: {
dir: string;
remote: string;
url: string;
}): Promise<void>;
// (undocumented)
clone({ url, dir, ref, }: {
url: string;
dir: string;
ref?: string;
}): Promise<void>;
// (undocumented)
commit({ dir, message, author, committer, }: {
dir: string;
message: string;
author: {
name: string;
email: string;
};
committer: {
name: string;
email: string;
};
}): Promise<string>;
// (undocumented)
currentBranch({ dir, fullName, }: {
dir: string;
fullName?: boolean;
}): Promise<string | undefined>;
// (undocumented)
fetch({ dir, remote, }: {
dir: string;
remote?: string;
}): Promise<void>;
// (undocumented)
static fromAuth: ({ username, password, logger, }: {
username?: string | undefined;
password?: string | undefined;
logger?: Logger_2 | undefined;
}) => Git;
// (undocumented)
init({ dir, defaultBranch, }: {
dir: string;
defaultBranch?: string;
}): Promise<void>;
// (undocumented)
merge({ dir, theirs, ours, author, committer, }: {
dir: string;
theirs: string;
ours?: string;
author: {
name: string;
email: string;
};
committer: {
name: string;
email: string;
};
}): Promise<MergeResult>;
// (undocumented)
push({ dir, remote }: {
dir: string;
remote: string;
}): Promise<PushResult>;
// (undocumented)
readCommit({ dir, sha, }: {
dir: string;
sha: string;
}): Promise<ReadCommitResult>;
// (undocumented)
resolveRef({ dir, ref, }: {
dir: string;
ref: string;
}): Promise<string>;
// (undocumented)
add({ dir, filepath }: { dir: string; filepath: string }): Promise<void>;
// (undocumented)
addRemote({
dir,
url,
remote,
}: {
dir: string;
remote: string;
url: string;
}): Promise<void>;
// (undocumented)
clone({
url,
dir,
ref,
}: {
url: string;
dir: string;
ref?: string;
}): Promise<void>;
// (undocumented)
commit({
dir,
message,
author,
committer,
}: {
dir: string;
message: string;
author: {
name: string;
email: string;
};
committer: {
name: string;
email: string;
};
}): Promise<string>;
// (undocumented)
currentBranch({
dir,
fullName,
}: {
dir: string;
fullName?: boolean;
}): Promise<string | undefined>;
// (undocumented)
fetch({ dir, remote }: { dir: string; remote?: string }): Promise<void>;
// (undocumented)
static fromAuth: ({
username,
password,
logger,
}: {
username?: string | undefined;
password?: string | undefined;
logger?: Logger_2 | undefined;
}) => Git;
// (undocumented)
init({
dir,
defaultBranch,
}: {
dir: string;
defaultBranch?: string;
}): Promise<void>;
// (undocumented)
merge({
dir,
theirs,
ours,
author,
committer,
}: {
dir: string;
theirs: string;
ours?: string;
author: {
name: string;
email: string;
};
committer: {
name: string;
email: string;
};
}): Promise<MergeResult>;
// (undocumented)
push({ dir, remote }: { dir: string; remote: string }): Promise<PushResult>;
// (undocumented)
readCommit({
dir,
sha,
}: {
dir: string;
sha: string;
}): Promise<ReadCommitResult>;
// (undocumented)
resolveRef({ dir, ref }: { dir: string; ref: string }): Promise<string>;
}
// @public
export class GithubUrlReader implements UrlReader {
constructor(integration: GitHubIntegration, deps: {
treeResponseFactory: ReadTreeResponseFactory;
credentialsProvider: GithubCredentialsProvider;
});
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
constructor(
integration: GitHubIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
credentialsProvider: GithubCredentialsProvider;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// @public (undocumented)
export class GitlabUrlReader implements UrlReader {
constructor(integration: GitLabIntegration, deps: {
treeResponseFactory: ReadTreeResponseFactory;
});
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
constructor(
integration: GitLabIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
export { isChildPath }
export { isChildPath };
// @public
export function loadBackendConfig(options: Options): Promise<Config>;
@@ -272,32 +328,32 @@ export function notFoundHandler(): RequestHandler;
// @public
export type PluginCacheManager = {
getClient: (options?: ClientOptions) => CacheClient;
getClient: (options?: ClientOptions) => CacheClient;
};
// @public
export interface PluginDatabaseManager {
getClient(): Promise<Knex>;
getClient(): Promise<Knex>;
}
// @public
export type PluginEndpointDiscovery = {
getBaseUrl(pluginId: string): Promise<string>;
getExternalBaseUrl(pluginId: string): Promise<string>;
getBaseUrl(pluginId: string): Promise<string>;
getExternalBaseUrl(pluginId: string): Promise<string>;
};
// @public
export type ReadTreeResponse = {
files(): Promise<ReadTreeResponseFile[]>;
archive(): Promise<NodeJS.ReadableStream>;
dir(options?: ReadTreeResponseDirOptions): Promise<string>;
etag: string;
files(): Promise<ReadTreeResponseFile[]>;
archive(): Promise<NodeJS.ReadableStream>;
dir(options?: ReadTreeResponseDirOptions): Promise<string>;
etag: string;
};
// @public
export type ReadTreeResponseFile = {
path: string;
content(): Promise<Buffer>;
path: string;
content(): Promise<Buffer>;
};
// @public
@@ -311,37 +367,37 @@ export function resolveSafeChildPath(base: string, path: string): string;
// @public (undocumented)
export type RunContainerOptions = {
imageName: string;
command?: string | string[];
args: string[];
logStream?: Writable;
mountDirs?: Record<string, string>;
workingDir?: string;
envVars?: Record<string, string>;
imageName: string;
command?: string | string[];
args: string[];
logStream?: Writable;
mountDirs?: Record<string, string>;
workingDir?: string;
envVars?: Record<string, string>;
};
// @public
export type SearchResponse = {
files: SearchResponseFile[];
etag: string;
files: SearchResponseFile[];
etag: string;
};
// @public
export type SearchResponseFile = {
url: string;
content(): Promise<Buffer>;
url: string;
content(): Promise<Buffer>;
};
// @public (undocumented)
export type ServiceBuilder = {
loadConfig(config: ConfigReader): ServiceBuilder;
setPort(port: number): ServiceBuilder;
setHost(host: string): ServiceBuilder;
setLogger(logger: Logger_2): ServiceBuilder;
enableCors(options: cors.CorsOptions): ServiceBuilder;
setHttpsSettings(settings: HttpsSettings): ServiceBuilder;
addRouter(root: string, router: Router | RequestHandler): ServiceBuilder;
start(): Promise<Server>;
loadConfig(config: ConfigReader): ServiceBuilder;
setPort(port: number): ServiceBuilder;
setHost(host: string): ServiceBuilder;
setLogger(logger: Logger_2): ServiceBuilder;
enableCors(options: cors.CorsOptions): ServiceBuilder;
setHttpsSettings(settings: HttpsSettings): ServiceBuilder;
addRouter(root: string, router: Router | RequestHandler): ServiceBuilder;
start(): Promise<Server>;
};
// @public (undocumented)
@@ -352,47 +408,53 @@ export const SingleConnectionDatabaseManager: typeof DatabaseManager;
// @public
export class SingleHostDiscovery implements PluginEndpointDiscovery {
static fromConfig(config: Config, options?: {
basePath?: string;
}): SingleHostDiscovery;
// (undocumented)
getBaseUrl(pluginId: string): Promise<string>;
// (undocumented)
getExternalBaseUrl(pluginId: string): Promise<string>;
}
static fromConfig(
config: Config,
options?: {
basePath?: string;
},
): SingleHostDiscovery;
// (undocumented)
getBaseUrl(pluginId: string): Promise<string>;
// (undocumented)
getExternalBaseUrl(pluginId: string): Promise<string>;
}
// @public (undocumented)
export type StatusCheck = () => Promise<any>;
// @public
export function statusCheckHandler(options?: StatusCheckHandlerOptions): Promise<RequestHandler>;
export function statusCheckHandler(
options?: StatusCheckHandlerOptions,
): Promise<RequestHandler>;
// @public (undocumented)
export interface StatusCheckHandlerOptions {
statusCheck?: StatusCheck;
statusCheck?: StatusCheck;
}
// @public
export type UrlReader = {
read(url: string): Promise<Buffer>;
readUrl?(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
read(url: string): Promise<Buffer>;
readUrl?(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
};
// @public
export class UrlReaders {
static create({ logger, config, factories }: CreateOptions): UrlReader;
static default({ logger, config, factories }: CreateOptions): UrlReader;
static create({ logger, config, factories }: CreateOptions): UrlReader;
static default({ logger, config, factories }: CreateOptions): UrlReader;
}
// @public
export function useHotCleanup(_module: NodeModule, cancelEffect: () => void): void;
export function useHotCleanup(
_module: NodeModule,
cancelEffect: () => void,
): void;
// @public
export function useHotMemoize<T>(_module: NodeModule, valueFactory: () => T): T;
// (No @packageDocumentation comment for this package)
```
+10
View File
@@ -64,6 +64,11 @@ export interface Config {
connection: string | object;
/** Database name prefix override */
prefix?: string;
/**
* Whether to ensure the given database exists by creating it if it does not.
* Defaults to true if unspecified.
*/
ensureExists?: boolean;
/** Plugin specific database configuration and client override */
plugin?: {
[pluginId: string]: {
@@ -74,6 +79,11 @@ export interface Config {
* @secret
*/
connection?: string | object;
/**
* Whether to ensure the given database exists by creating it if it does not.
* Defaults to base config if unspecified.
*/
ensureExists?: boolean;
};
};
};
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.8.4",
"version": "0.8.5",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -33,7 +33,7 @@
"@backstage/config": "^0.1.5",
"@backstage/config-loader": "^0.6.4",
"@backstage/errors": "^0.1.1",
"@backstage/integration": "^0.5.7",
"@backstage/integration": "^0.5.8",
"@google-cloud/storage": "^5.8.0",
"@octokit/rest": "^18.5.3",
"@types/cors": "^2.8.6",
@@ -47,8 +47,8 @@
"dockerode": "^3.2.1",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"fs-extra": "^10.0.0",
"git-url-parse": "^11.4.4",
"fs-extra": "9.1.0",
"git-url-parse": "~11.4.4",
"helmet": "^4.0.0",
"isomorphic-git": "^1.8.0",
"keyv": "^4.0.3",
@@ -128,6 +128,14 @@ export class DatabaseManager {
};
}
private getEnsureExistsConfig(pluginId: string): boolean {
const baseConfig = this.config.getOptionalBoolean('ensureExists') ?? true;
return (
this.config.getOptionalBoolean(`${pluginPath(pluginId)}.ensureExists`) ??
baseConfig
);
}
/**
* Provides a Knex connection plugin config by combining base and plugin config.
*
@@ -203,13 +211,15 @@ export class DatabaseManager {
this.getConfigForPlugin(pluginId) as JsonObject,
);
const databaseName = this.getDatabaseName(pluginId);
try {
await ensureDatabaseExists(pluginConfig, databaseName);
} catch (error) {
throw new Error(
`Failed to connect to the database to make sure that '${databaseName}' exists, ${error}`,
);
if (this.getEnsureExistsConfig(pluginId)) {
const databaseName = this.getDatabaseName(pluginId);
try {
await ensureDatabaseExists(pluginConfig, databaseName);
} catch (error) {
throw new Error(
`Failed to connect to the database to make sure that '${databaseName}' exists, ${error}`,
);
}
}
return createDatabaseClient(
@@ -22,6 +22,10 @@ import { errorHandler, statusCheckHandler, StatusCheck } from '../middleware';
export interface StatusCheckRouterOptions {
logger: Logger;
path?: string;
/**
* If not implemented, the default express middleware always returns 200.
* Override this to implement your own logic for a health check.
*/
statusCheck?: StatusCheck;
}
+8
View File
@@ -1,5 +1,13 @@
# @backstage/backend-test-utils
## 0.1.4
### Patch Changes
- f7134c368: bump sqlite3 to 5.0.1
- Updated dependencies
- @backstage/backend-common@0.8.5
## 0.1.3
### Patch Changes
+14 -13
View File
@@ -3,29 +3,30 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { Knex } from 'knex';
// @public (undocumented)
export function isDockerDisabledForTests(): boolean;
// @public
export type TestDatabaseId = 'POSTGRES_13' | 'POSTGRES_9' | 'MYSQL_8' | 'SQLITE_3';
export type TestDatabaseId =
| 'POSTGRES_13'
| 'POSTGRES_9'
| 'MYSQL_8'
| 'SQLITE_3';
// @public
export class TestDatabases {
static create(options?: {
ids?: TestDatabaseId[];
disableDocker?: boolean;
}): TestDatabases;
// (undocumented)
eachSupportedId(): [TestDatabaseId][];
init(id: TestDatabaseId): Promise<Knex>;
// (undocumented)
supports(id: TestDatabaseId): boolean;
static create(options?: {
ids?: TestDatabaseId[];
disableDocker?: boolean;
}): TestDatabases;
// (undocumented)
eachSupportedId(): [TestDatabaseId][];
init(id: TestDatabaseId): Promise<Knex>;
// (undocumented)
supports(id: TestDatabaseId): boolean;
}
// (No @packageDocumentation comment for this package)
```
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-test-utils",
"description": "Test helpers library for Backstage backends",
"version": "0.1.3",
"version": "0.1.4",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -30,7 +30,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.8.3",
"@backstage/backend-common": "^0.8.5",
"@backstage/cli": "^0.7.1",
"@backstage/config": "^0.1.5",
"knex": "^0.95.1",
+23
View File
@@ -1,5 +1,28 @@
# example-backend
## 0.2.36
### Patch Changes
- Updated dependencies
- @backstage/integration@0.5.8
- @backstage/plugin-scaffolder-backend@0.13.0
- @backstage/catalog-model@0.9.0
- @backstage/plugin-catalog-backend@0.12.0
- @backstage/backend-common@0.8.5
- @backstage/plugin-search-backend-node@0.3.0
- example-app@0.2.36
- @backstage/plugin-scaffolder-backend-module-rails@0.1.2
- @backstage/catalog-client@0.3.16
- @backstage/plugin-auth-backend@0.3.16
- @backstage/plugin-badges-backend@0.1.8
- @backstage/plugin-code-coverage-backend@0.1.8
- @backstage/plugin-kafka-backend@0.2.8
- @backstage/plugin-kubernetes-backend@0.3.9
- @backstage/plugin-techdocs-backend@0.8.6
- @backstage/plugin-todo-backend@0.1.8
- @backstage/plugin-search-backend@0.2.2
## 0.2.35
### Patch Changes
+10
View File
@@ -39,6 +39,16 @@ You can also, instead of using dummy values for a huge number of environment var
The backend starts up on port 7000 per default.
### Debugging
The backend is a node process that can be inspected to allow breakpoints and live debugging. To enable this, pass the `--inspect` flag to [backend:dev](https://backstage.io/docs/cli/commands#backenddev).
To debug the backend in [Visual Studio Code](https://code.visualstudio.com/):
- Enable Auto Attach (⌘ + Shift + P > Toggle Auto Attach > Only With Flag)
- Open a VSCode terminal (Control + `)
- Run the backend from the VSCode terminal: `yarn start-backend --inspect`
## Populating The Catalog
If you want to use the catalog functionality, you need to add so called
+18 -18
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.2.35",
"version": "0.2.36",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -27,32 +27,32 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
"@backstage/backend-common": "^0.8.4",
"@backstage/catalog-client": "^0.3.15",
"@backstage/catalog-model": "^0.8.2",
"@backstage/backend-common": "^0.8.5",
"@backstage/catalog-client": "^0.3.16",
"@backstage/catalog-model": "^0.9.0",
"@backstage/config": "^0.1.5",
"@backstage/integration": "^0.5.6",
"@backstage/integration": "^0.5.8",
"@backstage/plugin-app-backend": "^0.3.13",
"@backstage/plugin-auth-backend": "^0.3.15",
"@backstage/plugin-badges-backend": "^0.1.6",
"@backstage/plugin-catalog-backend": "^0.11.0",
"@backstage/plugin-code-coverage-backend": "^0.1.6",
"@backstage/plugin-auth-backend": "^0.3.16",
"@backstage/plugin-badges-backend": "^0.1.8",
"@backstage/plugin-catalog-backend": "^0.12.0",
"@backstage/plugin-code-coverage-backend": "^0.1.8",
"@backstage/plugin-graphql-backend": "^0.1.8",
"@backstage/plugin-kubernetes-backend": "^0.3.8",
"@backstage/plugin-kafka-backend": "^0.2.7",
"@backstage/plugin-kubernetes-backend": "^0.3.9",
"@backstage/plugin-kafka-backend": "^0.2.8",
"@backstage/plugin-proxy-backend": "^0.2.9",
"@backstage/plugin-rollbar-backend": "^0.1.11",
"@backstage/plugin-scaffolder-backend": "^0.12.4",
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.1",
"@backstage/plugin-search-backend": "^0.2.0",
"@backstage/plugin-search-backend-node": "^0.2.0",
"@backstage/plugin-techdocs-backend": "^0.8.5",
"@backstage/plugin-todo-backend": "^0.1.6",
"@backstage/plugin-scaffolder-backend": "^0.13.0",
"@backstage/plugin-scaffolder-backend-module-rails": "^0.1.2",
"@backstage/plugin-search-backend": "^0.2.2",
"@backstage/plugin-search-backend-node": "^0.3.0",
"@backstage/plugin-techdocs-backend": "^0.8.6",
"@backstage/plugin-todo-backend": "^0.1.8",
"@gitbeaker/node": "^30.2.0",
"@octokit/rest": "^18.5.3",
"azure-devops-node-api": "^10.2.2",
"dockerode": "^3.2.1",
"example-app": "^0.2.32",
"example-app": "^0.2.36",
"express": "^4.17.1",
"express-promise-router": "^4.1.0",
"knex": "^0.95.1",
+7
View File
@@ -1,5 +1,12 @@
# @backstage/catalog-client
## 0.3.16
### Patch Changes
- Updated dependencies
- @backstage/catalog-model@0.9.0
## 0.3.15
### Patch Changes
+96 -49
View File
@@ -3,83 +3,130 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { Entity } from '@backstage/catalog-model';
import { EntityName } from '@backstage/catalog-model';
import { Location as Location_2 } from '@backstage/catalog-model';
// @public (undocumented)
export type AddLocationRequest = {
type?: string;
target: string;
dryRun?: boolean;
presence?: 'optional' | 'required';
type?: string;
target: string;
dryRun?: boolean;
presence?: 'optional' | 'required';
};
// @public (undocumented)
export type AddLocationResponse = {
location: Location_2;
entities: Entity[];
location: Location_2;
entities: Entity[];
};
// @public (undocumented)
export interface CatalogApi {
// (undocumented)
addLocation(location: AddLocationRequest, options?: CatalogRequestOptions): Promise<AddLocationResponse>;
// (undocumented)
getEntities(request?: CatalogEntitiesRequest, options?: CatalogRequestOptions): Promise<CatalogListResponse<Entity>>;
// (undocumented)
getEntityByName(name: EntityName, options?: CatalogRequestOptions): Promise<Entity | undefined>;
// (undocumented)
getLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>;
// (undocumented)
getLocationById(id: string, options?: CatalogRequestOptions): Promise<Location_2 | undefined>;
// (undocumented)
getOriginLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>;
// (undocumented)
removeEntityByUid(uid: string, options?: CatalogRequestOptions): Promise<void>;
// (undocumented)
removeLocationById(id: string, options?: CatalogRequestOptions): Promise<void>;
// (undocumented)
addLocation(
location: AddLocationRequest,
options?: CatalogRequestOptions,
): Promise<AddLocationResponse>;
// (undocumented)
getEntities(
request?: CatalogEntitiesRequest,
options?: CatalogRequestOptions,
): Promise<CatalogListResponse<Entity>>;
// (undocumented)
getEntityByName(
name: EntityName,
options?: CatalogRequestOptions,
): Promise<Entity | undefined>;
// (undocumented)
getLocationByEntity(
entity: Entity,
options?: CatalogRequestOptions,
): Promise<Location_2 | undefined>;
// (undocumented)
getLocationById(
id: string,
options?: CatalogRequestOptions,
): Promise<Location_2 | undefined>;
// (undocumented)
getOriginLocationByEntity(
entity: Entity,
options?: CatalogRequestOptions,
): Promise<Location_2 | undefined>;
// (undocumented)
removeEntityByUid(
uid: string,
options?: CatalogRequestOptions,
): Promise<void>;
// (undocumented)
removeLocationById(
id: string,
options?: CatalogRequestOptions,
): Promise<void>;
}
// @public (undocumented)
export class CatalogClient implements CatalogApi {
constructor(options: {
discoveryApi: DiscoveryApi;
});
// (undocumented)
addLocation({ type, target, dryRun, presence }: AddLocationRequest, options?: CatalogRequestOptions): Promise<AddLocationResponse>;
// (undocumented)
getEntities(request?: CatalogEntitiesRequest, options?: CatalogRequestOptions): Promise<CatalogListResponse<Entity>>;
// (undocumented)
getEntityByName(compoundName: EntityName, options?: CatalogRequestOptions): Promise<Entity | undefined>;
// (undocumented)
getLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>;
// (undocumented)
getLocationById(id: string, options?: CatalogRequestOptions): Promise<Location_2 | undefined>;
// (undocumented)
getOriginLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location_2 | undefined>;
// (undocumented)
removeEntityByUid(uid: string, options?: CatalogRequestOptions): Promise<void>;
// (undocumented)
removeLocationById(id: string, options?: CatalogRequestOptions): Promise<void>;
}
constructor(options: { discoveryApi: DiscoveryApi });
// (undocumented)
addLocation(
{ type, target, dryRun, presence }: AddLocationRequest,
options?: CatalogRequestOptions,
): Promise<AddLocationResponse>;
// (undocumented)
getEntities(
request?: CatalogEntitiesRequest,
options?: CatalogRequestOptions,
): Promise<CatalogListResponse<Entity>>;
// (undocumented)
getEntityByName(
compoundName: EntityName,
options?: CatalogRequestOptions,
): Promise<Entity | undefined>;
// (undocumented)
getLocationByEntity(
entity: Entity,
options?: CatalogRequestOptions,
): Promise<Location_2 | undefined>;
// (undocumented)
getLocationById(
id: string,
options?: CatalogRequestOptions,
): Promise<Location_2 | undefined>;
// (undocumented)
getOriginLocationByEntity(
entity: Entity,
options?: CatalogRequestOptions,
): Promise<Location_2 | undefined>;
// (undocumented)
removeEntityByUid(
uid: string,
options?: CatalogRequestOptions,
): Promise<void>;
// (undocumented)
removeLocationById(
id: string,
options?: CatalogRequestOptions,
): Promise<void>;
}
// @public (undocumented)
export type CatalogEntitiesRequest = {
filter?: Record<string, string | string[]>[] | Record<string, string | string[]> | undefined;
fields?: string[] | undefined;
filter?:
| Record<string, string | string[]>[]
| Record<string, string | string[]>
| undefined;
fields?: string[] | undefined;
};
// @public (undocumented)
export type CatalogListResponse<T> = {
items: T[];
items: T[];
};
// @public
export const ENTITY_STATUS_CATALOG_PROCESSING_TYPE = "backstage.io/catalog-processing";
export const ENTITY_STATUS_CATALOG_PROCESSING_TYPE =
'backstage.io/catalog-processing';
// (No @packageDocumentation comment for this package)
```
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/catalog-client",
"version": "0.3.15",
"version": "0.3.16",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.8.4",
"@backstage/catalog-model": "^0.9.0",
"@backstage/config": "^0.1.5",
"@backstage/errors": "^0.1.1",
"cross-fetch": "^3.0.6"
+66
View File
@@ -1,5 +1,71 @@
# @backstage/catalog-model
## 0.9.0
### Minor Changes
- 77db0c454: Changed the regex to validate names following the Kubernetes validation rule, this allow to be more permissive validating the name of the object in Backstage.
- 60e830222: Support for `Template` kinds with version `backstage.io/v1alpha1` has now been removed. This means that the old method of running templates with `Preparers`, `Templaters` and `Publishers` has also been removed. If you had any logic in these abstractions, they should now be moved to `actions` instead, and you can find out more about those in the [documentation](https://backstage.io/docs/features/software-templates/writing-custom-actions)
If you need any help migrating existing templates, there's a [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1alpha1-to-v1beta2). Reach out to us on Discord in the #support channel if you're having problems.
The `scaffolder-backend` now no longer requires these `Preparers`, `Templaters`, and `Publishers` to be passed in, now all it needs is the `containerRunner`.
Please update your `packages/backend/src/plugins/scaffolder.ts` like the following
```diff
- import {
- DockerContainerRunner,
- SingleHostDiscovery,
- } from '@backstage/backend-common';
+ import { DockerContainerRunner } from '@backstage/backend-common';
import { CatalogClient } from '@backstage/catalog-client';
- import {
- CookieCutter,
- CreateReactAppTemplater,
- createRouter,
- Preparers,
- Publishers,
- Templaters,
- } from '@backstage/plugin-scaffolder-backend';
+ import { createRouter } from '@backstage/plugin-scaffolder-backend';
import Docker from 'dockerode';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
export default async function createPlugin({
config,
database,
reader,
+ discovery,
}: PluginEnvironment): Promise<Router> {
const dockerClient = new Docker();
const containerRunner = new DockerContainerRunner({ dockerClient });
- const cookiecutterTemplater = new CookieCutter({ containerRunner });
- const craTemplater = new CreateReactAppTemplater({ containerRunner });
- const templaters = new Templaters();
- templaters.register('cookiecutter', cookiecutterTemplater);
- templaters.register('cra', craTemplater);
-
- const preparers = await Preparers.fromConfig(config, { logger });
- const publishers = await Publishers.fromConfig(config, { logger });
- const discovery = SingleHostDiscovery.fromConfig(config);
const catalogClient = new CatalogClient({ discoveryApi: discovery });
return await createRouter({
- preparers,
- templaters,
- publishers,
+ containerRunner,
logger,
config,
database,
```
## 0.8.4
### Patch Changes
+342 -312
View File
@@ -3,7 +3,6 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { JsonObject } from '@backstage/config';
import { JSONSchema7 } from 'json-schema';
import { JsonValue } from '@backstage/config';
@@ -11,204 +10,222 @@ import { SerializedError } from '@backstage/errors';
import * as yup from 'yup';
// @public @deprecated (undocumented)
export const analyzeLocationSchema: yup.ObjectSchema<{
export const analyzeLocationSchema: yup.ObjectSchema<
{
location: LocationSpec;
}, object>;
},
object
>;
// @public (undocumented)
interface ApiEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'API';
// (undocumented)
spec: {
type: string;
lifecycle: string;
owner: string;
definition: string;
system?: string;
};
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'API';
// (undocumented)
spec: {
type: string;
lifecycle: string;
owner: string;
definition: string;
system?: string;
};
}
export { ApiEntityV1alpha1 as ApiEntity }
export { ApiEntityV1alpha1 }
export { ApiEntityV1alpha1 as ApiEntity };
export { ApiEntityV1alpha1 };
// @public (undocumented)
export const apiEntityV1alpha1Validator: KindValidator;
// @public
export class CommonValidatorFunctions {
static isJsonSafe(value: unknown): boolean;
static isValidDnsLabel(value: unknown): boolean;
static isValidDnsSubdomain(value: unknown): boolean;
static isValidPrefixAndOrSuffix(value: unknown, separator: string, isValidPrefix: (value: string) => boolean, isValidSuffix: (value: string) => boolean): boolean;
static isValidString(value: unknown): boolean;
static isValidUrl(value: unknown): boolean;
static isJsonSafe(value: unknown): boolean;
static isValidDnsLabel(value: unknown): boolean;
static isValidDnsSubdomain(value: unknown): boolean;
static isValidPrefixAndOrSuffix(
value: unknown,
separator: string,
isValidPrefix: (value: string) => boolean,
isValidSuffix: (value: string) => boolean,
): boolean;
static isValidString(value: unknown): boolean;
static isValidUrl(value: unknown): boolean;
}
// @public
export function compareEntityToRef(entity: Entity, ref: EntityRef | EntityName, context?: EntityRefContext): boolean;
export function compareEntityToRef(
entity: Entity,
ref: EntityRef | EntityName,
context?: EntityRefContext,
): boolean;
// @public (undocumented)
interface ComponentEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Component';
// (undocumented)
spec: {
type: string;
lifecycle: string;
owner: string;
subcomponentOf?: string;
providesApis?: string[];
consumesApis?: string[];
dependsOn?: string[];
system?: string;
};
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Component';
// (undocumented)
spec: {
type: string;
lifecycle: string;
owner: string;
subcomponentOf?: string;
providesApis?: string[];
consumesApis?: string[];
dependsOn?: string[];
system?: string;
};
}
export { ComponentEntityV1alpha1 as ComponentEntity }
export { ComponentEntityV1alpha1 }
export { ComponentEntityV1alpha1 as ComponentEntity };
export { ComponentEntityV1alpha1 };
// @public (undocumented)
export const componentEntityV1alpha1Validator: KindValidator;
// @public
export class DefaultNamespaceEntityPolicy implements EntityPolicy {
constructor(namespace?: string);
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
constructor(namespace?: string);
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
// @public (undocumented)
interface DomainEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Domain';
// (undocumented)
spec: {
owner: string;
};
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Domain';
// (undocumented)
spec: {
owner: string;
};
}
export { DomainEntityV1alpha1 as DomainEntity }
export { DomainEntityV1alpha1 }
export { DomainEntityV1alpha1 as DomainEntity };
export { DomainEntityV1alpha1 };
// @public (undocumented)
export const domainEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
export const EDIT_URL_ANNOTATION = "backstage.io/edit-url";
export const EDIT_URL_ANNOTATION = 'backstage.io/edit-url';
// @public
export type Entity = {
apiVersion: string;
kind: string;
metadata: EntityMeta;
spec?: JsonObject;
relations?: EntityRelation[];
status?: UNSTABLE_EntityStatus;
apiVersion: string;
kind: string;
metadata: EntityMeta;
spec?: JsonObject;
relations?: EntityRelation[];
status?: UNSTABLE_EntityStatus;
};
// @public
export const ENTITY_DEFAULT_NAMESPACE = "default";
export const ENTITY_DEFAULT_NAMESPACE = 'default';
// @public
export const ENTITY_META_GENERATED_FIELDS: readonly ["uid", "etag", "generation"];
export const ENTITY_META_GENERATED_FIELDS: readonly [
'uid',
'etag',
'generation',
];
// @public
export type EntityEnvelope = {
apiVersion: string;
kind: string;
metadata: {
name: string;
namespace?: string;
};
apiVersion: string;
kind: string;
metadata: {
name: string;
namespace?: string;
};
};
// @public
export function entityEnvelopeSchemaValidator<T extends EntityEnvelope = EntityEnvelope>(schema?: unknown): (data: unknown) => T;
export function entityEnvelopeSchemaValidator<
T extends EntityEnvelope = EntityEnvelope
>(schema?: unknown): (data: unknown) => T;
// @public
export function entityHasChanges(previous: Entity, next: Entity): boolean;
// @public
export function entityKindSchemaValidator<T extends Entity>(schema: unknown): (data: unknown) => T | false;
export function entityKindSchemaValidator<T extends Entity>(
schema: unknown,
): (data: unknown) => T | false;
// @public
export type EntityLink = {
url: string;
title?: string;
icon?: string;
url: string;
title?: string;
icon?: string;
};
// @public
export type EntityMeta = JsonObject & {
uid?: string;
etag?: string;
generation?: number;
name: string;
namespace?: string;
description?: string;
labels?: Record<string, string>;
annotations?: Record<string, string>;
tags?: string[];
links?: EntityLink[];
uid?: string;
etag?: string;
generation?: number;
name: string;
namespace?: string;
description?: string;
labels?: Record<string, string>;
annotations?: Record<string, string>;
tags?: string[];
links?: EntityLink[];
};
// @public
export type EntityName = {
kind: string;
namespace: string;
name: string;
kind: string;
namespace: string;
name: string;
};
// @public (undocumented)
export const EntityPolicies: {
allOf(policies: EntityPolicy[]): AllEntityPolicies;
oneOf(policies: EntityPolicy[]): AnyEntityPolicy;
allOf(policies: EntityPolicy[]): AllEntityPolicies;
oneOf(policies: EntityPolicy[]): AnyEntityPolicy;
};
// @public
export type EntityPolicy = {
enforce(entity: Entity): Promise<Entity | undefined>;
enforce(entity: Entity): Promise<Entity | undefined>;
};
// @public
export type EntityRef = string | {
kind?: string;
namespace?: string;
name: string;
};
export type EntityRef =
| string
| {
kind?: string;
namespace?: string;
name: string;
};
// @public
export type EntityRelation = {
type: string;
target: EntityName;
type: string;
target: EntityName;
};
// @public
export type EntityRelationSpec = {
source: EntityName;
type: string;
target: EntityName;
source: EntityName;
type: string;
target: EntityName;
};
// @public
export function entitySchemaValidator<T extends Entity = Entity>(schema?: unknown): (data: unknown) => T;
export function entitySchemaValidator<T extends Entity = Entity>(
schema?: unknown,
): (data: unknown) => T;
// @public
export class FieldFormatEntityPolicy implements EntityPolicy {
constructor(validators?: Validators);
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
constructor(validators?: Validators);
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
// @public
export function generateEntityEtag(): string;
@@ -223,95 +240,93 @@ export function generateUpdatedEntity(previous: Entity, next: Entity): Entity;
export function getEntityName(entity: Entity): EntityName;
// @public
export function getEntitySourceLocation(entity: Entity): {
type: string;
target: string;
export function getEntitySourceLocation(
entity: Entity,
): {
type: string;
target: string;
};
// @public (undocumented)
interface GroupEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Group';
// (undocumented)
spec: {
type: string;
profile?: {
displayName?: string;
email?: string;
picture?: string;
};
parent?: string;
children: string[];
members?: string[];
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Group';
// (undocumented)
spec: {
type: string;
profile?: {
displayName?: string;
email?: string;
picture?: string;
};
parent?: string;
children: string[];
members?: string[];
};
}
export { GroupEntityV1alpha1 as GroupEntity }
export { GroupEntityV1alpha1 }
export { GroupEntityV1alpha1 as GroupEntity };
export { GroupEntityV1alpha1 };
// @public (undocumented)
export const groupEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
export type JSONSchema = JSONSchema7 & {
export type JSONSchema = JSONSchema7 &
{
[key in string]?: JsonValue;
};
};
// @public
export type KindValidator = {
check(entity: Entity): Promise<boolean>;
check(entity: Entity): Promise<boolean>;
};
// @public
export class KubernetesValidatorFunctions {
// (undocumented)
static isValidAnnotationKey(value: unknown): boolean;
// (undocumented)
static isValidAnnotationValue(value: unknown): boolean;
// (undocumented)
static isValidApiVersion(value: unknown): boolean;
// (undocumented)
static isValidKind(value: unknown): boolean;
// (undocumented)
static isValidLabelKey(value: unknown): boolean;
// (undocumented)
static isValidLabelValue(value: unknown): boolean;
// (undocumented)
static isValidNamespace(value: unknown): boolean;
// (undocumented)
static isValidObjectName(value: unknown): boolean;
// (undocumented)
static isValidAnnotationKey(value: unknown): boolean;
// (undocumented)
static isValidAnnotationValue(value: unknown): boolean;
// (undocumented)
static isValidApiVersion(value: unknown): boolean;
// (undocumented)
static isValidKind(value: unknown): boolean;
// (undocumented)
static isValidLabelKey(value: unknown): boolean;
// (undocumented)
static isValidLabelValue(value: unknown): boolean;
// (undocumented)
static isValidNamespace(value: unknown): boolean;
// (undocumented)
static isValidObjectName(value: unknown): boolean;
}
// @public (undocumented)
type Location_2 = {
id: string;
id: string;
} & LocationSpec;
export { Location_2 as Location }
export { Location_2 as Location };
// @public (undocumented)
export const LOCATION_ANNOTATION = "backstage.io/managed-by-location";
export const LOCATION_ANNOTATION = 'backstage.io/managed-by-location';
// @public (undocumented)
interface LocationEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Location';
// (undocumented)
spec: {
type?: string;
target?: string;
targets?: string[];
};
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Location';
// (undocumented)
spec: {
type?: string;
target?: string;
targets?: string[];
};
}
export { LocationEntityV1alpha1 as LocationEntity }
export { LocationEntityV1alpha1 }
export { LocationEntityV1alpha1 as LocationEntity };
export { LocationEntityV1alpha1 };
// @public (undocumented)
export const locationEntityV1alpha1Validator: KindValidator;
@@ -321,9 +336,9 @@ export const locationSchema: yup.ObjectSchema<Location_2, object>;
// @public (undocumented)
export type LocationSpec = {
type: string;
target: string;
presence?: 'optional' | 'required';
type: string;
target: string;
presence?: 'optional' | 'required';
};
// @public @deprecated (undocumented)
@@ -334,190 +349,209 @@ export function makeValidator(overrides?: Partial<Validators>): Validators;
// @public
export class NoForeignRootFieldsEntityPolicy implements EntityPolicy {
constructor(knownFields?: string[]);
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
constructor(knownFields?: string[]);
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
// @public (undocumented)
export const ORIGIN_LOCATION_ANNOTATION = "backstage.io/managed-by-origin-location";
export const ORIGIN_LOCATION_ANNOTATION =
'backstage.io/managed-by-origin-location';
// @public
export function parseEntityName(ref: EntityRef, context?: EntityRefContext): EntityName;
export function parseEntityName(
ref: EntityRef,
context?: EntityRefContext,
): EntityName;
// @public
export function parseEntityRef(ref: EntityRef, context?: {
export function parseEntityRef(
ref: EntityRef,
context?: {
defaultKind: string;
defaultNamespace: string;
}): {
kind: string;
namespace: string;
name: string;
},
): {
kind: string;
namespace: string;
name: string;
};
// @public (undocumented)
export function parseEntityRef(ref: EntityRef, context?: {
export function parseEntityRef(
ref: EntityRef,
context?: {
defaultKind: string;
}): {
kind: string;
namespace?: string;
name: string;
},
): {
kind: string;
namespace?: string;
name: string;
};
// @public (undocumented)
export function parseEntityRef(ref: EntityRef, context?: {
export function parseEntityRef(
ref: EntityRef,
context?: {
defaultNamespace: string;
}): {
kind?: string;
namespace: string;
name: string;
},
): {
kind?: string;
namespace: string;
name: string;
};
// @public
export function parseLocationReference(ref: string): {
type: string;
target: string;
export function parseLocationReference(
ref: string,
): {
type: string;
target: string;
};
// @public (undocumented)
export const RELATION_API_CONSUMED_BY = "apiConsumedBy";
export const RELATION_API_CONSUMED_BY = 'apiConsumedBy';
// @public (undocumented)
export const RELATION_API_PROVIDED_BY = "apiProvidedBy";
export const RELATION_API_PROVIDED_BY = 'apiProvidedBy';
// @public (undocumented)
export const RELATION_CHILD_OF = "childOf";
export const RELATION_CHILD_OF = 'childOf';
// @public
export const RELATION_CONSUMES_API = "consumesApi";
export const RELATION_CONSUMES_API = 'consumesApi';
// @public (undocumented)
export const RELATION_DEPENDENCY_OF = "dependencyOf";
export const RELATION_DEPENDENCY_OF = 'dependencyOf';
// @public
export const RELATION_DEPENDS_ON = "dependsOn";
export const RELATION_DEPENDS_ON = 'dependsOn';
// @public (undocumented)
export const RELATION_HAS_MEMBER = "hasMember";
export const RELATION_HAS_MEMBER = 'hasMember';
// @public (undocumented)
export const RELATION_HAS_PART = "hasPart";
export const RELATION_HAS_PART = 'hasPart';
// @public
export const RELATION_MEMBER_OF = "memberOf";
export const RELATION_MEMBER_OF = 'memberOf';
// @public
export const RELATION_OWNED_BY = "ownedBy";
export const RELATION_OWNED_BY = 'ownedBy';
// @public (undocumented)
export const RELATION_OWNER_OF = "ownerOf";
export const RELATION_OWNER_OF = 'ownerOf';
// @public
export const RELATION_PARENT_OF = "parentOf";
export const RELATION_PARENT_OF = 'parentOf';
// @public
export const RELATION_PART_OF = "partOf";
export const RELATION_PART_OF = 'partOf';
// @public (undocumented)
export const RELATION_PROVIDES_API = "providesApi";
export const RELATION_PROVIDES_API = 'providesApi';
// @public (undocumented)
interface ResourceEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Resource';
// (undocumented)
spec: {
type: string;
owner: string;
dependsOn?: string[];
system?: string;
};
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'Resource';
// (undocumented)
spec: {
type: string;
owner: string;
dependsOn?: string[];
system?: string;
};
}
export { ResourceEntityV1alpha1 as ResourceEntity }
export { ResourceEntityV1alpha1 }
export { ResourceEntityV1alpha1 as ResourceEntity };
export { ResourceEntityV1alpha1 };
// @public (undocumented)
export const resourceEntityV1alpha1Validator: KindValidator;
// @public
export class SchemaValidEntityPolicy implements EntityPolicy {
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
// (undocumented)
enforce(entity: Entity): Promise<Entity>;
}
// @public @deprecated
export function serializeEntityRef(ref: Entity | {
kind?: string;
namespace?: string;
name: string;
}): EntityRef;
export function serializeEntityRef(
ref:
| Entity
| {
kind?: string;
namespace?: string;
name: string;
},
): EntityRef;
// @public (undocumented)
export const SOURCE_LOCATION_ANNOTATION = "backstage.io/source-location";
export const SOURCE_LOCATION_ANNOTATION = 'backstage.io/source-location';
// @public
export function stringifyEntityRef(ref: Entity | {
kind: string;
namespace?: string;
name: string;
}): string;
export function stringifyEntityRef(
ref:
| Entity
| {
kind: string;
namespace?: string;
name: string;
},
): string;
// @public
export function stringifyLocationReference(ref: {
type: string;
target: string;
type: string;
target: string;
}): string;
// @public (undocumented)
interface SystemEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'System';
// (undocumented)
spec: {
owner: string;
domain?: string;
};
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'System';
// (undocumented)
spec: {
owner: string;
domain?: string;
};
}
export { SystemEntityV1alpha1 as SystemEntity }
export { SystemEntityV1alpha1 }
export { SystemEntityV1alpha1 as SystemEntity };
export { SystemEntityV1alpha1 };
// @public (undocumented)
export const systemEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
export interface TemplateEntityV1beta2 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1beta2';
// (undocumented)
kind: 'Template';
// (undocumented)
metadata: EntityMeta & {
title?: string;
};
// (undocumented)
spec: {
type: string;
parameters?: JsonObject | JsonObject[];
steps: Array<{
id?: string;
name?: string;
action: string;
input?: JsonObject;
if?: string | boolean;
}>;
output?: {
[name: string]: string;
};
owner?: string;
// (undocumented)
apiVersion: 'backstage.io/v1beta2';
// (undocumented)
kind: 'Template';
// (undocumented)
metadata: EntityMeta & {
title?: string;
};
// (undocumented)
spec: {
type: string;
parameters?: JsonObject | JsonObject[];
steps: Array<{
id?: string;
name?: string;
action: string;
input?: JsonObject;
if?: string | boolean;
}>;
output?: {
[name: string]: string;
};
owner?: string;
};
}
// @public (undocumented)
@@ -525,15 +559,15 @@ export const templateEntityV1beta2Validator: KindValidator;
// @alpha
export type UNSTABLE_EntityStatus = {
items?: UNSTABLE_EntityStatusItem[];
items?: UNSTABLE_EntityStatusItem[];
};
// @alpha
export type UNSTABLE_EntityStatusItem = {
type: string;
level: UNSTABLE_EntityStatusLevel;
message: string;
error?: SerializedError;
type: string;
level: UNSTABLE_EntityStatusLevel;
message: string;
error?: SerializedError;
};
// @alpha
@@ -541,45 +575,41 @@ export type UNSTABLE_EntityStatusLevel = 'info' | 'warning' | 'error';
// @public (undocumented)
interface UserEntityV1alpha1 extends Entity {
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'User';
// (undocumented)
spec: {
profile?: {
displayName?: string;
email?: string;
picture?: string;
};
memberOf: string[];
// (undocumented)
apiVersion: 'backstage.io/v1alpha1' | 'backstage.io/v1beta1';
// (undocumented)
kind: 'User';
// (undocumented)
spec: {
profile?: {
displayName?: string;
email?: string;
picture?: string;
};
memberOf: string[];
};
}
export { UserEntityV1alpha1 as UserEntity }
export { UserEntityV1alpha1 }
export { UserEntityV1alpha1 as UserEntity };
export { UserEntityV1alpha1 };
// @public (undocumented)
export const userEntityV1alpha1Validator: KindValidator;
// @public (undocumented)
export type Validators = {
isValidApiVersion(value: unknown): boolean;
isValidKind(value: unknown): boolean;
isValidEntityName(value: unknown): boolean;
isValidNamespace(value: unknown): boolean;
isValidLabelKey(value: unknown): boolean;
isValidLabelValue(value: unknown): boolean;
isValidAnnotationKey(value: unknown): boolean;
isValidAnnotationValue(value: unknown): boolean;
isValidTag(value: unknown): boolean;
isValidApiVersion(value: unknown): boolean;
isValidKind(value: unknown): boolean;
isValidEntityName(value: unknown): boolean;
isValidNamespace(value: unknown): boolean;
isValidLabelKey(value: unknown): boolean;
isValidLabelValue(value: unknown): boolean;
isValidAnnotationKey(value: unknown): boolean;
isValidAnnotationValue(value: unknown): boolean;
isValidTag(value: unknown): boolean;
};
// @public
export const VIEW_URL_ANNOTATION = "backstage.io/view-url";
export const VIEW_URL_ANNOTATION = 'backstage.io/view-url';
// (No @packageDocumentation comment for this package)
```
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/catalog-model",
"version": "0.8.4",
"version": "0.9.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
+1 -1
View File
@@ -77,7 +77,7 @@
"express": "^4.17.1",
"file-loader": "^6.2.0",
"fork-ts-checker-webpack-plugin": "^6.2.9",
"fs-extra": "^10.0.0",
"fs-extra": "9.1.0",
"handlebars": "^4.7.3",
"html-webpack-plugin": "^4.3.0",
"inquirer": "^7.0.4",
+7
View File
@@ -1,5 +1,12 @@
# @backstage/codemods
## 0.1.5
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.1.5
## 0.1.4
### Patch Changes
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/codemods",
"description": "A collection of codemods for Backstage projects",
"version": "0.1.4",
"version": "0.1.5",
"private": false,
"publishConfig": {
"access": "public",
+10 -10
View File
@@ -3,15 +3,17 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { AppConfig } from '@backstage/config';
import { JsonObject } from '@backstage/config';
import { JSONSchema7 } from 'json-schema';
// @public
export type ConfigSchema = {
process(appConfigs: AppConfig[], options?: ConfigProcessingOptions): AppConfig[];
serialize(): JsonObject;
process(
appConfigs: AppConfig[],
options?: ConfigProcessingOptions,
): AppConfig[];
serialize(): JsonObject;
};
// @public
@@ -22,10 +24,10 @@ export function loadConfig(options: LoadConfigOptions): Promise<AppConfig[]>;
// @public (undocumented)
export type LoadConfigOptions = {
configRoot: string;
configPaths: string[];
env?: string;
experimentalEnvFunc?: EnvFunc;
configRoot: string;
configPaths: string[];
env?: string;
experimentalEnvFunc?: EnvFunc;
};
// @public
@@ -36,10 +38,8 @@ export function mergeConfigSchemas(schemas: JSONSchema7[]): JSONSchema7;
// @public
export function readEnvConfig(env: {
[name: string]: string | undefined;
[name: string]: string | undefined;
}): AppConfig[];
// (No @packageDocumentation comment for this package)
```
+1 -1
View File
@@ -34,7 +34,7 @@
"@backstage/config": "^0.1.5",
"@types/json-schema": "^7.0.6",
"ajv": "^7.0.3",
"fs-extra": "^10.0.0",
"fs-extra": "9.1.0",
"json-schema": "^0.3.0",
"json-schema-merge-allof": "^0.8.1",
"typescript-json-schema": "^0.50.1",
+62 -61
View File
@@ -3,79 +3,82 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
// @public (undocumented)
export type AppConfig = {
context: string;
data: JsonObject;
context: string;
data: JsonObject;
};
// @public (undocumented)
export type Config = {
has(key: string): boolean;
keys(): string[];
get<T = JsonValue>(key?: string): T;
getOptional<T = JsonValue>(key?: string): T | undefined;
getConfig(key: string): Config;
getOptionalConfig(key: string): Config | undefined;
getConfigArray(key: string): Config[];
getOptionalConfigArray(key: string): Config[] | undefined;
getNumber(key: string): number;
getOptionalNumber(key: string): number | undefined;
getBoolean(key: string): boolean;
getOptionalBoolean(key: string): boolean | undefined;
getString(key: string): string;
getOptionalString(key: string): string | undefined;
getStringArray(key: string): string[];
getOptionalStringArray(key: string): string[] | undefined;
has(key: string): boolean;
keys(): string[];
get<T = JsonValue>(key?: string): T;
getOptional<T = JsonValue>(key?: string): T | undefined;
getConfig(key: string): Config;
getOptionalConfig(key: string): Config | undefined;
getConfigArray(key: string): Config[];
getOptionalConfigArray(key: string): Config[] | undefined;
getNumber(key: string): number;
getOptionalNumber(key: string): number | undefined;
getBoolean(key: string): boolean;
getOptionalBoolean(key: string): boolean | undefined;
getString(key: string): string;
getOptionalString(key: string): string | undefined;
getStringArray(key: string): string[];
getOptionalStringArray(key: string): string[] | undefined;
};
// @public (undocumented)
export class ConfigReader implements Config {
constructor(data: JsonObject | undefined, context?: string, fallback?: ConfigReader | undefined, prefix?: string);
// (undocumented)
static fromConfigs(configs: AppConfig[]): ConfigReader;
// (undocumented)
get<T = JsonValue>(key?: string): T;
// (undocumented)
getBoolean(key: string): boolean;
// (undocumented)
getConfig(key: string): ConfigReader;
// (undocumented)
getConfigArray(key: string): ConfigReader[];
// (undocumented)
getNumber(key: string): number;
// (undocumented)
getOptional<T = JsonValue>(key?: string): T | undefined;
// (undocumented)
getOptionalBoolean(key: string): boolean | undefined;
// (undocumented)
getOptionalConfig(key: string): ConfigReader | undefined;
// (undocumented)
getOptionalConfigArray(key: string): ConfigReader[] | undefined;
// (undocumented)
getOptionalNumber(key: string): number | undefined;
// (undocumented)
getOptionalString(key: string): string | undefined;
// (undocumented)
getOptionalStringArray(key: string): string[] | undefined;
// (undocumented)
getString(key: string): string;
// (undocumented)
getStringArray(key: string): string[];
// (undocumented)
has(key: string): boolean;
// (undocumented)
keys(): string[];
}
// @public (undocumented)
export interface JsonArray extends Array<JsonValue> {
constructor(
data: JsonObject | undefined,
context?: string,
fallback?: ConfigReader | undefined,
prefix?: string,
);
// (undocumented)
static fromConfigs(configs: AppConfig[]): ConfigReader;
// (undocumented)
get<T = JsonValue>(key?: string): T;
// (undocumented)
getBoolean(key: string): boolean;
// (undocumented)
getConfig(key: string): ConfigReader;
// (undocumented)
getConfigArray(key: string): ConfigReader[];
// (undocumented)
getNumber(key: string): number;
// (undocumented)
getOptional<T = JsonValue>(key?: string): T | undefined;
// (undocumented)
getOptionalBoolean(key: string): boolean | undefined;
// (undocumented)
getOptionalConfig(key: string): ConfigReader | undefined;
// (undocumented)
getOptionalConfigArray(key: string): ConfigReader[] | undefined;
// (undocumented)
getOptionalNumber(key: string): number | undefined;
// (undocumented)
getOptionalString(key: string): string | undefined;
// (undocumented)
getOptionalStringArray(key: string): string[] | undefined;
// (undocumented)
getString(key: string): string;
// (undocumented)
getStringArray(key: string): string[];
// (undocumented)
has(key: string): boolean;
// (undocumented)
keys(): string[];
}
// @public (undocumented)
export interface JsonArray extends Array<JsonValue> {}
// @public (undocumented)
export type JsonObject = {
[key in string]?: JsonValue;
[key in string]?: JsonValue;
};
// @public (undocumented)
@@ -84,7 +87,5 @@ export type JsonPrimitive = number | string | boolean | null;
// @public (undocumented)
export type JsonValue = JsonObject | JsonArray | JsonPrimitive;
// (No @packageDocumentation comment for this package)
```
+327 -224
View File
@@ -3,7 +3,6 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { AlertApi } from '@backstage/core-plugin-api';
import { AlertMessage } from '@backstage/core-plugin-api';
import { AnyApiFactory } from '@backstage/core-plugin-api';
@@ -57,72 +56,97 @@ import { SubRouteRef } from '@backstage/core-plugin-api';
// @public
export class AlertApiForwarder implements AlertApi {
// (undocumented)
alert$(): Observable<AlertMessage>;
// (undocumented)
post(alert: AlertMessage): void;
}
// (undocumented)
alert$(): Observable<AlertMessage>;
// (undocumented)
post(alert: AlertMessage): void;
}
// @public (undocumented)
export type ApiFactoryHolder = {
get<T>(api: ApiRef<T>): ApiFactory<T, T, {
[key in string]: unknown;
}> | undefined;
get<T>(
api: ApiRef<T>,
):
| ApiFactory<
T,
T,
{
[key in string]: unknown;
}
>
| undefined;
};
// @public
export class ApiFactoryRegistry implements ApiFactoryHolder {
// (undocumented)
get<T>(api: ApiRef<T>): ApiFactory<T, T, {
[x: string]: unknown;
}> | undefined;
// (undocumented)
getAllApis(): Set<AnyApiRef>;
register<Api, Impl extends Api, Deps extends {
[name in string]: unknown;
}>(scope: ApiFactoryScope, factory: ApiFactory<Api, Impl, Deps>): boolean;
// (undocumented)
get<T>(
api: ApiRef<T>,
):
| ApiFactory<
T,
T,
{
[x: string]: unknown;
}
>
| undefined;
// (undocumented)
getAllApis(): Set<AnyApiRef>;
register<
Api,
Impl extends Api,
Deps extends {
[name in string]: unknown;
}
>(scope: ApiFactoryScope, factory: ApiFactory<Api, Impl, Deps>): boolean;
}
// @public (undocumented)
export const ApiProvider: {
({ apis, children, }: PropsWithChildren<ApiProviderProps>): JSX.Element;
propTypes: {
apis: PropTypes.Validator<PropTypes.InferProps<{
get: PropTypes.Validator<(...args: any[]) => any>;
}>>;
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
};
({ apis, children }: PropsWithChildren<ApiProviderProps>): JSX.Element;
propTypes: {
apis: PropTypes.Validator<
PropTypes.InferProps<{
get: PropTypes.Validator<(...args: any[]) => any>;
}>
>;
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
};
};
// @public (undocumented)
export class ApiRegistry implements ApiHolder {
constructor(apis: Map<string, unknown>);
// (undocumented)
static builder(): ApiRegistryBuilder;
// (undocumented)
static from(apis: ApiImpl[]): ApiRegistry;
// (undocumented)
get<T>(api: ApiRef<T>): T | undefined;
static with<T>(api: ApiRef<T>, impl: T): ApiRegistry;
with<T>(api: ApiRef<T>, impl: T): ApiRegistry;
constructor(apis: Map<string, unknown>);
// (undocumented)
static builder(): ApiRegistryBuilder;
// (undocumented)
static from(apis: ApiImpl[]): ApiRegistry;
// (undocumented)
get<T>(api: ApiRef<T>): T | undefined;
static with<T>(api: ApiRef<T>, impl: T): ApiRegistry;
with<T>(api: ApiRef<T>, impl: T): ApiRegistry;
}
// @public (undocumented)
export class ApiResolver implements ApiHolder {
constructor(factories: ApiFactoryHolder);
// (undocumented)
get<T>(ref: ApiRef<T>): T | undefined;
static validateFactories(factories: ApiFactoryHolder, apis: Iterable<AnyApiRef>): void;
constructor(factories: ApiFactoryHolder);
// (undocumented)
get<T>(ref: ApiRef<T>): T | undefined;
static validateFactories(
factories: ApiFactoryHolder,
apis: Iterable<AnyApiRef>,
): void;
}
// @public (undocumented)
export type AppComponents = {
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType<BootErrorPageProps>;
Progress: ComponentType<{}>;
Router: ComponentType<{}>;
ErrorBoundaryFallback: ComponentType<ErrorBoundaryFallbackProps>;
SignInPage?: ComponentType<SignInPageProps>;
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType<BootErrorPageProps>;
Progress: ComponentType<{}>;
Router: ComponentType<{}>;
ErrorBoundaryFallback: ComponentType<ErrorBoundaryFallbackProps>;
SignInPage?: ComponentType<SignInPageProps>;
};
// @public
@@ -130,72 +154,88 @@ export type AppConfigLoader = () => Promise<AppConfig[]>;
// @public (undocumented)
export type AppContext = {
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
getComponents(): AppComponents;
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
getComponents(): AppComponents;
};
// @public (undocumented)
export type AppOptions = {
apis?: Iterable<AnyApiFactory>;
icons?: Partial<AppIcons> & {
[key in string]: IconComponent;
apis?: Iterable<AnyApiFactory>;
icons?: Partial<AppIcons> &
{
[key in string]: IconComponent;
};
plugins?: BackstagePluginWithAnyOutput[];
components?: Partial<AppComponents>;
themes?: AppTheme[];
configLoader?: AppConfigLoader;
bindRoutes?(context: {
bind: AppRouteBinder;
}): void;
plugins?: BackstagePluginWithAnyOutput[];
components?: Partial<AppComponents>;
themes?: AppTheme[];
configLoader?: AppConfigLoader;
bindRoutes?(context: { bind: AppRouteBinder }): void;
};
// @public (undocumented)
export type AppRouteBinder = <ExternalRoutes extends {
export type AppRouteBinder = <
ExternalRoutes extends {
[name: string]: ExternalRouteRef;
}>(externalRoutes: ExternalRoutes, targetRoutes: PartialKeys<TargetRouteMap<ExternalRoutes>, KeysWithType<ExternalRoutes, ExternalRouteRef<any, true>>>) => void;
}
>(
externalRoutes: ExternalRoutes,
targetRoutes: PartialKeys<
TargetRouteMap<ExternalRoutes>,
KeysWithType<ExternalRoutes, ExternalRouteRef<any, true>>
>,
) => void;
// @public (undocumented)
export class AppThemeSelector implements AppThemeApi {
constructor(themes: AppTheme[]);
// (undocumented)
activeThemeId$(): Observable<string | undefined>;
// (undocumented)
static createWithStorage(themes: AppTheme[]): AppThemeSelector;
// (undocumented)
getActiveThemeId(): string | undefined;
// (undocumented)
getInstalledThemes(): AppTheme[];
// (undocumented)
setActiveThemeId(themeId?: string): void;
}
constructor(themes: AppTheme[]);
// (undocumented)
activeThemeId$(): Observable<string | undefined>;
// (undocumented)
static createWithStorage(themes: AppTheme[]): AppThemeSelector;
// (undocumented)
getActiveThemeId(): string | undefined;
// (undocumented)
getInstalledThemes(): AppTheme[];
// (undocumented)
setActiveThemeId(themeId?: string): void;
}
// @public (undocumented)
export class Auth0Auth {
// (undocumented)
static create({ discoveryApi, environment, provider, oauthRequestApi, defaultScopes, }: OAuthApiCreateOptions): typeof auth0AuthApiRef.T;
// (undocumented)
static create({
discoveryApi,
environment,
provider,
oauthRequestApi,
defaultScopes,
}: OAuthApiCreateOptions): typeof auth0AuthApiRef.T;
}
// @public (undocumented)
export type BackstageApp = {
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
getProvider(): ComponentType<{}>;
getRouter(): ComponentType<{}>;
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
getProvider(): ComponentType<{}>;
getRouter(): ComponentType<{}>;
};
// @public (undocumented)
export type BackstagePluginWithAnyOutput = Omit<BackstagePlugin<any, any>, 'output'> & {
output(): (PluginOutput | UnknownPluginOutput)[];
export type BackstagePluginWithAnyOutput = Omit<
BackstagePlugin<any, any>,
'output'
> & {
output(): (PluginOutput | UnknownPluginOutput)[];
};
// @public (undocumented)
export type BootErrorPageProps = {
step: 'load-config' | 'load-chunk';
error: Error;
step: 'load-config' | 'load-chunk';
error: Error;
};
export { ConfigReader }
export { ConfigReader };
// @public
export function createApp(options?: AppOptions): PrivateAppImpl;
@@ -205,36 +245,36 @@ export const defaultConfigLoader: AppConfigLoader;
// @public
export class ErrorAlerter implements ErrorApi {
constructor(alertApi: AlertApi, errorApi: ErrorApi);
// (undocumented)
error$(): Observable<{
error: {
name: string;
message: string;
stack?: string | undefined;
};
context?: ErrorContext | undefined;
}>;
// (undocumented)
post(error: Error, context?: ErrorContext): void;
constructor(alertApi: AlertApi, errorApi: ErrorApi);
// (undocumented)
error$(): Observable<{
error: {
name: string;
message: string;
stack?: string | undefined;
};
context?: ErrorContext | undefined;
}>;
// (undocumented)
post(error: Error, context?: ErrorContext): void;
}
// @public
export class ErrorApiForwarder implements ErrorApi {
// (undocumented)
error$(): Observable<{
error: Error;
context?: ErrorContext;
}>;
// (undocumented)
post(error: Error, context?: ErrorContext): void;
}
// (undocumented)
error$(): Observable<{
error: Error;
context?: ErrorContext;
}>;
// (undocumented)
post(error: Error, context?: ErrorContext): void;
}
// @public (undocumented)
export type ErrorBoundaryFallbackProps = {
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
};
// @public (undocumented)
@@ -242,191 +282,254 @@ export const FeatureFlagged: (props: FeatureFlaggedProps) => JSX.Element;
// @public (undocumented)
export type FeatureFlaggedProps = {
children: ReactNode;
} & ({
with: string;
} | {
without: string;
});
children: ReactNode;
} & (
| {
with: string;
}
| {
without: string;
}
);
// @public (undocumented)
export const FlatRoutes: (props: FlatRoutesProps) => JSX.Element | null;
// @public (undocumented)
export class GithubAuth implements OAuthApi, SessionApi {
constructor(sessionManager: SessionManager<GithubSession>);
// (undocumented)
static create({ discoveryApi, environment, provider, oauthRequestApi, defaultScopes, }: OAuthApiCreateOptions): GithubAuth;
// (undocumented)
getAccessToken(scope?: string, options?: AuthRequestOptions): Promise<string>;
// (undocumented)
getBackstageIdentity(options?: AuthRequestOptions): Promise<BackstageIdentity | undefined>;
// (undocumented)
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
// (undocumented)
static normalizeScope(scope?: string): Set<string>;
// (undocumented)
sessionState$(): Observable<SessionState>;
// (undocumented)
signIn(): Promise<void>;
// (undocumented)
signOut(): Promise<void>;
constructor(sessionManager: SessionManager<GithubSession>);
// (undocumented)
static create({
discoveryApi,
environment,
provider,
oauthRequestApi,
defaultScopes,
}: OAuthApiCreateOptions): GithubAuth;
// (undocumented)
getAccessToken(scope?: string, options?: AuthRequestOptions): Promise<string>;
// (undocumented)
getBackstageIdentity(
options?: AuthRequestOptions,
): Promise<BackstageIdentity | undefined>;
// (undocumented)
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
// (undocumented)
static normalizeScope(scope?: string): Set<string>;
// (undocumented)
sessionState$(): Observable<SessionState>;
// (undocumented)
signIn(): Promise<void>;
// (undocumented)
signOut(): Promise<void>;
}
// @public (undocumented)
export type GithubSession = {
providerInfo: {
accessToken: string;
scopes: Set<string>;
expiresAt: Date;
};
profile: ProfileInfo;
backstageIdentity: BackstageIdentity;
providerInfo: {
accessToken: string;
scopes: Set<string>;
expiresAt: Date;
};
profile: ProfileInfo;
backstageIdentity: BackstageIdentity;
};
// @public (undocumented)
export class GitlabAuth {
// (undocumented)
static create({ discoveryApi, environment, provider, oauthRequestApi, defaultScopes, }: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T;
// (undocumented)
static create({
discoveryApi,
environment,
provider,
oauthRequestApi,
defaultScopes,
}: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T;
}
// @public (undocumented)
export class GoogleAuth {
// (undocumented)
static create({ discoveryApi, oauthRequestApi, environment, provider, defaultScopes, }: OAuthApiCreateOptions): typeof googleAuthApiRef.T;
// (undocumented)
static create({
discoveryApi,
oauthRequestApi,
environment,
provider,
defaultScopes,
}: OAuthApiCreateOptions): typeof googleAuthApiRef.T;
}
// @public
export class LocalStorageFeatureFlags implements FeatureFlagsApi {
// (undocumented)
getRegisteredFlags(): FeatureFlag[];
// (undocumented)
isActive(name: string): boolean;
// (undocumented)
registerFlag(flag: FeatureFlag): void;
// (undocumented)
save(options: FeatureFlagsSaveOptions): void;
// (undocumented)
getRegisteredFlags(): FeatureFlag[];
// (undocumented)
isActive(name: string): boolean;
// (undocumented)
registerFlag(flag: FeatureFlag): void;
// (undocumented)
save(options: FeatureFlagsSaveOptions): void;
}
// @public (undocumented)
export class MicrosoftAuth {
// (undocumented)
static create({ environment, provider, oauthRequestApi, discoveryApi, defaultScopes, }: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
// (undocumented)
static create({
environment,
provider,
oauthRequestApi,
discoveryApi,
defaultScopes,
}: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
}
// @public (undocumented)
export class OAuth2 implements OAuthApi, OpenIdConnectApi, ProfileInfoApi, BackstageIdentityApi, SessionApi {
constructor(options: Options);
// (undocumented)
static create({ discoveryApi, environment, provider, oauthRequestApi, defaultScopes, scopeTransform, }: CreateOptions): OAuth2;
// (undocumented)
getAccessToken(scope?: string | string[], options?: AuthRequestOptions): Promise<string>;
// (undocumented)
getBackstageIdentity(options?: AuthRequestOptions): Promise<BackstageIdentity | undefined>;
// (undocumented)
getIdToken(options?: AuthRequestOptions): Promise<string>;
// (undocumented)
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
// (undocumented)
sessionState$(): Observable<SessionState>;
// (undocumented)
signIn(): Promise<void>;
// (undocumented)
signOut(): Promise<void>;
export class OAuth2
implements
OAuthApi,
OpenIdConnectApi,
ProfileInfoApi,
BackstageIdentityApi,
SessionApi {
constructor(options: Options);
// (undocumented)
static create({
discoveryApi,
environment,
provider,
oauthRequestApi,
defaultScopes,
scopeTransform,
}: CreateOptions): OAuth2;
// (undocumented)
getAccessToken(
scope?: string | string[],
options?: AuthRequestOptions,
): Promise<string>;
// (undocumented)
getBackstageIdentity(
options?: AuthRequestOptions,
): Promise<BackstageIdentity | undefined>;
// (undocumented)
getIdToken(options?: AuthRequestOptions): Promise<string>;
// (undocumented)
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
// (undocumented)
sessionState$(): Observable<SessionState>;
// (undocumented)
signIn(): Promise<void>;
// (undocumented)
signOut(): Promise<void>;
}
// @public (undocumented)
export type OAuth2Session = {
providerInfo: {
idToken: string;
accessToken: string;
scopes: Set<string>;
expiresAt: Date;
};
profile: ProfileInfo;
backstageIdentity: BackstageIdentity;
providerInfo: {
idToken: string;
accessToken: string;
scopes: Set<string>;
expiresAt: Date;
};
profile: ProfileInfo;
backstageIdentity: BackstageIdentity;
};
// @public
export class OAuthRequestManager implements OAuthRequestApi {
// (undocumented)
authRequest$(): Observable<PendingAuthRequest[]>;
// (undocumented)
createAuthRequester<T>(options: AuthRequesterOptions<T>): AuthRequester<T>;
}
// (undocumented)
authRequest$(): Observable<PendingAuthRequest[]>;
// (undocumented)
createAuthRequester<T>(options: AuthRequesterOptions<T>): AuthRequester<T>;
}
// @public (undocumented)
export class OktaAuth {
// (undocumented)
static create({ discoveryApi, environment, provider, oauthRequestApi, defaultScopes, }: OAuthApiCreateOptions): typeof oktaAuthApiRef.T;
// (undocumented)
static create({
discoveryApi,
environment,
provider,
oauthRequestApi,
defaultScopes,
}: OAuthApiCreateOptions): typeof oktaAuthApiRef.T;
}
// @public (undocumented)
export class OneLoginAuth {
// (undocumented)
static create({ discoveryApi, environment, provider, oauthRequestApi, }: CreateOptions_2): typeof oneloginAuthApiRef.T;
// (undocumented)
static create({
discoveryApi,
environment,
provider,
oauthRequestApi,
}: CreateOptions_2): typeof oneloginAuthApiRef.T;
}
// @public (undocumented)
export class SamlAuth implements ProfileInfoApi, BackstageIdentityApi, SessionApi {
constructor(sessionManager: SessionManager<SamlSession>);
// (undocumented)
static create({ discoveryApi, environment, provider, }: AuthApiCreateOptions): SamlAuth;
// (undocumented)
getBackstageIdentity(options?: AuthRequestOptions): Promise<BackstageIdentity | undefined>;
// (undocumented)
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
// (undocumented)
sessionState$(): Observable<SessionState>;
// (undocumented)
signIn(): Promise<void>;
// (undocumented)
signOut(): Promise<void>;
export class SamlAuth
implements ProfileInfoApi, BackstageIdentityApi, SessionApi {
constructor(sessionManager: SessionManager<SamlSession>);
// (undocumented)
static create({
discoveryApi,
environment,
provider,
}: AuthApiCreateOptions): SamlAuth;
// (undocumented)
getBackstageIdentity(
options?: AuthRequestOptions,
): Promise<BackstageIdentity | undefined>;
// (undocumented)
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
// (undocumented)
sessionState$(): Observable<SessionState>;
// (undocumented)
signIn(): Promise<void>;
// (undocumented)
signOut(): Promise<void>;
}
// @public (undocumented)
export type SignInPageProps = {
onResult(result: SignInResult): void;
onResult(result: SignInResult): void;
};
// @public (undocumented)
export type SignInResult = {
userId: string;
profile: ProfileInfo;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
userId: string;
profile: ProfileInfo;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
};
// @public (undocumented)
export class UnhandledErrorForwarder {
static forward(errorApi: ErrorApi, errorContext: ErrorContext): void;
static forward(errorApi: ErrorApi, errorContext: ErrorContext): void;
}
// @public
export class UrlPatternDiscovery implements DiscoveryApi {
static compile(pattern: string): UrlPatternDiscovery;
// (undocumented)
getBaseUrl(pluginId: string): Promise<string>;
}
static compile(pattern: string): UrlPatternDiscovery;
// (undocumented)
getBaseUrl(pluginId: string): Promise<string>;
}
// @public (undocumented)
export class WebStorage implements StorageApi {
constructor(namespace: string, errorApi: ErrorApi);
// (undocumented)
static create(options: CreateStorageApiOptions): WebStorage;
// (undocumented)
forBucket(name: string): WebStorage;
// (undocumented)
get<T>(key: string): T | undefined;
// (undocumented)
observe$<T>(key: string): Observable<StorageValueChange<T>>;
// (undocumented)
remove(key: string): Promise<void>;
// (undocumented)
set<T>(key: string, data: T): Promise<void>;
}
constructor(namespace: string, errorApi: ErrorApi);
// (undocumented)
static create(options: CreateStorageApiOptions): WebStorage;
// (undocumented)
forBucket(name: string): WebStorage;
// (undocumented)
get<T>(key: string): T | undefined;
// (undocumented)
observe$<T>(key: string): Observable<StorageValueChange<T>>;
// (undocumented)
remove(key: string): Promise<void>;
// (undocumented)
set<T>(key: string, data: T): Promise<void>;
}
// (No @packageDocumentation comment for this package)
```
+13
View File
@@ -1,5 +1,18 @@
# @backstage/core-components
## 0.1.5
### Patch Changes
- a446bffdb: Improve UX of the Sidebar by adding SidebarScrollWrapper component allowing the user to scroll through Plugins & Shortcuts on smaller screens. Prevent the Sidebar from opening on click on small devices
- f11e50ea7: - Enhanced core `Button` component to open external links in new tab.
- Replaced the use of `Button` component from material by `core-components` in tools card.
- 76bb7aeda: Show scroll bar of the sidebar wrapper only on hover
- 2a13aa1b7: Handle empty code blocks in markdown files so they don't fail rendering
- 47748c7e6: Fix error in error panel, and console warnings about DOM nesting pre inside p
- 34352a79c: Add edit button to Group Profile Card
- 612e25fd7: Add custom styles to scroll bar of the sidebar wrapper to fix flaky behaviour
## 0.1.4
### Patch Changes
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-components",
"description": "Core components used by Backstage plugins and apps",
"version": "0.1.4",
"version": "0.1.5",
"private": false,
"publishConfig": {
"access": "public",
+325 -206
View File
@@ -3,6 +3,7 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
/// <reference types="react" />
import { BackstageTheme } from '@backstage/theme';
import { ComponentType } from 'react';
@@ -14,8 +15,8 @@ import { SvgIconProps } from '@material-ui/core';
// @public
export type AlertApi = {
post(alert: AlertMessage): void;
alert$(): Observable<AlertMessage>;
post(alert: AlertMessage): void;
alert$(): Observable<AlertMessage>;
};
// @public (undocumented)
@@ -23,43 +24,53 @@ export const alertApiRef: ApiRef<AlertApi>;
// @public (undocumented)
export type AlertMessage = {
message: string;
severity?: 'success' | 'info' | 'warning' | 'error';
message: string;
severity?: 'success' | 'info' | 'warning' | 'error';
};
// @public (undocumented)
export type AnyApiFactory = ApiFactory<unknown, unknown, {
export type AnyApiFactory = ApiFactory<
unknown,
unknown,
{
[key in string]: unknown;
}>;
}
>;
// @public (undocumented)
export type AnyApiRef = ApiRef<unknown>;
// @public (undocumented)
export type ApiFactory<Api, Impl extends Api, Deps extends {
export type ApiFactory<
Api,
Impl extends Api,
Deps extends {
[name in string]: unknown;
}> = {
api: ApiRef<Api>;
deps: TypesToApiRefs<Deps>;
factory(deps: Deps): Impl;
}
> = {
api: ApiRef<Api>;
deps: TypesToApiRefs<Deps>;
factory(deps: Deps): Impl;
};
// @public (undocumented)
export type ApiHolder = {
get<T>(api: ApiRef<T>): T | undefined;
get<T>(api: ApiRef<T>): T | undefined;
};
// @public (undocumented)
export type ApiRef<T> = {
id: string;
T: T;
id: string;
T: T;
};
// @public (undocumented)
export type ApiRefsToTypes<T extends {
export type ApiRefsToTypes<
T extends {
[key in string]: ApiRef<unknown>;
}> = {
[key in keyof T]: ApiRefType<T[key]>;
}
> = {
[key in keyof T]: ApiRefType<T[key]>;
};
// @public (undocumented)
@@ -67,93 +78,106 @@ export type ApiRefType<T> = T extends ApiRef<infer U> ? U : never;
// @public (undocumented)
export type AppComponents = {
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType<BootErrorPageProps>;
Progress: ComponentType<{}>;
Router: ComponentType<{}>;
ErrorBoundaryFallback: ComponentType<ErrorBoundaryFallbackProps>;
SignInPage?: ComponentType<SignInPageProps>;
NotFoundErrorPage: ComponentType<{}>;
BootErrorPage: ComponentType<BootErrorPageProps>;
Progress: ComponentType<{}>;
Router: ComponentType<{}>;
ErrorBoundaryFallback: ComponentType<ErrorBoundaryFallbackProps>;
SignInPage?: ComponentType<SignInPageProps>;
};
// @public (undocumented)
export type AppContext = {
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
getComponents(): AppComponents;
getPlugins(): BackstagePlugin<any, any>[];
getSystemIcon(key: string): IconComponent | undefined;
getComponents(): AppComponents;
};
// @public
export type AppTheme = {
id: string;
title: string;
variant: 'light' | 'dark';
theme: BackstageTheme;
icon?: React.ReactElement;
id: string;
title: string;
variant: 'light' | 'dark';
theme: BackstageTheme;
icon?: React.ReactElement;
};
// @public
export type AppThemeApi = {
getInstalledThemes(): AppTheme[];
activeThemeId$(): Observable<string | undefined>;
getActiveThemeId(): string | undefined;
setActiveThemeId(themeId?: string): void;
getInstalledThemes(): AppTheme[];
activeThemeId$(): Observable<string | undefined>;
getActiveThemeId(): string | undefined;
setActiveThemeId(themeId?: string): void;
};
// @public (undocumented)
export const appThemeApiRef: ApiRef<AppThemeApi>;
// @public (undocumented)
export function attachComponentData<P>(component: ComponentType<P>, type: string, data: unknown): void;
export function attachComponentData<P>(
component: ComponentType<P>,
type: string,
data: unknown,
): void;
// @public
export const auth0AuthApiRef: ApiRef<OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const auth0AuthApiRef: ApiRef<
OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
>;
// @public
export type AuthProvider = {
title: string;
icon: IconComponent;
title: string;
icon: IconComponent;
};
// @public
export type AuthRequester<AuthResponse> = (scopes: Set<string>) => Promise<AuthResponse>;
export type AuthRequester<AuthResponse> = (
scopes: Set<string>,
) => Promise<AuthResponse>;
// @public
export type AuthRequesterOptions<AuthResponse> = {
provider: AuthProvider;
onAuthRequest(scopes: Set<string>): Promise<AuthResponse>;
provider: AuthProvider;
onAuthRequest(scopes: Set<string>): Promise<AuthResponse>;
};
// @public (undocumented)
export type AuthRequestOptions = {
optional?: boolean;
instantPopup?: boolean;
optional?: boolean;
instantPopup?: boolean;
};
// @public (undocumented)
export type BackstageIdentity = {
id: string;
idToken: string;
id: string;
idToken: string;
};
// @public
export type BackstageIdentityApi = {
getBackstageIdentity(options?: AuthRequestOptions): Promise<BackstageIdentity | undefined>;
getBackstageIdentity(
options?: AuthRequestOptions,
): Promise<BackstageIdentity | undefined>;
};
// @public (undocumented)
export type BackstagePlugin<Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}> = {
getId(): string;
output(): PluginOutput[];
getApis(): Iterable<AnyApiFactory>;
provide<T>(extension: Extension<T>): T;
routes: Routes;
externalRoutes: ExternalRoutes;
export type BackstagePlugin<
Routes extends AnyRoutes = {},
ExternalRoutes extends AnyExternalRoutes = {}
> = {
getId(): string;
output(): PluginOutput[];
getApis(): Iterable<AnyApiFactory>;
provide<T>(extension: Extension<T>): T;
routes: Routes;
externalRoutes: ExternalRoutes;
};
// @public (undocumented)
export type BootErrorPageProps = {
step: 'load-config' | 'load-chunk';
error: Error;
step: 'load-config' | 'load-chunk';
error: Error;
};
// @public
@@ -163,66 +187,89 @@ export type ConfigApi = Config;
export const configApiRef: ApiRef<ConfigApi>;
// @public
export function createApiFactory<Api, Impl extends Api, Deps extends {
export function createApiFactory<
Api,
Impl extends Api,
Deps extends {
[name in string]: unknown;
}>(factory: ApiFactory<Api, Impl, Deps>): ApiFactory<Api, Impl, Deps>;
}
>(factory: ApiFactory<Api, Impl, Deps>): ApiFactory<Api, Impl, Deps>;
// @public (undocumented)
export function createApiFactory<Api, Impl extends Api>(api: ApiRef<Api>, instance: Impl): ApiFactory<Api, Impl, {}>;
export function createApiFactory<Api, Impl extends Api>(
api: ApiRef<Api>,
instance: Impl,
): ApiFactory<Api, Impl, {}>;
// @public (undocumented)
export function createApiRef<T>(config: ApiRefConfig): ApiRef<T>;
// @public (undocumented)
export function createComponentExtension<T extends (props: any) => JSX.Element | null>(options: {
component: ComponentLoader<T>;
}): Extension<T>;
export function createComponentExtension<
T extends (props: any) => JSX.Element | null
>(options: { component: ComponentLoader<T> }): Extension<T>;
// @public (undocumented)
export function createExternalRouteRef<Params extends {
export function createExternalRouteRef<
Params extends {
[param in ParamKey]: string;
}, Optional extends boolean = false, ParamKey extends string = never>(options: {
id: string;
params?: ParamKey[];
optional?: Optional;
},
Optional extends boolean = false,
ParamKey extends string = never
>(options: {
id: string;
params?: ParamKey[];
optional?: Optional;
}): ExternalRouteRef<OptionalParams<Params>, Optional>;
// @public (undocumented)
export function createPlugin<Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}>(config: PluginConfig<Routes, ExternalRoutes>): BackstagePlugin<Routes, ExternalRoutes>;
export function createPlugin<
Routes extends AnyRoutes = {},
ExternalRoutes extends AnyExternalRoutes = {}
>(
config: PluginConfig<Routes, ExternalRoutes>,
): BackstagePlugin<Routes, ExternalRoutes>;
// @public (undocumented)
export function createReactExtension<T extends (props: any) => JSX.Element | null>(options: {
component: ComponentLoader<T>;
data?: Record<string, unknown>;
export function createReactExtension<
T extends (props: any) => JSX.Element | null
>(options: {
component: ComponentLoader<T>;
data?: Record<string, unknown>;
}): Extension<T>;
// @public (undocumented)
export function createRoutableExtension<T extends (props: any) => JSX.Element | null>(options: {
component: () => Promise<T>;
mountPoint: RouteRef;
}): Extension<T>;
export function createRoutableExtension<
T extends (props: any) => JSX.Element | null
>(options: { component: () => Promise<T>; mountPoint: RouteRef }): Extension<T>;
// @public (undocumented)
export function createRouteRef<Params extends {
export function createRouteRef<
Params extends {
[param in ParamKey]: string;
}, ParamKey extends string = never>(config: {
id?: string;
params?: ParamKey[];
path?: string;
icon?: OldIconComponent;
title?: string;
},
ParamKey extends string = never
>(config: {
id?: string;
params?: ParamKey[];
path?: string;
icon?: OldIconComponent;
title?: string;
}): RouteRef<OptionalParams<Params>>;
// @public (undocumented)
export function createSubRouteRef<Path extends string, ParentParams extends AnyParams = never>(config: {
id: string;
path: Path;
parent: RouteRef<ParentParams>;
export function createSubRouteRef<
Path extends string,
ParentParams extends AnyParams = never
>(config: {
id: string;
path: Path;
parent: RouteRef<ParentParams>;
}): MakeSubRouteRef<PathParams<Path>, ParentParams>;
// @public
export type DiscoveryApi = {
getBaseUrl(pluginId: string): Promise<string>;
getBaseUrl(pluginId: string): Promise<string>;
};
// @public (undocumented)
@@ -230,25 +277,25 @@ export const discoveryApiRef: ApiRef<DiscoveryApi>;
// @public
export interface ElementCollection {
findComponentData<T>(query: {
key: string;
}): T[];
getElements<Props extends {
[name: string]: unknown;
}>(): Array<ReactElement<Props>>;
selectByComponentData(query: {
key: string;
withStrictError?: string;
}): ElementCollection;
findComponentData<T>(query: { key: string }): T[];
getElements<
Props extends {
[name: string]: unknown;
}
>(): Array<ReactElement<Props>>;
selectByComponentData(query: {
key: string;
withStrictError?: string;
}): ElementCollection;
}
// @public
export type ErrorApi = {
post(error: Error_2, context?: ErrorContext): void;
error$(): Observable<{
error: Error_2;
context?: ErrorContext;
}>;
post(error: Error_2, context?: ErrorContext): void;
error$(): Observable<{
error: Error_2;
context?: ErrorContext;
}>;
};
// @public (undocumented)
@@ -256,46 +303,49 @@ export const errorApiRef: ApiRef<ErrorApi>;
// @public (undocumented)
export type ErrorBoundaryFallbackProps = {
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
plugin?: BackstagePlugin;
error: Error;
resetError: () => void;
};
// @public
export type ErrorContext = {
hidden?: boolean;
hidden?: boolean;
};
// @public (undocumented)
export type Extension<T> = {
expose(plugin: BackstagePlugin<any, any>): T;
expose(plugin: BackstagePlugin<any, any>): T;
};
// @public (undocumented)
export type ExternalRouteRef<Params extends AnyParams = any, Optional extends boolean = any> = {
readonly [routeRefType]: 'external';
params: ParamKeys<Params>;
optional?: Optional;
export type ExternalRouteRef<
Params extends AnyParams = any,
Optional extends boolean = any
> = {
readonly [routeRefType]: 'external';
params: ParamKeys<Params>;
optional?: Optional;
};
// @public
export type FeatureFlag = {
name: string;
pluginId: string;
name: string;
pluginId: string;
};
// @public (undocumented)
export type FeatureFlagOutput = {
type: 'feature-flag';
name: string;
type: 'feature-flag';
name: string;
};
// @public (undocumented)
export interface FeatureFlagsApi {
getRegisteredFlags(): FeatureFlag[];
isActive(name: string): boolean;
registerFlag(flag: FeatureFlag): void;
save(options: FeatureFlagsSaveOptions): void;
getRegisteredFlags(): FeatureFlag[];
isActive(name: string): boolean;
registerFlag(flag: FeatureFlag): void;
save(options: FeatureFlagsSaveOptions): void;
}
// @public (undocumented)
@@ -303,66 +353,96 @@ export const featureFlagsApiRef: ApiRef<FeatureFlagsApi>;
// @public (undocumented)
export type FeatureFlagsHooks = {
register(name: string): void;
register(name: string): void;
};
// @public
export type FeatureFlagsSaveOptions = {
states: Record<string, FeatureFlagState>;
merge?: boolean;
states: Record<string, FeatureFlagState>;
merge?: boolean;
};
// @public (undocumented)
export enum FeatureFlagState {
// (undocumented)
Active = 1,
// (undocumented)
None = 0
// (undocumented)
Active = 1,
// (undocumented)
None = 0,
}
// @public (undocumented)
export function getComponentData<T>(node: ReactNode, type: string): T | undefined;
export function getComponentData<T>(
node: ReactNode,
type: string,
): T | undefined;
// @public
export const githubAuthApiRef: ApiRef<OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const githubAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
>;
// @public
export const gitlabAuthApiRef: ApiRef<OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const gitlabAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
>;
// @public
export const googleAuthApiRef: ApiRef<OAuthApi & OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const googleAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>;
// @public
export type IconComponent = ComponentType<{
fontSize?: 'default' | 'small' | 'large';
fontSize?: 'default' | 'small' | 'large';
}>;
// @public
export type IdentityApi = {
getUserId(): string;
getProfile(): ProfileInfo;
getIdToken(): Promise<string | undefined>;
signOut(): Promise<void>;
getUserId(): string;
getProfile(): ProfileInfo;
getIdToken(): Promise<string | undefined>;
signOut(): Promise<void>;
};
// @public (undocumented)
export const identityApiRef: ApiRef<IdentityApi>;
// @public
export const microsoftAuthApiRef: ApiRef<OAuthApi & OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const microsoftAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>;
// @public
export const oauth2ApiRef: ApiRef<OAuthApi & OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const oauth2ApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>;
// @public
export type OAuthApi = {
getAccessToken(scope?: OAuthScope, options?: AuthRequestOptions): Promise<string>;
getAccessToken(
scope?: OAuthScope,
options?: AuthRequestOptions,
): Promise<string>;
};
// @public
export type OAuthRequestApi = {
createAuthRequester<AuthResponse>(options: AuthRequesterOptions<AuthResponse>): AuthRequester<AuthResponse>;
authRequest$(): Observable<PendingAuthRequest[]>;
createAuthRequester<AuthResponse>(
options: AuthRequesterOptions<AuthResponse>,
): AuthRequester<AuthResponse>;
authRequest$(): Observable<PendingAuthRequest[]>;
};
// @public (undocumented)
@@ -373,51 +453,76 @@ export type OAuthScope = string | string[];
// @public
export type Observable<T> = {
[Symbol.observable](): Observable<T>;
subscribe(observer: Observer<T>): Subscription;
subscribe(onNext?: (value: T) => void, onError?: (error: Error) => void, onComplete?: () => void): Subscription;
[Symbol.observable](): Observable<T>;
subscribe(observer: Observer<T>): Subscription;
subscribe(
onNext?: (value: T) => void,
onError?: (error: Error) => void,
onComplete?: () => void,
): Subscription;
};
// @public
export type Observer<T> = {
next?(value: T): void;
error?(error: Error): void;
complete?(): void;
next?(value: T): void;
error?(error: Error): void;
complete?(): void;
};
// @public
export const oidcAuthApiRef: ApiRef<OAuthApi & OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const oidcAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>;
// @public
export const oktaAuthApiRef: ApiRef<OAuthApi & OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const oktaAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>;
// @public (undocumented)
export const oneloginAuthApiRef: ApiRef<OAuthApi & OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const oneloginAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>;
// @public
export type OpenIdConnectApi = {
getIdToken(options?: AuthRequestOptions): Promise<string>;
getIdToken(options?: AuthRequestOptions): Promise<string>;
};
// @public
export type PendingAuthRequest = {
provider: AuthProvider;
reject: () => void;
trigger(): Promise<void>;
provider: AuthProvider;
reject: () => void;
trigger(): Promise<void>;
};
// @public (undocumented)
export type PluginConfig<Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes> = {
id: string;
apis?: Iterable<AnyApiFactory>;
register?(hooks: PluginHooks): void;
routes?: Routes;
externalRoutes?: ExternalRoutes;
export type PluginConfig<
Routes extends AnyRoutes,
ExternalRoutes extends AnyExternalRoutes
> = {
id: string;
apis?: Iterable<AnyApiFactory>;
register?(hooks: PluginHooks): void;
routes?: Routes;
externalRoutes?: ExternalRoutes;
};
// @public (undocumented)
export type PluginHooks = {
featureFlags: FeatureFlagsHooks;
featureFlags: FeatureFlagsHooks;
};
// @public (undocumented)
@@ -425,19 +530,19 @@ export type PluginOutput = FeatureFlagOutput;
// @public
export type ProfileInfo = {
email?: string;
displayName?: string;
picture?: string;
email?: string;
displayName?: string;
picture?: string;
};
// @public
export type ProfileInfoApi = {
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
getProfile(options?: AuthRequestOptions): Promise<ProfileInfo | undefined>;
};
// @public (undocumented)
export type RouteOptions = {
exact?: boolean;
exact?: boolean;
};
// @public (undocumented)
@@ -445,51 +550,53 @@ export type RoutePath = string;
// @public (undocumented)
export type RouteRef<Params extends AnyParams = any> = {
readonly [routeRefType]: 'absolute';
params: ParamKeys<Params>;
path: string;
icon?: OldIconComponent;
title?: string;
readonly [routeRefType]: 'absolute';
params: ParamKeys<Params>;
path: string;
icon?: OldIconComponent;
title?: string;
};
// @public
export const samlAuthApiRef: ApiRef<ProfileInfoApi & BackstageIdentityApi & SessionApi>;
export const samlAuthApiRef: ApiRef<
ProfileInfoApi & BackstageIdentityApi & SessionApi
>;
// @public
export type SessionApi = {
signIn(): Promise<void>;
signOut(): Promise<void>;
sessionState$(): Observable<SessionState>;
signIn(): Promise<void>;
signOut(): Promise<void>;
sessionState$(): Observable<SessionState>;
};
// @public
export enum SessionState {
// (undocumented)
SignedIn = "SignedIn",
// (undocumented)
SignedOut = "SignedOut"
// (undocumented)
SignedIn = 'SignedIn',
// (undocumented)
SignedOut = 'SignedOut',
}
// @public (undocumented)
export type SignInPageProps = {
onResult(result: SignInResult): void;
onResult(result: SignInResult): void;
};
// @public (undocumented)
export type SignInResult = {
userId: string;
profile: ProfileInfo;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
userId: string;
profile: ProfileInfo;
getIdToken?: () => Promise<string>;
signOut?: () => Promise<void>;
};
// @public (undocumented)
export interface StorageApi {
forBucket(name: string): StorageApi;
get<T>(key: string): T | undefined;
observe$<T>(key: string): Observable<StorageValueChange<T>>;
remove(key: string): Promise<void>;
set(key: string, data: any): Promise<void>;
forBucket(name: string): StorageApi;
get<T>(key: string): T | undefined;
observe$<T>(key: string): Observable<StorageValueChange<T>>;
remove(key: string): Promise<void>;
set(key: string, data: any): Promise<void>;
}
// @public (undocumented)
@@ -497,27 +604,27 @@ export const storageApiRef: ApiRef<StorageApi>;
// @public (undocumented)
export type StorageValueChange<T = any> = {
key: string;
newValue?: T;
key: string;
newValue?: T;
};
// @public (undocumented)
export type SubRouteRef<Params extends AnyParams = any> = {
readonly [routeRefType]: 'sub';
parent: RouteRef;
path: string;
params: ParamKeys<Params>;
readonly [routeRefType]: 'sub';
parent: RouteRef;
path: string;
params: ParamKeys<Params>;
};
// @public
export type Subscription = {
unsubscribe(): void;
readonly closed: boolean;
unsubscribe(): void;
readonly closed: boolean;
};
// @public (undocumented)
export type TypesToApiRefs<T> = {
[key in keyof T]: ApiRef<T[key]>;
[key in keyof T]: ApiRef<T[key]>;
};
// @public (undocumented)
@@ -530,27 +637,39 @@ export function useApiHolder(): ApiHolder;
export const useApp: () => AppContext;
// @public
export function useElementFilter<T>(node: ReactNode, filterFn: (arg: ElementCollection) => T, dependencies?: any[]): T;
export function useElementFilter<T>(
node: ReactNode,
filterFn: (arg: ElementCollection) => T,
dependencies?: any[],
): T;
// @public (undocumented)
export type UserFlags = {};
// @public (undocumented)
export function useRouteRef<Optional extends boolean, Params extends AnyParams>(routeRef: ExternalRouteRef<Params, Optional>): Optional extends true ? RouteFunc<Params> | undefined : RouteFunc<Params>;
export function useRouteRef<Optional extends boolean, Params extends AnyParams>(
routeRef: ExternalRouteRef<Params, Optional>,
): Optional extends true ? RouteFunc<Params> | undefined : RouteFunc<Params>;
// @public (undocumented)
export function useRouteRef<Params extends AnyParams>(routeRef: RouteRef<Params> | SubRouteRef<Params>): RouteFunc<Params>;
export function useRouteRef<Params extends AnyParams>(
routeRef: RouteRef<Params> | SubRouteRef<Params>,
): RouteFunc<Params>;
// @public (undocumented)
export function useRouteRefParams<Params extends AnyParams>(_routeRef: RouteRef<Params> | SubRouteRef<Params>): Params;
export function useRouteRefParams<Params extends AnyParams>(
_routeRef: RouteRef<Params> | SubRouteRef<Params>,
): Params;
// @public (undocumented)
export function withApis<T>(apis: TypesToApiRefs<T>): <P extends T>(WrappedComponent: React_2.ComponentType<P>) => {
(props: React_2.PropsWithChildren<Omit<P, keyof T>>): JSX.Element;
displayName: string;
export function withApis<T>(
apis: TypesToApiRefs<T>,
): <P extends T>(
WrappedComponent: React_2.ComponentType<P>,
) => {
(props: React_2.PropsWithChildren<Omit<P, keyof T>>): JSX.Element;
displayName: string;
};
// (No @packageDocumentation comment for this package)
```
+68
View File
@@ -1,5 +1,73 @@
# @backstage/create-app
## 0.3.30
### Patch Changes
- 60e830222: Support for `Template` kinds with version `backstage.io/v1alpha1` has now been removed. This means that the old method of running templates with `Preparers`, `Templaters` and `Publishers` has also been removed. If you had any logic in these abstractions, they should now be moved to `actions` instead, and you can find out more about those in the [documentation](https://backstage.io/docs/features/software-templates/writing-custom-actions)
If you need any help migrating existing templates, there's a [migration guide](https://backstage.io/docs/features/software-templates/migrating-from-v1alpha1-to-v1beta2). Reach out to us on Discord in the #support channel if you're having problems.
The `scaffolder-backend` now no longer requires these `Preparers`, `Templaters`, and `Publishers` to be passed in, now all it needs is the `containerRunner`.
Please update your `packages/backend/src/plugins/scaffolder.ts` like the following
```diff
- import {
- DockerContainerRunner,
- SingleHostDiscovery,
- } from '@backstage/backend-common';
+ import { DockerContainerRunner } from '@backstage/backend-common';
import { CatalogClient } from '@backstage/catalog-client';
- import {
- CookieCutter,
- CreateReactAppTemplater,
- createRouter,
- Preparers,
- Publishers,
- Templaters,
- } from '@backstage/plugin-scaffolder-backend';
+ import { createRouter } from '@backstage/plugin-scaffolder-backend';
import Docker from 'dockerode';
import { Router } from 'express';
import type { PluginEnvironment } from '../types';
export default async function createPlugin({
config,
database,
reader,
+ discovery,
}: PluginEnvironment): Promise<Router> {
const dockerClient = new Docker();
const containerRunner = new DockerContainerRunner({ dockerClient });
- const cookiecutterTemplater = new CookieCutter({ containerRunner });
- const craTemplater = new CreateReactAppTemplater({ containerRunner });
- const templaters = new Templaters();
- templaters.register('cookiecutter', cookiecutterTemplater);
- templaters.register('cra', craTemplater);
-
- const preparers = await Preparers.fromConfig(config, { logger });
- const publishers = await Publishers.fromConfig(config, { logger });
- const discovery = SingleHostDiscovery.fromConfig(config);
const catalogClient = new CatalogClient({ discoveryApi: discovery });
return await createRouter({
- preparers,
- templaters,
- publishers,
+ containerRunner,
logger,
config,
database,
```
- f7134c368: bump sqlite3 to 5.0.1
- e4244f94b: Use SidebarScrollWrapper to improve responsiveness of the current sidebar. Change: Wrap a section of SidebarItems with this component to enable scroll for smaller screens. It can also be used in sidebar plugins (see shortcuts plugin for an example).
## 0.3.29
### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/create-app",
"description": "Create app package for Backstage",
"version": "0.3.29",
"version": "0.3.30",
"private": false,
"publishConfig": {
"access": "public"
@@ -30,7 +30,7 @@
"@backstage/cli-common": "^0.1.2",
"chalk": "^4.0.0",
"commander": "^6.1.0",
"fs-extra": "^10.0.0",
"fs-extra": "9.1.0",
"handlebars": "^4.7.3",
"inquirer": "^7.0.4",
"ora": "^5.3.0",
+9
View File
@@ -1,5 +1,14 @@
# @backstage/dev-utils
## 0.2.1
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.1.5
- @backstage/catalog-model@0.9.0
- @backstage/plugin-catalog-react@0.2.6
## 0.2.0
### Minor Changes
+7 -4
View File
@@ -3,6 +3,7 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
/// <reference types="react" />
import { ApiFactory } from '@backstage/core-plugin-api';
import { ComponentType } from 'react';
@@ -16,11 +17,13 @@ import { ReactNode } from 'react';
export function createDevApp(): DevAppBuilder;
// @public (undocumented)
export const EntityGridItem: ({ entity, classes, ...rest }: Omit<GridProps<"div", {}>, "container" | "item"> & {
entity: Entity;
export const EntityGridItem: ({
entity,
classes,
...rest
}: Omit<GridProps<'div', {}>, 'container' | 'item'> & {
entity: Entity;
}) => JSX.Element;
// (No @packageDocumentation comment for this package)
```

Some files were not shown because too many files have changed in this diff Show More