Merge branch 'backstage:master' into master
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Renamed `RootHttpRouterConfigureOptions` to `RootHttpRouterConfigureContext`, and removed the unused type `ServiceOrExtensionPoint`.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-playlist-backend': patch
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Minor improvements to the descriptions provided with permission rules schemas
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Removed the unused `TypesToServiceRef` type
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-react': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
scaffolder/next: Implementing a simple `OngoingTask` page
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend-module-incremental-ingestion': patch
|
||||
---
|
||||
|
||||
Removing extra imports for `run` script as `TestBackend` auto loads the default factories
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
---
|
||||
|
||||
Updated the `mockServices.rootLogger` options to accept a single level option instead.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-vault': patch
|
||||
---
|
||||
|
||||
Surface additional context and details to the Backstage UI when the Vault plugin encounters non-successful HTTP responses from the Vault API.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Updates to match new `BackendFeature` type.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-scaffolder-react': patch
|
||||
---
|
||||
|
||||
bump `@rjsf` `v5` dependencies to 5.1.0
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
'@backstage/plugin-techdocs-node': patch
|
||||
'@techdocs/cli': patch
|
||||
---
|
||||
|
||||
Added support for using a default `mkdocs.yml` configuration file when none is provided
|
||||
+68
-1
@@ -195,82 +195,149 @@
|
||||
"@backstage/plugin-vault": "0.1.8",
|
||||
"@backstage/plugin-vault-backend": "0.2.6",
|
||||
"@backstage/plugin-xcmetrics": "0.2.34",
|
||||
"@backstage/plugin-scaffolder-node": "0.0.0"
|
||||
"@backstage/plugin-scaffolder-node": "0.0.0",
|
||||
"@backstage/backend-dev-utils": "0.0.0",
|
||||
"@backstage/eslint-plugin": "0.0.0",
|
||||
"@backstage/plugin-entity-validation": "0.0.0",
|
||||
"@backstage/plugin-graphql-voyager": "0.0.0",
|
||||
"@backstage/plugin-lighthouse-backend": "0.0.0",
|
||||
"@backstage/plugin-lighthouse-common": "0.0.0"
|
||||
},
|
||||
"changesets": [
|
||||
"afraid-foxes-provide",
|
||||
"afraid-planets-crash",
|
||||
"brave-cougars-burn",
|
||||
"breezy-ears-rule",
|
||||
"bright-eagles-love",
|
||||
"bright-plums-cough",
|
||||
"bright-teachers-compete",
|
||||
"brown-islands-own",
|
||||
"calm-avocados-exercise",
|
||||
"chatty-owls-care",
|
||||
"chilled-sheep-collect",
|
||||
"clean-queens-judge",
|
||||
"cold-cycles-switch",
|
||||
"cool-spoons-bathe",
|
||||
"create-app-1674561612",
|
||||
"cuddly-boxes-agree",
|
||||
"cyan-deers-walk",
|
||||
"dry-donkeys-cheer",
|
||||
"dull-fishes-suffer",
|
||||
"dull-gorillas-sing",
|
||||
"eight-falcons-explode",
|
||||
"eight-hotels-sparkle",
|
||||
"eight-vans-drum",
|
||||
"eleven-shoes-crash",
|
||||
"few-moons-accept",
|
||||
"flat-cups-itch",
|
||||
"four-candles-add",
|
||||
"four-rivers-enjoy",
|
||||
"four-tables-fix",
|
||||
"friendly-chefs-rule",
|
||||
"friendly-scissors-shop",
|
||||
"gold-bulldogs-talk",
|
||||
"gold-lemons-eat",
|
||||
"gold-masks-sleep",
|
||||
"great-goats-talk",
|
||||
"green-adults-retire",
|
||||
"green-guests-flow",
|
||||
"grumpy-bottles-stare",
|
||||
"grumpy-fireants-drop",
|
||||
"happy-cows-moo",
|
||||
"hip-chairs-double",
|
||||
"hip-onions-tan",
|
||||
"hip-pugs-teach",
|
||||
"hip-tables-prove",
|
||||
"hot-lions-cover",
|
||||
"hot-wasps-cover",
|
||||
"hungry-news-fix",
|
||||
"itchy-chairs-punch",
|
||||
"itchy-goats-melt",
|
||||
"khaki-toes-care",
|
||||
"late-rice-crash",
|
||||
"lazy-badgers-rule",
|
||||
"lazy-badgers-try",
|
||||
"lemon-tables-train",
|
||||
"little-jars-lay",
|
||||
"long-chefs-burn",
|
||||
"lovely-ladybugs-taste",
|
||||
"many-nails-joke",
|
||||
"many-pans-unite",
|
||||
"mean-squids-kneel",
|
||||
"modern-cats-worry",
|
||||
"nasty-beans-accept",
|
||||
"neat-schools-raise",
|
||||
"neat-zebras-run",
|
||||
"nervous-apricots-whisper",
|
||||
"nervous-mangos-rhyme",
|
||||
"nervous-phones-shout",
|
||||
"new-pumpkins-sleep",
|
||||
"nine-glasses-invent",
|
||||
"nine-guests-compete",
|
||||
"nine-ravens-kiss",
|
||||
"ninety-hats-serve",
|
||||
"old-knives-wonder",
|
||||
"old-ways-know",
|
||||
"perfect-cheetahs-serve",
|
||||
"pink-falcons-serve",
|
||||
"poor-moons-confess",
|
||||
"popular-dancers-join",
|
||||
"pretty-ladybugs-taste",
|
||||
"proud-glasses-live",
|
||||
"purple-feet-smile",
|
||||
"quick-ladybugs-reply",
|
||||
"quick-mice-change",
|
||||
"rare-berries-give",
|
||||
"rare-melons-battle",
|
||||
"red-kiwis-compare",
|
||||
"renovate-0b349f9",
|
||||
"renovate-0c3644c",
|
||||
"renovate-53e8b07",
|
||||
"rich-snakes-rest",
|
||||
"rotten-mayflies-love",
|
||||
"selfish-frogs-punch",
|
||||
"serious-pigs-watch",
|
||||
"sharp-lobsters-build",
|
||||
"shiny-years-tap",
|
||||
"short-apes-relate",
|
||||
"shy-buses-mix",
|
||||
"shy-steaks-invite",
|
||||
"silent-peas-fly",
|
||||
"silly-buckets-joke",
|
||||
"silly-socks-lie",
|
||||
"silly-turkeys-hang",
|
||||
"silver-wolves-breathe",
|
||||
"slow-carrots-sniff",
|
||||
"slow-moles-sin",
|
||||
"smart-dingos-raise",
|
||||
"soft-actors-worry",
|
||||
"soft-boxes-buy",
|
||||
"soft-snails-notice",
|
||||
"spotty-coats-clean",
|
||||
"stale-dots-smile",
|
||||
"stale-experts-punch",
|
||||
"stupid-ladybugs-brake",
|
||||
"swift-fishes-smash",
|
||||
"tall-falcons-teach",
|
||||
"tall-tables-hide",
|
||||
"tall-years-relate",
|
||||
"tasty-jobs-help",
|
||||
"thick-clocks-pump",
|
||||
"thick-tables-travel",
|
||||
"thin-donkeys-attack",
|
||||
"thin-scissors-press",
|
||||
"tough-jeans-camp",
|
||||
"twenty-islands-wonder",
|
||||
"twenty-parents-relate",
|
||||
"two-melons-lie",
|
||||
"violet-tips-rhyme",
|
||||
"weak-radios-sing",
|
||||
"wicked-beers-walk",
|
||||
"wild-donkeys-rescue",
|
||||
"witty-moose-itch",
|
||||
"yellow-roses-tell",
|
||||
"young-beans-float",
|
||||
"young-points-drop",
|
||||
"young-singers-learn"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
Use the new `*ServiceFactory` exports from `@backstage/backend-app-api`
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Updated usage of `ServiceFactory`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': minor
|
||||
---
|
||||
|
||||
**BREAKING**: Switched out `LogMeta` type for `JsonObject`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': minor
|
||||
---
|
||||
|
||||
**BREAKING** Renaming `*Factory` exports to `*ServiceFactory` instead. For example `configFactory` now is exported as `configServiceFactory`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-react': minor
|
||||
---
|
||||
|
||||
refactor `createAsyncValidators` to be recursive to ensure validators are called in nested schemas.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Moved the options of the `config` and `rootHttpRouter` services out to the factories themselves, where they belong
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-entity-validation': minor
|
||||
---
|
||||
|
||||
First implementation for the entity validation UI. For more information refer to its `README.md`.
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-module-addons-contrib': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Create a TechDocs `<LightBox/>` addon that allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page.
|
||||
|
||||
Here's an example on how to use it in a Backstage app:
|
||||
|
||||
```diff
|
||||
import {
|
||||
DefaultTechDocsHome,
|
||||
TechDocsIndexPage,
|
||||
TechDocsReaderPage,
|
||||
} from '@backstage/plugin-techdocs';
|
||||
import { TechDocsAddons } from '@backstage/plugin-techdocs-react/alpha';
|
||||
+import { LightBox } from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
|
||||
const AppRoutes = () => {
|
||||
<FlatRoutes>
|
||||
// other plugin routes
|
||||
<Route path="/docs" element={<TechDocsIndexPage />}>
|
||||
<DefaultTechDocsHome />
|
||||
</Route>
|
||||
<Route
|
||||
path="/docs/:namespace/:kind/:name/*"
|
||||
element={<TechDocsReaderPage />}
|
||||
>
|
||||
<TechDocsAddons>
|
||||
+ <LightBox />
|
||||
</TechDocsAddons>
|
||||
</Route>
|
||||
</FlatRoutes>;
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-app-api': minor
|
||||
---
|
||||
|
||||
**BREAKING** `HttpServerCertificateOptions` when specified with a `key` and `cert` should also have the `type: 'pem'` instead of `type: 'plain'`
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
---
|
||||
|
||||
Fix bug in EntityCostsCard if cost aggregation array is empty. Allow title override on the Cost Insights Page
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/backend-test-utils': patch
|
||||
'@backstage/backend-app-api': patch
|
||||
---
|
||||
|
||||
Updated usages of `LogMeta`.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': minor
|
||||
---
|
||||
|
||||
Switch `ServiceFactory` to be an opaque type, keeping only the `service` field as public API, but also adding a type parameter for the service scope.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-plugin-api': minor
|
||||
---
|
||||
|
||||
Switched `BackendFeature` to be an opaque type.
|
||||
@@ -18,12 +18,12 @@ jobs:
|
||||
if: github.repository == 'backstage/backstage' && ( github.event.pull_request || github.event.issue.pull_request )
|
||||
steps:
|
||||
- name: PR sync
|
||||
uses: backstage/actions/pr-sync@v0.6.0
|
||||
uses: backstage/actions/pr-sync@v0.6.1
|
||||
with:
|
||||
github-token: ${{ secrets.GH_SERVICE_ACCOUNT_TOKEN }}
|
||||
app-id: ${{ secrets.BACKSTAGE_GOALIE_APPLICATION_ID }}
|
||||
private-key: ${{ secrets.BACKSTAGE_GOALIE_PRIVATE_KEY }}
|
||||
installation-id: ${{ secrets.BACKSTAGE_GOALIE_INSTALLATION_ID }}
|
||||
project-id: PVT_kwDOBFKqdc02LQ
|
||||
excluded-users: ${{ secrets.OOO_USERS }}
|
||||
auto-assign: false
|
||||
owning-teams: '@backstage/techdocs-core'
|
||||
|
||||
@@ -61,7 +61,7 @@ class DefaultFooService implements FooService {
|
||||
}
|
||||
}
|
||||
|
||||
export const fooFactory = createServiceFactory({
|
||||
export const fooServiceFactory = createServiceFactory({
|
||||
service: fooServiceRef,
|
||||
deps: { bar: barServiceRef },
|
||||
factory({ bar }) {
|
||||
@@ -75,7 +75,7 @@ To create a service factory we need to provide a reference to the `service` for
|
||||
If you need the creation of the service instance to be asynchronous, you can make the `factory` function async. For example:
|
||||
|
||||
```ts
|
||||
export const fooFactory = createServiceFactory({
|
||||
export const fooServiceFactory = createServiceFactory({
|
||||
service: fooServiceRef,
|
||||
deps: {},
|
||||
async factory() {
|
||||
@@ -94,18 +94,18 @@ To install a service factory in a backend instance, we pass it in through the `s
|
||||
|
||||
```ts
|
||||
const backend = createBackend({
|
||||
services: [fooFactory()],
|
||||
services: [fooServiceFactory()],
|
||||
});
|
||||
```
|
||||
|
||||
Note that we call `fooFactory` to create the service factory instance. This is because `createServiceFactory` always returns a factory function that creates the actual service factory. This is done to always allow for options to be added to the service factory in the future, without breaking existing code. To add options to your service factory, you wrap the object passed to `createServiceFactory` in a callback that accepts the desired options. For example:
|
||||
Note that we call `fooServiceFactory` to create the service factory instance. This is because `createServiceFactory` always returns a factory function that creates the actual service factory. This is done to always allow for options to be added to the service factory in the future, without breaking existing code. To add options to your service factory, you wrap the object passed to `createServiceFactory` in a callback that accepts the desired options. For example:
|
||||
|
||||
```ts
|
||||
export interface FooFactoryOptions {
|
||||
mode: 'eager' | 'lazy';
|
||||
}
|
||||
|
||||
export const fooFactory = createServiceFactory(
|
||||
export const fooServiceFactory = createServiceFactory(
|
||||
(options?: FooFactoryOptions) => ({
|
||||
service: fooServiceRef,
|
||||
deps: { bar: barServiceRef },
|
||||
@@ -120,7 +120,7 @@ This lets us use the options to customize the factory implementation in any way
|
||||
|
||||
```ts
|
||||
const backend = createBackend({
|
||||
services: [fooFactory({ mode: 'eager' })],
|
||||
services: [fooServiceFactory({ mode: 'eager' })],
|
||||
});
|
||||
```
|
||||
|
||||
@@ -164,7 +164,7 @@ Plugin scoped services have access to a plugin metadata service, which is a spec
|
||||
The plugin metadata service is the base for all plugin specific customizations for services. For example, the default implementation of the plugin scoped logger service uses the plugin metadata service to attach the plugin ID as a field in all log messages:
|
||||
|
||||
```ts
|
||||
export const loggerFactory = createServiceFactory({
|
||||
export const loggerServiceFactory = createServiceFactory({
|
||||
service: coreServices.logger,
|
||||
deps: {
|
||||
rootLogger: coreServices.rootLogger,
|
||||
@@ -183,7 +183,7 @@ Some services may benefit from having a context that is shared across all instan
|
||||
The root context is defined as part of the service factory by passing the `createRootContext` option:
|
||||
|
||||
```ts
|
||||
export const fooFactory = createServiceFactory({
|
||||
export const fooServiceFactory = createServiceFactory({
|
||||
service: fooServiceRef,
|
||||
deps: { rootLogger: coreServices.rootLogger, bar: barServiceRef },
|
||||
createRootContext({ rootLogger }) {
|
||||
|
||||
@@ -66,12 +66,12 @@ export const catalogProcessingExtensionPoint = createExtensionPoint<CatalogProce
|
||||
|
||||
### Services
|
||||
|
||||
| Description | Pattern | Examples |
|
||||
| ----------- | ------------------- | -------------------------------------------------- |
|
||||
| Interface | `<Name>Service` | `LoggerService`, `DatabaseService` |
|
||||
| Reference | `<name>ServiceRef` | `loggerServiceRef`, `databaseServiceRef` |
|
||||
| ID | `<pluginId>.<name>` | `'core.rootHttpRouter'`, `'catalog.catalogClient'` |
|
||||
| Factory | `<name>Factory` | `loggerFactory`, `databaseFactory` |
|
||||
| Description | Pattern | Examples |
|
||||
| ----------- | ---------------------- | -------------------------------------------------- |
|
||||
| Interface | `<Name>Service` | `LoggerService`, `DatabaseService` |
|
||||
| Reference | `<name>ServiceRef` | `loggerServiceRef`, `databaseServiceRef` |
|
||||
| ID | `<pluginId>.<name>` | `'core.rootHttpRouter'`, `'catalog.catalogClient'` |
|
||||
| Factory | `<name>ServiceFactory` | `loggerServiceFactory`, `databaseServiceFactory` |
|
||||
|
||||
Example:
|
||||
|
||||
@@ -85,7 +85,7 @@ export const catalogClientServiceRef = createServiceRef<CatalogClientService>({
|
||||
...
|
||||
})
|
||||
|
||||
export const catalogClientFactory = createServiceFactory({
|
||||
export const catalogClientServiceFactory = createServiceFactory({
|
||||
service: catalogClientServiceRef,
|
||||
...
|
||||
})
|
||||
|
||||
@@ -61,11 +61,11 @@ All of these services can be replaced with your own implementations if you need
|
||||
For example, let's say we want to customize the core configuration service to enable remote configuration loading. That would look something like this:
|
||||
|
||||
```ts
|
||||
import { configFactory } from '@backstage/backend-app-api';
|
||||
import { configServiceFactory } from '@backstage/backend-app-api';
|
||||
|
||||
const backend = createBackend({
|
||||
services: [
|
||||
configFactory({
|
||||
configServiceFactory({
|
||||
remote: { reloadIntervalSeconds: 60 },
|
||||
}),
|
||||
],
|
||||
@@ -160,11 +160,11 @@ A shared environment is defined using `createSharedEnvironment`. In this example
|
||||
```ts
|
||||
// packages/backend-env/src/index.ts
|
||||
import { createSharedEnvironment } from '@backstage/backend-plugin-api';
|
||||
import { customDiscoveryFactory } from './customDiscoveryFactory';
|
||||
import { customDiscoveryServiceFactory } from './customDiscoveryServiceFactory';
|
||||
|
||||
export const env = createSharedEnvironment({
|
||||
services: [
|
||||
customDiscoveryFactory(), // custom DiscoveryService implementation
|
||||
customDiscoveryServiceFactory(), // custom DiscoveryService implementation
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
@@ -59,11 +59,11 @@ There's additional configuration that you can optionally pass to setup the `http
|
||||
You can configure these additional options by adding an override for the core service when calling `createBackend` like follows:
|
||||
|
||||
```ts
|
||||
import { httpRouterFactory } from '@backstage/backend-app-api';
|
||||
import { httpRouterServiceFactory } from '@backstage/backend-app-api';
|
||||
|
||||
const backend = createBackend({
|
||||
services: [
|
||||
httpRouterFactory({
|
||||
httpRouterServiceFactory({
|
||||
getPath: (pluginId: string) => `/plugins/${pluginId}`,
|
||||
}),
|
||||
],
|
||||
@@ -116,11 +116,11 @@ There's additional options that you can pass to configure the root HTTP Router s
|
||||
You can configure the root HTTP Router service by passing the options to the `createBackend` function.
|
||||
|
||||
```ts
|
||||
import { rootHttpRouterFactory } from '@backstage/backend-app-api';
|
||||
import { rootHttpRouterServiceFactory } from '@backstage/backend-app-api';
|
||||
|
||||
const backend = createBackend({
|
||||
services: [
|
||||
rootHttpRouterFactory({
|
||||
rootHttpRouterServiceFactory({
|
||||
configure: ({ app, middleware, routes, config, logger, lifecycle }) => {
|
||||
// the built in middleware is provided through an option in the configure function
|
||||
app.use(middleware.helmet());
|
||||
@@ -183,11 +183,11 @@ There's additional configuration that you can optionally pass to setup the `conf
|
||||
You can configure these additional options by adding an override for the core service when calling `createBackend` like follows:
|
||||
|
||||
```ts
|
||||
import { configFactory } from '@backstage/backend-app-api';
|
||||
import { configServiceFactory } from '@backstage/backend-app-api';
|
||||
|
||||
const backend = createBackend({
|
||||
services: [
|
||||
configFactory({
|
||||
configServiceFactory({
|
||||
argv: [
|
||||
'--config',
|
||||
'/backstage/app-config.development.yaml',
|
||||
@@ -438,11 +438,11 @@ There's additional configuration that you can optionally pass to setup the `iden
|
||||
You can configure these additional options by adding an override for the core service when calling `createBackend` like follows:
|
||||
|
||||
```ts
|
||||
import { identityFactory } from '@backstage/backend-app-api';
|
||||
import { identityServiceFactory } from '@backstage/backend-app-api';
|
||||
|
||||
const backend = createBackend({
|
||||
services: [
|
||||
identityFactory({
|
||||
identityServiceFactory({
|
||||
issuer: 'backstage',
|
||||
algorithms: ['ES256', 'RS256'],
|
||||
}),
|
||||
|
||||
@@ -125,6 +125,7 @@ discover available Addons, we've compiled a list of them here:
|
||||
| [`<ExpandableNavigation />`](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.expandablenavigation) | `@backstage/plugin-techdocs-module-addons-contrib` | Allows TechDocs users to expand or collapse the entire TechDocs main navigation, and keeps the user's preferred state between documentation sites. |
|
||||
| [`<ReportIssue />`](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.reportissue) | `@backstage/plugin-techdocs-module-addons-contrib` | Allows TechDocs users to select a portion of text on a TechDocs page and open an issue against the repository that contains the documentation, populating the issue description with the selected text according to a configurable template. |
|
||||
| [`<TextSize />`](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.textsize) | `@backstage/plugin-techdocs-module-addons-contrib` | This TechDocs addon allows users to customize text size on documentation pages, they can select how much they want to increase or decrease the font size via slider or buttons. The default value for font size is 100% and this setting is kept in the browser's local storage whenever it is changed. |
|
||||
| [`<LightBox />`](https://backstage.io/docs/reference/plugin-techdocs-module-addons-contrib.lightbox) | `@backstage/plugin-techdocs-module-addons-contrib` | This TechDocs addon allows users to open images in a light-box on documentation pages, they can navigate between images if there are several on one page. The image size of the light-box image is the same as the image size on the document page. |
|
||||
|
||||
Got an Addon to contribute? Feel free to add a row above!
|
||||
|
||||
|
||||
@@ -262,12 +262,12 @@ You will have to install the `mkdocs` and `mkdocs-techdocs-core` package from
|
||||
pip, as well as `graphviz` and `plantuml` from your OS package manager (e.g.
|
||||
apt).
|
||||
|
||||
You can do so by including the following lines in the last step of your
|
||||
You can do so by including the following lines right above `USER node` of your
|
||||
`Dockerfile`:
|
||||
|
||||
```Dockerfile
|
||||
RUN apt-get update && apt-get install -y python3 python3-pip
|
||||
RUN pip3 install mkdocs-techdocs-core==1.0.1
|
||||
RUN pip3 install mkdocs-techdocs-core==1.1.7
|
||||
```
|
||||
|
||||
Please be aware that the version requirement could change, you need to check our
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8361,11 +8361,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:^2.6.2":
|
||||
version: 2.8.2
|
||||
resolution: "prettier@npm:2.8.2"
|
||||
version: 2.8.4
|
||||
resolution: "prettier@npm:2.8.4"
|
||||
bin:
|
||||
prettier: bin-prettier.js
|
||||
checksum: 740c56c2128d587d656ea1dde9bc9c3503dfc94db4f3ac387259215eeb2e216680bdad9d18a0c9feecc6b42cfa188d6fa777df4c36c1d00cedd4199074fbfbd2
|
||||
checksum: c173064bf3df57b6d93d19aa98753b9b9dd7657212e33b41ada8e2e9f9884066bb9ca0b4005b89b3ab137efffdf8fbe0b462785aba20364798ff4303aadda57e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
+3
-3
@@ -7369,11 +7369,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:^2.6.2":
|
||||
version: 2.8.2
|
||||
resolution: "prettier@npm:2.8.2"
|
||||
version: 2.8.4
|
||||
resolution: "prettier@npm:2.8.4"
|
||||
bin:
|
||||
prettier: bin-prettier.js
|
||||
checksum: 740c56c2128d587d656ea1dde9bc9c3503dfc94db4f3ac387259215eeb2e216680bdad9d18a0c9feecc6b42cfa188d6fa777df4c36c1d00cedd4199074fbfbd2
|
||||
checksum: c173064bf3df57b6d93d19aa98753b9b9dd7657212e33b41ada8e2e9f9884066bb9ca0b4005b89b3ab137efffdf8fbe0b462785aba20364798ff4303aadda57e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@
|
||||
"@types/react": "^17",
|
||||
"@types/react-dom": "^17"
|
||||
},
|
||||
"version": "1.11.0-next.1",
|
||||
"version": "1.11.0-next.2",
|
||||
"dependencies": {
|
||||
"@backstage/errors": "workspace:^",
|
||||
"@manypkg/get-packages": "^1.1.3"
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# @backstage/app-defaults
|
||||
|
||||
## 1.1.1-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/core-components@0.12.4-next.1
|
||||
- @backstage/core-app-api@1.4.1-next.0
|
||||
- @backstage/core-plugin-api@1.3.0
|
||||
- @backstage/theme@0.2.16
|
||||
- @backstage/plugin-permission-react@0.4.9
|
||||
|
||||
## 1.1.1-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/app-defaults",
|
||||
"description": "Provides the default wiring of a Backstage App",
|
||||
"version": "1.1.1-next.0",
|
||||
"version": "1.1.1-next.1",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.esm.js",
|
||||
|
||||
@@ -1,5 +1,69 @@
|
||||
# example-app
|
||||
|
||||
## 0.2.80-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-scaffolder-react@1.1.0-next.2
|
||||
- @backstage/plugin-scaffolder@1.11.0-next.2
|
||||
- @backstage/cli@0.22.2-next.1
|
||||
- @backstage/plugin-api-docs@0.9.0-next.2
|
||||
- @backstage/plugin-tech-radar@0.6.1-next.1
|
||||
- @backstage/catalog-model@1.2.0-next.1
|
||||
- @backstage/plugin-techdocs@1.5.0-next.2
|
||||
- @backstage/plugin-explore@0.4.0-next.2
|
||||
- @backstage/plugin-search-react@1.5.0-next.1
|
||||
- @backstage/plugin-sentry@0.5.0-next.2
|
||||
- @backstage/plugin-circleci@0.3.15-next.2
|
||||
- @backstage/core-components@0.12.4-next.1
|
||||
- @backstage/plugin-azure-sites@0.1.4-next.2
|
||||
- @backstage/plugin-search@1.1.0-next.2
|
||||
- @backstage/plugin-lighthouse@0.4.0-next.2
|
||||
- @backstage/app-defaults@1.1.1-next.1
|
||||
- @backstage/config@1.0.6
|
||||
- @backstage/core-app-api@1.4.1-next.0
|
||||
- @backstage/core-plugin-api@1.3.0
|
||||
- @backstage/integration-react@1.1.10-next.1
|
||||
- @backstage/theme@0.2.16
|
||||
- @backstage/plugin-airbrake@0.3.15-next.2
|
||||
- @backstage/plugin-apache-airflow@0.2.8-next.1
|
||||
- @backstage/plugin-azure-devops@0.2.6-next.2
|
||||
- @backstage/plugin-badges@0.2.39-next.2
|
||||
- @backstage/plugin-catalog-common@1.0.11-next.1
|
||||
- @backstage/plugin-catalog-graph@0.2.27-next.2
|
||||
- @backstage/plugin-catalog-import@0.9.5-next.2
|
||||
- @backstage/plugin-catalog-react@1.3.0-next.2
|
||||
- @backstage/plugin-cloudbuild@0.3.15-next.2
|
||||
- @backstage/plugin-code-coverage@0.2.8-next.2
|
||||
- @backstage/plugin-cost-insights@0.12.4-next.2
|
||||
- @backstage/plugin-dynatrace@2.0.0-next.2
|
||||
- @backstage/plugin-gcalendar@0.3.11-next.1
|
||||
- @backstage/plugin-gcp-projects@0.3.34-next.1
|
||||
- @backstage/plugin-github-actions@0.5.15-next.2
|
||||
- @backstage/plugin-gocd@0.1.21-next.2
|
||||
- @backstage/plugin-graphiql@0.2.47-next.1
|
||||
- @backstage/plugin-home@0.4.31-next.2
|
||||
- @backstage/plugin-jenkins@0.7.14-next.2
|
||||
- @backstage/plugin-kafka@0.3.15-next.2
|
||||
- @backstage/plugin-kubernetes@0.7.8-next.2
|
||||
- @backstage/plugin-newrelic@0.3.33-next.1
|
||||
- @backstage/plugin-newrelic-dashboard@0.2.8-next.2
|
||||
- @backstage/plugin-org@0.6.5-next.2
|
||||
- @backstage/plugin-pagerduty@0.5.8-next.2
|
||||
- @backstage/plugin-permission-react@0.4.9
|
||||
- @backstage/plugin-playlist@0.1.6-next.2
|
||||
- @backstage/plugin-rollbar@0.4.15-next.2
|
||||
- @backstage/plugin-search-common@1.2.1
|
||||
- @backstage/plugin-shortcuts@0.3.7-next.1
|
||||
- @backstage/plugin-stack-overflow@0.1.11-next.2
|
||||
- @backstage/plugin-tech-insights@0.3.7-next.2
|
||||
- @backstage/plugin-techdocs-module-addons-contrib@1.0.10-next.2
|
||||
- @backstage/plugin-techdocs-react@1.1.3-next.2
|
||||
- @backstage/plugin-todo@0.2.17-next.2
|
||||
- @backstage/plugin-user-settings@0.6.3-next.2
|
||||
- @internal/plugin-catalog-customized@0.0.7-next.2
|
||||
|
||||
## 0.2.80-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.80-next.1",
|
||||
"version": "0.2.80-next.2",
|
||||
"private": true,
|
||||
"backstage": {
|
||||
"role": "frontend"
|
||||
|
||||
@@ -78,6 +78,7 @@ import {
|
||||
ExpandableNavigation,
|
||||
ReportIssue,
|
||||
TextSize,
|
||||
LightBox,
|
||||
} from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
import {
|
||||
SettingsLayout,
|
||||
@@ -203,6 +204,7 @@ const routes = (
|
||||
<ExpandableNavigation />
|
||||
<ReportIssue />
|
||||
<TextSize />
|
||||
<LightBox />
|
||||
</TechDocsAddons>
|
||||
</Route>
|
||||
<Route
|
||||
|
||||
@@ -154,6 +154,7 @@ import { TechDocsAddons } from '@backstage/plugin-techdocs-react';
|
||||
import {
|
||||
TextSize,
|
||||
ReportIssue,
|
||||
LightBox,
|
||||
} from '@backstage/plugin-techdocs-module-addons-contrib';
|
||||
import { EntityCostInsightsContent } from '@backstage/plugin-cost-insights';
|
||||
|
||||
@@ -205,6 +206,7 @@ const techdocsContent = (
|
||||
<TechDocsAddons>
|
||||
<TextSize />
|
||||
<ReportIssue />
|
||||
<LightBox />
|
||||
</TechDocsAddons>
|
||||
</EntityTechdocsContent>
|
||||
);
|
||||
|
||||
@@ -68,7 +68,7 @@ export const LowerCaseValuePickerFieldExtension = scaffolderPlugin.provide(
|
||||
const MockDelayComponent = (
|
||||
props: NextFieldExtensionComponentProps<{ test?: string }>,
|
||||
) => {
|
||||
const { onChange, formData, rawErrors } = props;
|
||||
const { onChange, formData, rawErrors = [] } = props;
|
||||
return (
|
||||
<TextField
|
||||
label="test"
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# @backstage/backend-app-api
|
||||
|
||||
## 0.4.0-next.2
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 01a075ec1d: **BREAKING**: Renamed `RootHttpRouterConfigureOptions` to `RootHttpRouterConfigureContext`, and removed the unused type `ServiceOrExtensionPoint`.
|
||||
- 4ae71b7f2e: **BREAKING** Renaming `*Factory` exports to `*ServiceFactory` instead. For example `configFactory` now is exported as `configServiceFactory`.
|
||||
- d31d8e00b3: **BREAKING** `HttpServerCertificateOptions` when specified with a `key` and `cert` should also have the `type: 'pem'` instead of `type: 'plain'`
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e716946103: Updated usage of the lifecycle service.
|
||||
- f60cca9da1: Updated database factory to pass service deps required for restoring database state during development.
|
||||
- 610d65e143: Updates to match new `BackendFeature` type.
|
||||
- ab22515647: The shutdown signal handlers are now installed as part of the backend instance rather than the lifecycle service, and explicitly cause the process to exit.
|
||||
- b729f9f31f: Moved the options of the `config` and `rootHttpRouter` services out to the factories themselves, where they belong
|
||||
- 71a5ec0f06: Updated usages of `LogMeta`.
|
||||
- Updated dependencies
|
||||
- @backstage/backend-plugin-api@0.4.0-next.2
|
||||
- @backstage/backend-common@0.18.2-next.2
|
||||
- @backstage/backend-tasks@0.4.3-next.2
|
||||
- @backstage/plugin-auth-node@0.2.11-next.2
|
||||
- @backstage/plugin-permission-node@0.7.5-next.2
|
||||
- @backstage/cli-common@0.1.11
|
||||
- @backstage/config@1.0.6
|
||||
- @backstage/config-loader@1.1.8
|
||||
- @backstage/errors@1.1.4
|
||||
- @backstage/types@1.0.2
|
||||
|
||||
## 0.3.2-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -11,17 +11,16 @@ import { ConfigService } from '@backstage/backend-plugin-api';
|
||||
import { CorsOptions } from 'cors';
|
||||
import { ErrorRequestHandler } from 'express';
|
||||
import { Express as Express_2 } from 'express';
|
||||
import { ExtensionPoint } from '@backstage/backend-plugin-api';
|
||||
import { Format } from 'logform';
|
||||
import { Handler } from 'express';
|
||||
import { HelmetOptions } from 'helmet';
|
||||
import * as http from 'http';
|
||||
import { HttpRouterService } from '@backstage/backend-plugin-api';
|
||||
import { IdentityService } from '@backstage/backend-plugin-api';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { LifecycleService } from '@backstage/backend-plugin-api';
|
||||
import { LoadConfigOptionsRemote } from '@backstage/config-loader';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { LogMeta } from '@backstage/backend-plugin-api';
|
||||
import { PermissionsService } from '@backstage/backend-plugin-api';
|
||||
import { PluginCacheManager } from '@backstage/backend-common';
|
||||
import { PluginDatabaseManager } from '@backstage/backend-common';
|
||||
@@ -34,7 +33,6 @@ import { RootLoggerService } from '@backstage/backend-plugin-api';
|
||||
import { SchedulerService } from '@backstage/backend-plugin-api';
|
||||
import { ServiceFactory } from '@backstage/backend-plugin-api';
|
||||
import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api';
|
||||
import { ServiceRef } from '@backstage/backend-plugin-api';
|
||||
import { TokenManagerService } from '@backstage/backend-plugin-api';
|
||||
import { transport } from 'winston';
|
||||
import { UrlReader } from '@backstage/backend-common';
|
||||
@@ -50,10 +48,10 @@ export interface Backend {
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const cacheFactory: () => ServiceFactory<PluginCacheManager>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const configFactory: () => ServiceFactory<ConfigService>;
|
||||
export const cacheServiceFactory: () => ServiceFactory<
|
||||
PluginCacheManager,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface ConfigFactoryOptions {
|
||||
@@ -61,6 +59,11 @@ export interface ConfigFactoryOptions {
|
||||
remote?: LoadConfigOptionsRemote;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const configServiceFactory: (
|
||||
options?: ConfigFactoryOptions | undefined,
|
||||
) => ServiceFactory<ConfigService, 'root'>;
|
||||
|
||||
// @public (undocumented)
|
||||
export function createConfigSecretEnumerator(options: {
|
||||
logger: LoggerService;
|
||||
@@ -88,7 +91,10 @@ export interface CreateSpecializedBackendOptions {
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const databaseFactory: () => ServiceFactory<PluginDatabaseManager>;
|
||||
export const databaseServiceFactory: () => ServiceFactory<
|
||||
PluginDatabaseManager,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public
|
||||
export class DefaultRootHttpRouter implements RootHttpRouterService {
|
||||
@@ -106,7 +112,10 @@ export interface DefaultRootHttpRouterOptions {
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const discoveryFactory: () => ServiceFactory<PluginEndpointDiscovery>;
|
||||
export const discoveryServiceFactory: () => ServiceFactory<
|
||||
PluginEndpointDiscovery,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public
|
||||
export interface ExtendedHttpServer extends http.Server {
|
||||
@@ -118,20 +127,20 @@ export interface ExtendedHttpServer extends http.Server {
|
||||
stop(): Promise<void>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const httpRouterFactory: (
|
||||
options?: HttpRouterFactoryOptions | undefined,
|
||||
) => ServiceFactory<HttpRouterService>;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface HttpRouterFactoryOptions {
|
||||
getPath?(pluginId: string): string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const httpRouterServiceFactory: (
|
||||
options?: HttpRouterFactoryOptions | undefined,
|
||||
) => ServiceFactory<HttpRouterService, 'plugin'>;
|
||||
|
||||
// @public
|
||||
export type HttpServerCertificateOptions =
|
||||
| {
|
||||
type: 'plain';
|
||||
type: 'pem';
|
||||
key: string;
|
||||
cert: string;
|
||||
}
|
||||
@@ -151,19 +160,22 @@ export type HttpServerOptions = {
|
||||
};
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const identityFactory: (
|
||||
options?: IdentityFactoryOptions | undefined,
|
||||
) => ServiceFactory<IdentityService>;
|
||||
|
||||
// @public
|
||||
export type IdentityFactoryOptions = {
|
||||
issuer?: string;
|
||||
algorithms?: string[];
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const identityServiceFactory: (
|
||||
options?: IdentityFactoryOptions | undefined,
|
||||
) => ServiceFactory<IdentityService, 'plugin'>;
|
||||
|
||||
// @public
|
||||
export const lifecycleFactory: () => ServiceFactory<LifecycleService>;
|
||||
export const lifecycleServiceFactory: () => ServiceFactory<
|
||||
LifecycleService,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public
|
||||
export function loadBackendConfig(options: {
|
||||
@@ -174,7 +186,10 @@ export function loadBackendConfig(options: {
|
||||
}>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const loggerFactory: () => ServiceFactory<LoggerService>;
|
||||
export const loggerServiceFactory: () => ServiceFactory<
|
||||
LoggerService,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public
|
||||
export class MiddlewareFactory {
|
||||
@@ -202,7 +217,10 @@ export interface MiddlewareFactoryOptions {
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const permissionsFactory: () => ServiceFactory<PermissionsService>;
|
||||
export const permissionsServiceFactory: () => ServiceFactory<
|
||||
PermissionsService,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public
|
||||
export function readCorsOptions(config?: Config): CorsOptions;
|
||||
@@ -214,7 +232,7 @@ export function readHelmetOptions(config?: Config): HelmetOptions;
|
||||
export function readHttpServerOptions(config?: Config): HttpServerOptions;
|
||||
|
||||
// @public (undocumented)
|
||||
export interface RootHttpRouterConfigureOptions {
|
||||
export interface RootHttpRouterConfigureContext {
|
||||
// (undocumented)
|
||||
app: Express_2;
|
||||
// (undocumented)
|
||||
@@ -229,55 +247,64 @@ export interface RootHttpRouterConfigureOptions {
|
||||
routes: RequestHandler;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const rootHttpRouterFactory: () => ServiceFactory<RootHttpRouterService>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type RootHttpRouterFactoryOptions = {
|
||||
indexPath?: string | false;
|
||||
configure?(options: RootHttpRouterConfigureOptions): void;
|
||||
configure?(context: RootHttpRouterConfigureContext): void;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const rootHttpRouterServiceFactory: (
|
||||
options?: RootHttpRouterFactoryOptions | undefined,
|
||||
) => ServiceFactory<RootHttpRouterService, 'root'>;
|
||||
|
||||
// @public
|
||||
export const rootLifecycleFactory: () => ServiceFactory<RootLifecycleService>;
|
||||
export const rootLifecycleServiceFactory: () => ServiceFactory<
|
||||
RootLifecycleService,
|
||||
'root'
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const rootLoggerFactory: () => ServiceFactory<RootLoggerService>;
|
||||
export const rootLoggerServiceFactory: () => ServiceFactory<
|
||||
RootLoggerService,
|
||||
'root'
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const schedulerFactory: () => ServiceFactory<SchedulerService>;
|
||||
export const schedulerServiceFactory: () => ServiceFactory<
|
||||
SchedulerService,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export type ServiceOrExtensionPoint<T = unknown> =
|
||||
| ExtensionPoint<T>
|
||||
| ServiceRef<T>;
|
||||
export const tokenManagerServiceFactory: () => ServiceFactory<
|
||||
TokenManagerService,
|
||||
'plugin'
|
||||
>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const tokenManagerFactory: () => ServiceFactory<TokenManagerService>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const urlReaderFactory: () => ServiceFactory<UrlReader>;
|
||||
export const urlReaderServiceFactory: () => ServiceFactory<UrlReader, 'plugin'>;
|
||||
|
||||
// @public
|
||||
export class WinstonLogger implements RootLoggerService {
|
||||
// (undocumented)
|
||||
addRedactions(redactions: Iterable<string>): void;
|
||||
// (undocumented)
|
||||
child(meta: LogMeta): LoggerService;
|
||||
child(meta: JsonObject): LoggerService;
|
||||
static colorFormat(): Format;
|
||||
static create(options: WinstonLoggerOptions): WinstonLogger;
|
||||
// (undocumented)
|
||||
debug(message: string, meta?: LogMeta): void;
|
||||
debug(message: string, meta?: JsonObject): void;
|
||||
// (undocumented)
|
||||
error(message: string, meta?: LogMeta): void;
|
||||
error(message: string, meta?: JsonObject): void;
|
||||
// (undocumented)
|
||||
info(message: string, meta?: LogMeta): void;
|
||||
info(message: string, meta?: JsonObject): void;
|
||||
static redacter(): {
|
||||
format: Format;
|
||||
add: (redactions: Iterable<string>) => void;
|
||||
};
|
||||
// (undocumented)
|
||||
warn(message: string, meta?: LogMeta): void;
|
||||
warn(message: string, meta?: JsonObject): void;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -287,7 +314,7 @@ export interface WinstonLoggerOptions {
|
||||
// (undocumented)
|
||||
level: string;
|
||||
// (undocumented)
|
||||
meta?: LogMeta;
|
||||
meta?: JsonObject;
|
||||
// (undocumented)
|
||||
transports: transport[];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-app-api",
|
||||
"description": "Core API used by Backstage backend apps",
|
||||
"version": "0.3.2-next.1",
|
||||
"version": "0.4.0-next.2",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('readHttpServerOptions', () => {
|
||||
{
|
||||
listen: { host: '', port: 7007 },
|
||||
https: {
|
||||
certificate: { type: 'plain', cert: 'my-cert', key: 'my-key' },
|
||||
certificate: { type: 'pem', cert: 'my-cert', key: 'my-key' },
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -93,7 +93,7 @@ function readHttpsOptions(config?: Config): HttpServerOptions['https'] {
|
||||
|
||||
return {
|
||||
certificate: {
|
||||
type: 'plain',
|
||||
type: 'pem',
|
||||
cert: cc.getString('certificate.cert'),
|
||||
key: cc.getString('certificate.key'),
|
||||
},
|
||||
|
||||
@@ -51,7 +51,7 @@ export type HttpServerOptions = {
|
||||
*/
|
||||
export type HttpServerCertificateOptions =
|
||||
| {
|
||||
type: 'plain';
|
||||
type: 'pem';
|
||||
key: string;
|
||||
cert: string;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
|
||||
import {
|
||||
LoggerService,
|
||||
LogMeta,
|
||||
RootLoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { Format, TransformableInfo } from 'logform';
|
||||
import {
|
||||
Logger,
|
||||
@@ -33,7 +33,7 @@ import { escapeRegExp } from '../lib/escapeRegExp';
|
||||
* @public
|
||||
*/
|
||||
export interface WinstonLoggerOptions {
|
||||
meta?: LogMeta;
|
||||
meta?: JsonObject;
|
||||
level: string;
|
||||
format: Format;
|
||||
transports: Transport[];
|
||||
@@ -150,23 +150,23 @@ export class WinstonLogger implements RootLoggerService {
|
||||
this.#addRedactions = addRedactions;
|
||||
}
|
||||
|
||||
error(message: string, meta?: LogMeta): void {
|
||||
error(message: string, meta?: JsonObject): void {
|
||||
this.#winston.error(message, meta);
|
||||
}
|
||||
|
||||
warn(message: string, meta?: LogMeta): void {
|
||||
warn(message: string, meta?: JsonObject): void {
|
||||
this.#winston.warn(message, meta);
|
||||
}
|
||||
|
||||
info(message: string, meta?: LogMeta): void {
|
||||
info(message: string, meta?: JsonObject): void {
|
||||
this.#winston.info(message, meta);
|
||||
}
|
||||
|
||||
debug(message: string, meta?: LogMeta): void {
|
||||
debug(message: string, meta?: JsonObject): void {
|
||||
this.#winston.debug(message, meta);
|
||||
}
|
||||
|
||||
child(meta: LogMeta): LoggerService {
|
||||
child(meta: JsonObject): LoggerService {
|
||||
return new WinstonLogger(this.#winston.child(meta));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import {
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const cacheFactory = createServiceFactory({
|
||||
export const cacheServiceFactory = createServiceFactory({
|
||||
service: coreServices.cache,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { cacheFactory } from './cacheFactory';
|
||||
export { cacheServiceFactory } from './cacheServiceFactory';
|
||||
|
||||
+11
-10
@@ -35,13 +35,14 @@ export interface ConfigFactoryOptions {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const configFactory = createServiceFactory({
|
||||
service: coreServices.config,
|
||||
deps: {},
|
||||
async factory({}, options?: ConfigFactoryOptions) {
|
||||
const { argv = process.argv, remote } = options ?? {};
|
||||
|
||||
const { config } = await loadBackendConfig({ argv, remote });
|
||||
return config;
|
||||
},
|
||||
});
|
||||
export const configServiceFactory = createServiceFactory(
|
||||
(options?: ConfigFactoryOptions) => ({
|
||||
service: coreServices.config,
|
||||
deps: {},
|
||||
async factory({}) {
|
||||
const { argv = process.argv, remote } = options ?? {};
|
||||
const { config } = await loadBackendConfig({ argv, remote });
|
||||
return config;
|
||||
},
|
||||
}),
|
||||
);
|
||||
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { configFactory } from './configFactory';
|
||||
export type { ConfigFactoryOptions } from './configFactory';
|
||||
export { configServiceFactory } from './configServiceFactory';
|
||||
export type { ConfigFactoryOptions } from './configServiceFactory';
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ import {
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
|
||||
/** @public */
|
||||
export const databaseFactory = createServiceFactory({
|
||||
export const databaseServiceFactory = createServiceFactory({
|
||||
service: coreServices.database,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { databaseFactory } from './databaseFactory';
|
||||
export { databaseServiceFactory } from './databaseServiceFactory';
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import {
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const discoveryFactory = createServiceFactory({
|
||||
export const discoveryServiceFactory = createServiceFactory({
|
||||
service: coreServices.discovery,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { discoveryFactory } from './discoveryFactory';
|
||||
export { discoveryServiceFactory } from './discoveryServiceFactory';
|
||||
|
||||
+4
-11
@@ -14,19 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
HttpRouterService,
|
||||
ServiceFactory,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { httpRouterFactory } from './httpRouterFactory';
|
||||
import { httpRouterServiceFactory } from './httpRouterServiceFactory';
|
||||
|
||||
describe('httpRouterFactory', () => {
|
||||
it('should register plugin paths', async () => {
|
||||
const rootHttpRouter = { use: jest.fn() };
|
||||
const factory = httpRouterFactory() as Exclude<
|
||||
ServiceFactory<HttpRouterService>,
|
||||
{ scope: 'root' }
|
||||
>;
|
||||
const factory = httpRouterServiceFactory() as any;
|
||||
|
||||
const handler1 = () => {};
|
||||
const router1 = await factory.factory(
|
||||
@@ -55,9 +48,9 @@ describe('httpRouterFactory', () => {
|
||||
|
||||
it('should use custom path generator', async () => {
|
||||
const rootHttpRouter = { use: jest.fn() };
|
||||
const factory = httpRouterFactory({
|
||||
const factory = httpRouterServiceFactory({
|
||||
getPath: id => `/some/${id}/path`,
|
||||
}) as Exclude<ServiceFactory<HttpRouterService>, { scope: 'root' }>;
|
||||
}) as any;
|
||||
|
||||
const handler1 = () => {};
|
||||
const router1 = await factory.factory(
|
||||
+1
-1
@@ -31,7 +31,7 @@ export interface HttpRouterFactoryOptions {
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const httpRouterFactory = createServiceFactory(
|
||||
export const httpRouterServiceFactory = createServiceFactory(
|
||||
(options?: HttpRouterFactoryOptions) => ({
|
||||
service: coreServices.httpRouter,
|
||||
deps: {
|
||||
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { httpRouterFactory } from './httpRouterFactory';
|
||||
export type { HttpRouterFactoryOptions } from './httpRouterFactory';
|
||||
export { httpRouterServiceFactory } from './httpRouterServiceFactory';
|
||||
export type { HttpRouterFactoryOptions } from './httpRouterServiceFactory';
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ export type IdentityFactoryOptions = {
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const identityFactory = createServiceFactory(
|
||||
export const identityServiceFactory = createServiceFactory(
|
||||
(options?: IdentityFactoryOptions) => ({
|
||||
service: coreServices.identity,
|
||||
deps: {
|
||||
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { identityFactory } from './identityFactory';
|
||||
export type { IdentityFactoryOptions } from './identityFactory';
|
||||
export { identityServiceFactory } from './identityServiceFactory';
|
||||
export type { IdentityFactoryOptions } from './identityServiceFactory';
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { lifecycleFactory } from './lifecycleFactory';
|
||||
export { lifecycleServiceFactory } from './lifecycleServiceFactory';
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ import {
|
||||
* Allows plugins to register shutdown hooks that are run when the process is about to exit.
|
||||
* @public
|
||||
*/
|
||||
export const lifecycleFactory = createServiceFactory({
|
||||
export const lifecycleServiceFactory = createServiceFactory({
|
||||
service: coreServices.lifecycle,
|
||||
deps: {
|
||||
logger: coreServices.logger,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { loggerFactory } from './loggerFactory';
|
||||
export { loggerServiceFactory } from './loggerServiceFactory';
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ import {
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const loggerFactory = createServiceFactory({
|
||||
export const loggerServiceFactory = createServiceFactory({
|
||||
service: coreServices.logger,
|
||||
deps: {
|
||||
rootLogger: coreServices.rootLogger,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { permissionsFactory } from './permissionsFactory';
|
||||
export { permissionsServiceFactory } from './permissionsServiceFactory';
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import {
|
||||
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
||||
|
||||
/** @public */
|
||||
export const permissionsFactory = createServiceFactory({
|
||||
export const permissionsServiceFactory = createServiceFactory({
|
||||
service: coreServices.permissions,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
@@ -15,10 +15,10 @@
|
||||
*/
|
||||
|
||||
export {
|
||||
rootHttpRouterFactory,
|
||||
rootHttpRouterServiceFactory,
|
||||
type RootHttpRouterFactoryOptions,
|
||||
type RootHttpRouterConfigureOptions,
|
||||
} from './rootHttpRouterFactory';
|
||||
type RootHttpRouterConfigureContext,
|
||||
} from './rootHttpRouterServiceFactory';
|
||||
export {
|
||||
DefaultRootHttpRouter,
|
||||
type DefaultRootHttpRouterOptions,
|
||||
|
||||
+37
-43
@@ -32,7 +32,7 @@ import { DefaultRootHttpRouter } from './DefaultRootHttpRouter';
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface RootHttpRouterConfigureOptions {
|
||||
export interface RootHttpRouterConfigureContext {
|
||||
app: Express;
|
||||
middleware: MiddlewareFactory;
|
||||
routes: RequestHandler;
|
||||
@@ -51,14 +51,11 @@ export type RootHttpRouterFactoryOptions = {
|
||||
*/
|
||||
indexPath?: string | false;
|
||||
|
||||
configure?(options: RootHttpRouterConfigureOptions): void;
|
||||
configure?(context: RootHttpRouterConfigureContext): void;
|
||||
};
|
||||
|
||||
function defaultConfigure({
|
||||
app,
|
||||
routes,
|
||||
middleware,
|
||||
}: RootHttpRouterConfigureOptions) {
|
||||
function defaultConfigure(context: RootHttpRouterConfigureContext) {
|
||||
const { app, routes, middleware } = context;
|
||||
app.use(middleware.helmet());
|
||||
app.use(middleware.cors());
|
||||
app.use(middleware.compression());
|
||||
@@ -69,45 +66,42 @@ function defaultConfigure({
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export const rootHttpRouterFactory = createServiceFactory({
|
||||
service: coreServices.rootHttpRouter,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
rootLogger: coreServices.rootLogger,
|
||||
lifecycle: coreServices.rootLifecycle,
|
||||
},
|
||||
async factory(
|
||||
{ config, rootLogger, lifecycle },
|
||||
{
|
||||
indexPath,
|
||||
configure = defaultConfigure,
|
||||
}: RootHttpRouterFactoryOptions = {},
|
||||
) {
|
||||
const logger = rootLogger.child({ service: 'rootHttpRouter' });
|
||||
const app = express();
|
||||
export const rootHttpRouterServiceFactory = createServiceFactory(
|
||||
(options?: RootHttpRouterFactoryOptions) => ({
|
||||
service: coreServices.rootHttpRouter,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
rootLogger: coreServices.rootLogger,
|
||||
lifecycle: coreServices.rootLifecycle,
|
||||
},
|
||||
async factory({ config, rootLogger, lifecycle }) {
|
||||
const { indexPath, configure = defaultConfigure } = options ?? {};
|
||||
const logger = rootLogger.child({ service: 'rootHttpRouter' });
|
||||
const app = express();
|
||||
|
||||
const router = DefaultRootHttpRouter.create({ indexPath });
|
||||
const middleware = MiddlewareFactory.create({ config, logger });
|
||||
const router = DefaultRootHttpRouter.create({ indexPath });
|
||||
const middleware = MiddlewareFactory.create({ config, logger });
|
||||
|
||||
configure({
|
||||
app,
|
||||
routes: router.handler(),
|
||||
middleware,
|
||||
config,
|
||||
logger,
|
||||
lifecycle,
|
||||
});
|
||||
configure({
|
||||
app,
|
||||
routes: router.handler(),
|
||||
middleware,
|
||||
config,
|
||||
logger,
|
||||
lifecycle,
|
||||
});
|
||||
|
||||
const server = await createHttpServer(
|
||||
app,
|
||||
readHttpServerOptions(config.getOptionalConfig('backend')),
|
||||
{ logger },
|
||||
);
|
||||
const server = await createHttpServer(
|
||||
app,
|
||||
readHttpServerOptions(config.getOptionalConfig('backend')),
|
||||
{ logger },
|
||||
);
|
||||
|
||||
lifecycle.addShutdownHook(() => server.stop());
|
||||
lifecycle.addShutdownHook(() => server.stop());
|
||||
|
||||
await server.start();
|
||||
await server.start();
|
||||
|
||||
return router;
|
||||
},
|
||||
});
|
||||
return router;
|
||||
},
|
||||
}),
|
||||
);
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { rootLifecycleFactory } from './rootLifecycleFactory';
|
||||
export { rootLifecycleServiceFactory } from './rootLifecycleServiceFactory';
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { getVoidLogger } from '@backstage/backend-common';
|
||||
import { BackendLifecycleImpl } from './rootLifecycleFactory';
|
||||
import { BackendLifecycleImpl } from './rootLifecycleServiceFactory';
|
||||
|
||||
describe('lifecycleService', () => {
|
||||
it('should execute registered shutdown hook', async () => {
|
||||
+1
-1
@@ -65,7 +65,7 @@ export class BackendLifecycleImpl implements RootLifecycleService {
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const rootLifecycleFactory = createServiceFactory({
|
||||
export const rootLifecycleServiceFactory = createServiceFactory({
|
||||
service: coreServices.rootLifecycle,
|
||||
deps: {
|
||||
logger: coreServices.rootLogger,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { rootLoggerFactory } from './rootLoggerFactory';
|
||||
export { rootLoggerServiceFactory } from './rootLoggerServiceFactory';
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import { transports, format } from 'winston';
|
||||
import { createConfigSecretEnumerator } from '../../../config';
|
||||
|
||||
/** @public */
|
||||
export const rootLoggerFactory = createServiceFactory({
|
||||
export const rootLoggerServiceFactory = createServiceFactory({
|
||||
service: coreServices.rootLogger,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { schedulerFactory } from './schedulerFactory';
|
||||
export { schedulerServiceFactory } from './schedulerServiceFactory';
|
||||
|
||||
+2
-2
@@ -19,13 +19,13 @@ import {
|
||||
createBackendPlugin,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
import { schedulerFactory } from './schedulerFactory';
|
||||
import { schedulerServiceFactory } from './schedulerServiceFactory';
|
||||
|
||||
describe('schedulerFactory', () => {
|
||||
it('creates sidecar database features', async () => {
|
||||
expect.assertions(3);
|
||||
|
||||
const subject = schedulerFactory();
|
||||
const subject = schedulerServiceFactory();
|
||||
|
||||
const plugin = createBackendPlugin({
|
||||
pluginId: 'example',
|
||||
+1
-1
@@ -22,7 +22,7 @@ import {
|
||||
import { TaskScheduler } from '@backstage/backend-tasks';
|
||||
|
||||
/** @public */
|
||||
export const schedulerFactory = createServiceFactory({
|
||||
export const schedulerServiceFactory = createServiceFactory({
|
||||
service: coreServices.scheduler,
|
||||
deps: {
|
||||
plugin: coreServices.pluginMetadata,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { tokenManagerFactory } from './tokenManagerFactory';
|
||||
export { tokenManagerServiceFactory } from './tokenManagerServiceFactory';
|
||||
|
||||
+3
-10
@@ -14,22 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
LoggerService,
|
||||
ServiceFactory,
|
||||
TokenManagerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { tokenManagerFactory } from './tokenManagerFactory';
|
||||
import { tokenManagerServiceFactory } from './tokenManagerServiceFactory';
|
||||
|
||||
describe('tokenManagerFactory', () => {
|
||||
it('should create managers that can share tokens in development', async () => {
|
||||
(process.env as { NODE_ENV?: string }).NODE_ENV = 'development';
|
||||
|
||||
const factory = tokenManagerFactory() as Exclude<
|
||||
ServiceFactory<TokenManagerService>,
|
||||
{ scope: 'root' }
|
||||
>;
|
||||
const factory = tokenManagerServiceFactory() as any;
|
||||
const deps = {
|
||||
config: new ConfigReader({}),
|
||||
logger: { warn() {} } as unknown as LoggerService,
|
||||
+1
-1
@@ -21,7 +21,7 @@ import {
|
||||
import { ServerTokenManager } from '@backstage/backend-common';
|
||||
|
||||
/** @public */
|
||||
export const tokenManagerFactory = createServiceFactory({
|
||||
export const tokenManagerServiceFactory = createServiceFactory({
|
||||
service: coreServices.tokenManager,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { urlReaderFactory } from './urlReaderFactory';
|
||||
export { urlReaderServiceFactory } from './urlReaderServiceFactory';
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import {
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const urlReaderFactory = createServiceFactory({
|
||||
export const urlReaderServiceFactory = createServiceFactory({
|
||||
service: coreServices.urlReader,
|
||||
deps: {
|
||||
config: coreServices.config,
|
||||
@@ -20,16 +20,19 @@ import {
|
||||
coreServices,
|
||||
ServiceRef,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { BackendLifecycleImpl } from '../services/implementations/rootLifecycle/rootLifecycleFactory';
|
||||
import { BackendLifecycleImpl } from '../services/implementations/rootLifecycle/rootLifecycleServiceFactory';
|
||||
import {
|
||||
BackendRegisterInit,
|
||||
EnumerableServiceHolder,
|
||||
ServiceOrExtensionPoint,
|
||||
} from './types';
|
||||
// Direct internal import to avoid duplication
|
||||
// eslint-disable-next-line @backstage/no-forbidden-package-imports
|
||||
import { InternalBackendFeature } from '@backstage/backend-plugin-api/src/wiring/types';
|
||||
|
||||
export class BackendInitializer {
|
||||
#startPromise?: Promise<void>;
|
||||
#features = new Map<BackendFeature, unknown>();
|
||||
#features = new Array<InternalBackendFeature>();
|
||||
#registerInits = new Array<BackendRegisterInit>();
|
||||
#extensionPoints = new Map<ExtensionPoint<unknown>, unknown>();
|
||||
#serviceHolder: EnumerableServiceHolder;
|
||||
@@ -74,11 +77,22 @@ export class BackendInitializer {
|
||||
return Object.fromEntries(result);
|
||||
}
|
||||
|
||||
add<TOptions>(feature: BackendFeature, options?: TOptions) {
|
||||
add(feature: BackendFeature) {
|
||||
if (this.#startPromise) {
|
||||
throw new Error('feature can not be added after the backend has started');
|
||||
}
|
||||
this.#features.set(feature, options);
|
||||
if (feature.$$type !== '@backstage/BackendFeature') {
|
||||
throw new Error(
|
||||
`Failed to add feature, invalid type '${feature.$$type}'`,
|
||||
);
|
||||
}
|
||||
const internalFeature = feature as InternalBackendFeature;
|
||||
if (internalFeature.version !== 'v1') {
|
||||
throw new Error(
|
||||
`Failed to add feature, invalid version '${internalFeature.version}'`,
|
||||
);
|
||||
}
|
||||
this.#features.push(internalFeature);
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
@@ -117,50 +131,39 @@ export class BackendInitializer {
|
||||
}
|
||||
|
||||
// Initialize all features
|
||||
for (const [feature] of this.#features) {
|
||||
const provides = new Set<ExtensionPoint<unknown>>();
|
||||
for (const feature of this.#features) {
|
||||
for (const r of feature.getRegistrations()) {
|
||||
const provides = new Set<ExtensionPoint<unknown>>();
|
||||
|
||||
let registerInit: BackendRegisterInit | undefined = undefined;
|
||||
if (r.type === 'plugin') {
|
||||
for (const [extRef, extImpl] of r.extensionPoints) {
|
||||
if (this.#extensionPoints.has(extRef)) {
|
||||
throw new Error(
|
||||
`ExtensionPoint with ID '${extRef.id}' is already registered`,
|
||||
);
|
||||
}
|
||||
this.#extensionPoints.set(extRef, extImpl);
|
||||
provides.add(extRef);
|
||||
}
|
||||
}
|
||||
|
||||
feature.register({
|
||||
registerExtensionPoint: (extensionPointRef, impl) => {
|
||||
if (registerInit) {
|
||||
throw new Error('registerExtensionPoint called after registerInit');
|
||||
}
|
||||
if (this.#extensionPoints.has(extensionPointRef)) {
|
||||
throw new Error(`API ${extensionPointRef.id} already registered`);
|
||||
}
|
||||
this.#extensionPoints.set(extensionPointRef, impl);
|
||||
provides.add(extensionPointRef);
|
||||
},
|
||||
registerInit: registerOptions => {
|
||||
if (registerInit) {
|
||||
throw new Error('registerInit must only be called once');
|
||||
}
|
||||
registerInit = {
|
||||
id: feature.id,
|
||||
provides,
|
||||
consumes: new Set(Object.values(registerOptions.deps)),
|
||||
deps: registerOptions.deps,
|
||||
init: registerOptions.init as BackendRegisterInit['init'],
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
if (!registerInit) {
|
||||
throw new Error(
|
||||
`registerInit was not called by register in ${feature.id}`,
|
||||
);
|
||||
this.#registerInits.push({
|
||||
id: r.type === 'plugin' ? r.pluginId : `${r.pluginId}.${r.moduleId}`,
|
||||
provides,
|
||||
consumes: new Set(Object.values(r.init.deps)),
|
||||
init: r.init,
|
||||
});
|
||||
}
|
||||
|
||||
this.#registerInits.push(registerInit);
|
||||
}
|
||||
|
||||
const orderedRegisterResults = this.#resolveInitOrder(this.#registerInits);
|
||||
|
||||
for (const registerInit of orderedRegisterResults) {
|
||||
const deps = await this.#getInitDeps(registerInit.deps, registerInit.id);
|
||||
await registerInit.init(deps);
|
||||
const deps = await this.#getInitDeps(
|
||||
registerInit.init.deps,
|
||||
registerInit.id,
|
||||
);
|
||||
await registerInit.init.func(deps);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,36 +18,66 @@ import {
|
||||
ServiceFactory,
|
||||
ServiceRef,
|
||||
coreServices,
|
||||
createServiceFactory,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { stringifyError } from '@backstage/errors';
|
||||
import { EnumerableServiceHolder } from './types';
|
||||
// Direct internal import to avoid duplication
|
||||
// eslint-disable-next-line @backstage/no-forbidden-package-imports
|
||||
import { InternalServiceFactory } from '@backstage/backend-plugin-api/src/services/system/types';
|
||||
/**
|
||||
* Keep in sync with `@backstage/backend-plugin-api/src/services/system/types.ts`
|
||||
* @internal
|
||||
*/
|
||||
export type InternalServiceRef<T> = ServiceRef<T> & {
|
||||
export type InternalServiceRef = ServiceRef<unknown> & {
|
||||
__defaultFactory?: (
|
||||
service: ServiceRef<T>,
|
||||
) => Promise<ServiceFactory<T> | (() => ServiceFactory<T>)>;
|
||||
service: ServiceRef<unknown>,
|
||||
) => Promise<ServiceFactory | (() => ServiceFactory)>;
|
||||
};
|
||||
|
||||
function toInternalServiceFactory<TService, TScope extends 'plugin' | 'root'>(
|
||||
factory: ServiceFactory<TService, TScope>,
|
||||
): InternalServiceFactory<TService, TScope> {
|
||||
const f = factory as InternalServiceFactory<TService, TScope>;
|
||||
if (f.$$type !== '@backstage/ServiceFactory') {
|
||||
throw new Error(`Invalid service factory, bad type '${f.$$type}'`);
|
||||
}
|
||||
if (f.version !== 'v1') {
|
||||
throw new Error(`Invalid service factory, bad version '${f.version}'`);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
const pluginMetadataServiceFactory = createServiceFactory(
|
||||
(options: { pluginId: string }) => ({
|
||||
service: coreServices.pluginMetadata,
|
||||
deps: {},
|
||||
factory: async () => ({ getId: () => options.pluginId }),
|
||||
}),
|
||||
);
|
||||
|
||||
export class ServiceRegistry implements EnumerableServiceHolder {
|
||||
readonly #providedFactories: Map<string, ServiceFactory>;
|
||||
readonly #loadedDefaultFactories: Map<Function, Promise<ServiceFactory>>;
|
||||
readonly #providedFactories: Map<string, InternalServiceFactory>;
|
||||
readonly #loadedDefaultFactories: Map<
|
||||
Function,
|
||||
Promise<InternalServiceFactory>
|
||||
>;
|
||||
readonly #implementations: Map<
|
||||
ServiceFactory,
|
||||
InternalServiceFactory,
|
||||
{
|
||||
context: Promise<unknown>;
|
||||
byPlugin: Map<string, Promise<unknown>>;
|
||||
}
|
||||
>;
|
||||
readonly #rootServiceImplementations = new Map<
|
||||
ServiceFactory,
|
||||
InternalServiceFactory,
|
||||
Promise<unknown>
|
||||
>();
|
||||
|
||||
constructor(factories: Array<ServiceFactory<unknown>>) {
|
||||
this.#providedFactories = new Map(factories.map(f => [f.service.id, f]));
|
||||
constructor(factories: Array<ServiceFactory>) {
|
||||
this.#providedFactories = new Map(
|
||||
factories.map(sf => [sf.service.id, toInternalServiceFactory(sf)]),
|
||||
);
|
||||
this.#loadedDefaultFactories = new Map();
|
||||
this.#implementations = new Map();
|
||||
}
|
||||
@@ -55,23 +85,19 @@ export class ServiceRegistry implements EnumerableServiceHolder {
|
||||
#resolveFactory(
|
||||
ref: ServiceRef<unknown>,
|
||||
pluginId: string,
|
||||
): Promise<ServiceFactory> | undefined {
|
||||
): Promise<InternalServiceFactory> | undefined {
|
||||
// Special case handling of the plugin metadata service, generating a custom factory for it each time
|
||||
if (ref.id === coreServices.pluginMetadata.id) {
|
||||
return Promise.resolve<
|
||||
ServiceFactory<typeof coreServices.pluginMetadata.T>
|
||||
>({
|
||||
scope: 'plugin',
|
||||
service: coreServices.pluginMetadata,
|
||||
deps: {},
|
||||
factory: async () => ({ getId: () => pluginId }),
|
||||
});
|
||||
return Promise.resolve(
|
||||
toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId })),
|
||||
);
|
||||
}
|
||||
|
||||
let resolvedFactory: Promise<ServiceFactory> | ServiceFactory | undefined =
|
||||
this.#providedFactories.get(ref.id);
|
||||
const { __defaultFactory: defaultFactory } =
|
||||
ref as InternalServiceRef<unknown>;
|
||||
let resolvedFactory:
|
||||
| Promise<InternalServiceFactory>
|
||||
| InternalServiceFactory
|
||||
| undefined = this.#providedFactories.get(ref.id);
|
||||
const { __defaultFactory: defaultFactory } = ref as InternalServiceRef;
|
||||
if (!resolvedFactory && !defaultFactory) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -82,8 +108,8 @@ export class ServiceRegistry implements EnumerableServiceHolder {
|
||||
loadedFactory = Promise.resolve()
|
||||
.then(() => defaultFactory!(ref))
|
||||
.then(f =>
|
||||
typeof f === 'function' ? f() : f,
|
||||
) as Promise<ServiceFactory>;
|
||||
toInternalServiceFactory(typeof f === 'function' ? f() : f),
|
||||
);
|
||||
this.#loadedDefaultFactories.set(defaultFactory!, loadedFactory);
|
||||
}
|
||||
resolvedFactory = loadedFactory.catch(error => {
|
||||
@@ -100,7 +126,7 @@ export class ServiceRegistry implements EnumerableServiceHolder {
|
||||
return Promise.resolve(resolvedFactory);
|
||||
}
|
||||
|
||||
#checkForMissingDeps(factory: ServiceFactory, pluginId: string) {
|
||||
#checkForMissingDeps(factory: InternalServiceFactory, pluginId: string) {
|
||||
const missingDeps = Object.values(factory.deps).filter(ref => {
|
||||
if (ref.id === coreServices.pluginMetadata.id) {
|
||||
return false;
|
||||
@@ -109,7 +135,7 @@ export class ServiceRegistry implements EnumerableServiceHolder {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !(ref as InternalServiceRef<unknown>).__defaultFactory;
|
||||
return !(ref as InternalServiceRef).__defaultFactory;
|
||||
});
|
||||
|
||||
if (missingDeps.length) {
|
||||
@@ -126,7 +152,7 @@ export class ServiceRegistry implements EnumerableServiceHolder {
|
||||
|
||||
get<T>(ref: ServiceRef<T>, pluginId: string): Promise<T> | undefined {
|
||||
return this.#resolveFactory(ref, pluginId)?.then(factory => {
|
||||
if (factory.scope === 'root') {
|
||||
if (factory.service.scope === 'root') {
|
||||
let existing = this.#rootServiceImplementations.get(factory);
|
||||
if (!existing) {
|
||||
this.#checkForMissingDeps(factory, pluginId);
|
||||
@@ -143,7 +169,7 @@ export class ServiceRegistry implements EnumerableServiceHolder {
|
||||
}
|
||||
|
||||
existing = Promise.all(rootDeps).then(entries =>
|
||||
factory.factory(Object.fromEntries(entries)),
|
||||
factory.factory(Object.fromEntries(entries), undefined),
|
||||
);
|
||||
this.#rootServiceImplementations.set(factory, existing);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type {
|
||||
Backend,
|
||||
CreateSpecializedBackendOptions,
|
||||
ServiceOrExtensionPoint,
|
||||
} from './types';
|
||||
export type { Backend, CreateSpecializedBackendOptions } from './types';
|
||||
export { createSpecializedBackend } from './createSpecializedBackend';
|
||||
|
||||
@@ -34,8 +34,10 @@ export interface BackendRegisterInit {
|
||||
id: string;
|
||||
consumes: Set<ServiceOrExtensionPoint>;
|
||||
provides: Set<ServiceOrExtensionPoint>;
|
||||
deps: { [name: string]: ServiceOrExtensionPoint };
|
||||
init: (deps: { [name: string]: unknown }) => Promise<void>;
|
||||
init: {
|
||||
deps: { [name: string]: ServiceOrExtensionPoint };
|
||||
func: (deps: { [name: string]: unknown }) => Promise<void>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @backstage/backend-common
|
||||
|
||||
## 0.18.2-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e716946103: Updated usage of the lifecycle service.
|
||||
- d31d8e00b3: Updated to work with the new `type: 'pem'` with `createHttpServer` from `@backstage/backend-app-api`
|
||||
- 0ff03319be: Updated usage of `createBackendPlugin`.
|
||||
- f60cca9da1: The `DatabaseManager.forPlugin` method now accepts additional service dependencies. There is no need to update existing code to pass these dependencies.
|
||||
- Updated dependencies
|
||||
- @backstage/backend-app-api@0.4.0-next.2
|
||||
- @backstage/backend-plugin-api@0.4.0-next.2
|
||||
- @backstage/backend-dev-utils@0.1.0-next.0
|
||||
- @backstage/cli-common@0.1.11
|
||||
- @backstage/config@1.0.6
|
||||
- @backstage/config-loader@1.1.8
|
||||
- @backstage/errors@1.1.4
|
||||
- @backstage/integration@1.4.2
|
||||
- @backstage/types@1.0.2
|
||||
|
||||
## 0.18.2-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.18.2-next.1",
|
||||
"version": "0.18.2-next.2",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { Logger as WinstonLogger, createLogger } from 'winston';
|
||||
import Transport, { TransportStreamOptions } from 'winston-transport';
|
||||
|
||||
@@ -31,7 +32,7 @@ class BackstageLoggerTransport extends Transport {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
const { level, message, ...meta } = info as { [name: string]: unknown };
|
||||
const { level, message, ...meta } = info as JsonObject;
|
||||
switch (level) {
|
||||
case 'error':
|
||||
this.backstageLogger.error(String(message), meta);
|
||||
|
||||
@@ -102,7 +102,7 @@ export class ServiceBuilderImpl implements ServiceBuilder {
|
||||
this.serverOptions.https = {
|
||||
certificate: {
|
||||
...settings.certificate,
|
||||
type: 'plain',
|
||||
type: 'pem',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @backstage/backend-defaults
|
||||
|
||||
## 0.1.7-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e412d33025: Use the new `*ServiceFactory` exports from `@backstage/backend-app-api`
|
||||
- Updated dependencies
|
||||
- @backstage/backend-app-api@0.4.0-next.2
|
||||
- @backstage/backend-plugin-api@0.4.0-next.2
|
||||
|
||||
## 0.1.7-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-defaults",
|
||||
"description": "Backend defaults used by Backstage backend apps",
|
||||
"version": "0.1.7-next.1",
|
||||
"version": "0.1.7-next.2",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -16,22 +16,22 @@
|
||||
|
||||
import {
|
||||
Backend,
|
||||
cacheFactory,
|
||||
configFactory,
|
||||
cacheServiceFactory,
|
||||
configServiceFactory,
|
||||
createSpecializedBackend,
|
||||
databaseFactory,
|
||||
discoveryFactory,
|
||||
httpRouterFactory,
|
||||
rootHttpRouterFactory,
|
||||
lifecycleFactory,
|
||||
rootLifecycleFactory,
|
||||
loggerFactory,
|
||||
permissionsFactory,
|
||||
rootLoggerFactory,
|
||||
schedulerFactory,
|
||||
tokenManagerFactory,
|
||||
urlReaderFactory,
|
||||
identityFactory,
|
||||
databaseServiceFactory,
|
||||
discoveryServiceFactory,
|
||||
httpRouterServiceFactory,
|
||||
rootHttpRouterServiceFactory,
|
||||
lifecycleServiceFactory,
|
||||
rootLifecycleServiceFactory,
|
||||
loggerServiceFactory,
|
||||
permissionsServiceFactory,
|
||||
rootLoggerServiceFactory,
|
||||
schedulerServiceFactory,
|
||||
tokenManagerServiceFactory,
|
||||
urlReaderServiceFactory,
|
||||
identityServiceFactory,
|
||||
} from '@backstage/backend-app-api';
|
||||
import {
|
||||
ServiceFactory,
|
||||
@@ -44,21 +44,21 @@ import {
|
||||
import type { InternalSharedBackendEnvironment } from '@backstage/backend-plugin-api/src/wiring/createSharedEnvironment';
|
||||
|
||||
export const defaultServiceFactories = [
|
||||
cacheFactory(),
|
||||
configFactory(),
|
||||
databaseFactory(),
|
||||
discoveryFactory(),
|
||||
httpRouterFactory(),
|
||||
identityFactory(),
|
||||
lifecycleFactory(),
|
||||
loggerFactory(),
|
||||
permissionsFactory(),
|
||||
rootHttpRouterFactory(),
|
||||
rootLifecycleFactory(),
|
||||
rootLoggerFactory(),
|
||||
schedulerFactory(),
|
||||
tokenManagerFactory(),
|
||||
urlReaderFactory(),
|
||||
cacheServiceFactory(),
|
||||
configServiceFactory(),
|
||||
databaseServiceFactory(),
|
||||
discoveryServiceFactory(),
|
||||
httpRouterServiceFactory(),
|
||||
identityServiceFactory(),
|
||||
lifecycleServiceFactory(),
|
||||
loggerServiceFactory(),
|
||||
permissionsServiceFactory(),
|
||||
rootHttpRouterServiceFactory(),
|
||||
rootLifecycleServiceFactory(),
|
||||
rootLoggerServiceFactory(),
|
||||
schedulerServiceFactory(),
|
||||
tokenManagerServiceFactory(),
|
||||
urlReaderServiceFactory(),
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# @backstage/backend-dev-utils
|
||||
|
||||
## 0.1.0-next.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 9d9cdea117: Introduced a new package for backend development utilities. Similar to how `@backstage/dev-utils` is used in the frontend.
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/backend-dev-utils",
|
||||
"version": "0.0.0",
|
||||
"version": "0.1.0-next.0",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# example-backend-next
|
||||
|
||||
## 0.0.8-next.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies
|
||||
- @backstage/plugin-catalog-backend@1.7.2-next.2
|
||||
- @backstage/plugin-scaffolder-backend@1.11.0-next.2
|
||||
- @backstage/plugin-app-backend@0.3.42-next.2
|
||||
- @backstage/backend-defaults@0.1.7-next.2
|
||||
|
||||
## 0.0.8-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend-next",
|
||||
"version": "0.0.8-next.1",
|
||||
"version": "0.0.8-next.2",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
# @backstage/backend-plugin-api
|
||||
|
||||
## 0.4.0-next.2
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- e716946103: **BREAKING**: Split out the hook for both lifecycle services so that the first parameter of `addShutdownHook` is the hook function, and the second is the options.
|
||||
- 0ff03319be: **BREAKING**: The plugin ID option passed to `createBackendPlugin` is now `pluginId`, rather than just `id`. This is to make it match `createBackendModule` more closely.
|
||||
- 71a5ec0f06: **BREAKING**: Switched out `LogMeta` type for `JsonObject`.
|
||||
- 610d65e143: Switched `BackendFeature` to be an opaque type.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 9c9456fd33: Removed the unused `TypesToServiceRef` type
|
||||
- 181c03edb5: Aligned opaque type markers to all use a `$type` property with namespacing.
|
||||
- Updated dependencies
|
||||
- @backstage/backend-tasks@0.4.3-next.2
|
||||
- @backstage/plugin-auth-node@0.2.11-next.2
|
||||
- @backstage/config@1.0.6
|
||||
- @backstage/types@1.0.2
|
||||
- @backstage/plugin-permission-common@0.7.3
|
||||
|
||||
## 0.3.2-next.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user