Merge remote-tracking branch 'backstage/master' into erikengervall/grm-minor-corrections
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Add context for versions:bump on what version it was bumped to. Updated tests for the same.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-explore': patch
|
||||
---
|
||||
|
||||
Add "Organization" tab with a diagram
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
'@backstage/create-app': patch
|
||||
'@backstage/plugin-catalog-graphql': patch
|
||||
---
|
||||
|
||||
chore: bump `ts-node` versions to 9.1.1
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/catalog-model': patch
|
||||
---
|
||||
|
||||
Renamed parameters to input in template schema
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
The apiBaseUrl setting for Bitbucket Server integrations will now be used when it is set. Otherwise, it will default back to the host setting.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
---
|
||||
|
||||
Show error on task page if task does not exist.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-badges-backend': patch
|
||||
---
|
||||
|
||||
Fix generated badge links
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/catalog-model': patch
|
||||
---
|
||||
|
||||
Add the `status` field to the Entity envelope
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
update plugins created to use react-use 17.2.4
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/config-loader': patch
|
||||
---
|
||||
|
||||
Updated dependencies
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-org': patch
|
||||
---
|
||||
|
||||
Paginate group members to only display 50 members maximum.
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-git-release-manager': patch
|
||||
'@backstage/plugin-ilert': patch
|
||||
---
|
||||
|
||||
[ImgBot] Optimize images
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Skip adding entries to the `entities_search` table if their `key` exceeds a length limit.
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
'@backstage/core': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
---
|
||||
|
||||
Fix state persisted in the URL make search input in the table toolbar lose their
|
||||
focus.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/catalog-model': patch
|
||||
---
|
||||
|
||||
Improve error messages when schema validation fails
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
---
|
||||
|
||||
Move `jest-when` to the dev dependencies
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/core': patch
|
||||
---
|
||||
|
||||
Add count of older messages when multiple messages exist in AlertDisplay
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Bug fix on sidebar position when Tab-Bar is enabled
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-github-deployments': patch
|
||||
---
|
||||
|
||||
Support GHE by properly parsing enterprise instance hosts
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Handle URLs with a `#hash` correctly when rewriting link URLs.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/techdocs-common': patch
|
||||
---
|
||||
|
||||
Fixed a bug that prevented loading static assets from GCS, S3, Azure, and OpenStackSwift whose keys contain spaces or other special characters.
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
'@backstage/core': patch
|
||||
'@backstage/core-api': patch
|
||||
'@backstage/integration-react': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-badges': patch
|
||||
'@backstage/plugin-bitrise': patch
|
||||
'@backstage/plugin-catalog': patch
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
'@backstage/plugin-circleci': patch
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
'@backstage/plugin-code-coverage': patch
|
||||
'@backstage/plugin-config-schema': patch
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
'@backstage/plugin-explore': patch
|
||||
'@backstage/plugin-fossa': patch
|
||||
'@backstage/plugin-gcp-projects': patch
|
||||
'@backstage/plugin-github-actions': patch
|
||||
'@backstage/plugin-github-deployments': patch
|
||||
'@backstage/plugin-gitops-profiles': patch
|
||||
'@backstage/plugin-graphiql': patch
|
||||
'@backstage/plugin-jenkins': patch
|
||||
'@backstage/plugin-kafka': patch
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
'@backstage/plugin-lighthouse': patch
|
||||
'@backstage/plugin-newrelic': patch
|
||||
'@backstage/plugin-org': patch
|
||||
'@backstage/plugin-pagerduty': patch
|
||||
'@backstage/plugin-register-component': patch
|
||||
'@backstage/plugin-rollbar': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-search': patch
|
||||
'@backstage/plugin-sentry': patch
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
'@backstage/plugin-splunk-on-call': patch
|
||||
'@backstage/plugin-tech-radar': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
'@backstage/plugin-todo': patch
|
||||
'@backstage/plugin-user-settings': patch
|
||||
'@backstage/plugin-welcome': patch
|
||||
---
|
||||
|
||||
chore: bump `react-use` dependency in all packages
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': patch
|
||||
---
|
||||
|
||||
Add possibility to configure TLS verification for `gke` type clusters
|
||||
@@ -16,6 +16,7 @@
|
||||
/plugins/search-* @backstage/techdocs-core
|
||||
/plugins/techdocs @backstage/techdocs-core
|
||||
/plugins/techdocs-backend @backstage/techdocs-core
|
||||
/plugins/ilert @yacut
|
||||
/packages/search-common @backstage/techdocs-core
|
||||
/packages/techdocs-common @backstage/techdocs-core
|
||||
/.changeset/cost-insights-* @backstage/silver-lining
|
||||
|
||||
@@ -167,6 +167,7 @@ mailto
|
||||
maintainership
|
||||
makefile
|
||||
md
|
||||
memcache
|
||||
microsite
|
||||
middleware
|
||||
minikube
|
||||
@@ -177,6 +178,7 @@ mkdocs
|
||||
monorepo
|
||||
monorepos
|
||||
msw
|
||||
mysql
|
||||
namespace
|
||||
namespaced
|
||||
namespaces
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
_
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn lint-staged
|
||||
@@ -27,5 +27,5 @@ People that have made significant contributions to the project and earned write
|
||||
- Andrew Thauer - Wealthsimple (GitHub: [andrewthauer](https://github.com/andrewthauer))
|
||||
- Oliver Sand - SDA SE (GitHub: [Fox32](https://github.com/Fox32))
|
||||
- David Tuite - Roadie (GitHub: [dtuite](https://github.com/dtuite))
|
||||
- Adam Harvey - DXC Technology (GitHub: [adamdmharvey](https://github.com/adamdmharvey))
|
||||
- Adam Harvey - Cisco (GitHub: [adamdmharvey](https://github.com/adamdmharvey))
|
||||
- Dominik Henneke - SDA SE (GitHub: [dhenneke](https://github.com/dhenneke))
|
||||
|
||||
@@ -81,6 +81,13 @@ proxy:
|
||||
headers:
|
||||
Authorization: ${SENTRY_TOKEN}
|
||||
|
||||
'/ilert':
|
||||
target: https://api.ilert.com
|
||||
allowedMethods: ['GET', 'POST', 'PUT']
|
||||
allowedHeaders: ['Authorization']
|
||||
headers:
|
||||
Authorization: ${ILERT_AUTH_HEADER}
|
||||
|
||||
organization:
|
||||
name: My Company
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ we recommend that you name them `catalog-info.yaml`.
|
||||
- [Common to All Kinds: The Envelope](#common-to-all-kinds-the-envelope)
|
||||
- [Common to All Kinds: The Metadata](#common-to-all-kinds-the-metadata)
|
||||
- [Common to All Kinds: Relations](#common-to-all-kinds-relations)
|
||||
- [Common to All Kinds: Status](#common-to-all-kinds-status)
|
||||
- [Kind: Component](#kind-component)
|
||||
- [Kind: Template](#kind-template)
|
||||
- [Kind: API](#kind-api)
|
||||
@@ -396,6 +397,54 @@ with it (such as the default kind being `Group` if not specified).
|
||||
See the [well-known relations section](well-known-relations.md) for a list of
|
||||
well-known / common relations and their semantics.
|
||||
|
||||
## Common to All Kinds: Status
|
||||
|
||||
The `status` root field is a read-only set of statuses, pertaining to the
|
||||
current state or health of the entity, described in the
|
||||
[well-known statuses section](well-known-statuses.md). Each status field
|
||||
contains a specific blob of data that describes some aspect of the state of the
|
||||
entity, as seen from the point of view of some specific system. Different
|
||||
systems may contribute to this status object, under their own respective keys.
|
||||
|
||||
The current main use case for this field is for the ingestion processes of the
|
||||
catalog itself to convey information about failures and warnings back to the
|
||||
user.
|
||||
|
||||
A status field as part of a single entity that's read out of the API may look as
|
||||
follows.
|
||||
|
||||
```js
|
||||
{
|
||||
// ...
|
||||
"status": {
|
||||
"backstage.io/catalog-processing": {
|
||||
"errors": []
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The keys of the `status` object are arbitrary strings. We recommend that any
|
||||
statuses that are not strictly private within the organization be namespaced to
|
||||
avoid collisions. Statuses emitted by Backstage core processes will for example
|
||||
be prefixed with `backstage.io/` as in the example above.
|
||||
|
||||
The values of the `status` object are currently left unrestricted, except that
|
||||
they must be objects. We reserve the right to extend this model in the future,
|
||||
such that some fields of those value objects gain standardized meaning. We may
|
||||
for example want to add a standard concept of "severity" or "level" to these.
|
||||
|
||||
Entity descriptor YAML files are not supposed to contain this field. Instead,
|
||||
catalog processors analyze the entity descriptor data and its surroundings, and
|
||||
deduce status entries that are then attached onto the entity as read from the
|
||||
catalog.
|
||||
|
||||
See the [well-known statuses section](well-known-statuses.md) for a list of
|
||||
well-known / common relations and their semantics.
|
||||
|
||||
## Kind: Component
|
||||
|
||||
Describes the following entity kind:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
id: extending-the-model
|
||||
title: Extending the model
|
||||
# prettier-ignore
|
||||
description: Documentation on extending the catalog model
|
||||
---
|
||||
|
||||
@@ -301,9 +302,9 @@ Example intents:
|
||||
> "We have this concept of service maintainership, separate from ownership, that
|
||||
> we would like to make relations to individual users for."
|
||||
|
||||
> We feel that we want to explicitly model the team-to-global-department mapping
|
||||
> as a relation, because it is core to our org setup and we frequently query for
|
||||
> it.
|
||||
> "We feel that we want to explicitly model the team-to-global-department
|
||||
> mapping as a relation, because it is core to our org setup and we frequently
|
||||
> query for it."
|
||||
|
||||
Any processor can emit relations for entities as they are being processed, and
|
||||
new processors can be added when building the backend catalog using the
|
||||
@@ -349,3 +350,21 @@ If you want to extend the use of an established relation type in a way that has
|
||||
an effect outside of your organization, reach out to the Backstage maintainers
|
||||
or a support partner to discuss risk/impact. It may even be that one end of the
|
||||
relation could be considered for addition to the core.
|
||||
|
||||
## Adding a New Status field
|
||||
|
||||
Example intents:
|
||||
|
||||
> "We would like to convey entity statuses through the catalog in a generic way,
|
||||
> as an integration layer. Our monitoring and alerting system has a plugin with
|
||||
> Backstage, and it would be useful if the entity's status field contained the
|
||||
> current alert state close to the actual entity data for anyone to consume.
|
||||
|
||||
While we are considering a mechanism for contributing generic statuses to
|
||||
entities, no such mechanism has yet been built. If you are interested in that
|
||||
topic, [this issue](https://github.com/backstage/backstage/issues/2292) contains
|
||||
more context.
|
||||
|
||||
But in general, errors emitted (and exceptions thrown) by any processor
|
||||
including custom ones, end up in the [well known key](well-known-statuses.md)
|
||||
for ingestion status.
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: well-known-statuses
|
||||
title: Well-known Status fields of Catalog Entities
|
||||
sidebar_label: Well-known Statuses
|
||||
# prettier-ignore
|
||||
description: Lists a number of well known entity statuses, that have defined semantics. They can be attached to catalog entities and consumed by plugins as needed.
|
||||
---
|
||||
|
||||
This section lists a number of well known
|
||||
[entity status fields](descriptor-format.md#common-to-all-kinds-status), that
|
||||
have defined semantics. They can be attached to catalog entities and consumed by
|
||||
plugins as needed.
|
||||
|
||||
If you are looking to extend the set of statuses, see
|
||||
[Extending the model](extending-the-model.md).
|
||||
|
||||
## Common Fields
|
||||
|
||||
The values of statuses are currently left unrestricted, except that they must be
|
||||
objects. They therefore currently formally have no common fields.
|
||||
|
||||
We reserve the right to extend this model in the future, such that some fields
|
||||
of those value objects gain standardized meaning. We may for example want to add
|
||||
a standard concept of "severity" or "level" to these.
|
||||
|
||||
## Statuses
|
||||
|
||||
This is a (non-exhaustive) list of statuses that are known to be in active use.
|
||||
|
||||
### `backstage.io/catalog-processing`
|
||||
|
||||
Contains the current status of the catalog's ingestion of this entity. Errors
|
||||
that may appear here include inability to read from the remote SCM provider,
|
||||
syntax errors in the YAML file, and similar.
|
||||
|
||||
Note that the entity data itself may be of an older version, when errors are
|
||||
present. The ingestion system keeps the old, valid entity data untouched when
|
||||
possible, so the errors described in this state may not seem to align with the
|
||||
rest of the entity, because they pertain to a remote that could not be
|
||||
successfully ingested. This is normal.
|
||||
|
||||
```yaml
|
||||
# Example:
|
||||
status:
|
||||
backstage.io/catalog-processing:
|
||||
errors: []
|
||||
```
|
||||
|
||||
This status is in active development and its format will change unexpectedly. Do
|
||||
not consume it in your own code until such a time that this documentation has
|
||||
been updated.
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: iLert
|
||||
author: iLert
|
||||
authorUrl: https://www.ilert.com
|
||||
category: Monitoring
|
||||
description: iLert is a platform for alerting, on-call management and uptime monitoring targeted at DevOps and IT teams.
|
||||
documentation: https://github.com/backstage/backstage/tree/master/plugins/ilert
|
||||
iconUrl: https://avatars.githubusercontent.com/u/13230510?s=200&v=4
|
||||
npmPackageName: '@backstage/plugin-ilert'
|
||||
tags:
|
||||
- monitoring
|
||||
- errors
|
||||
- alerting
|
||||
- uptime
|
||||
- on-call
|
||||
@@ -40,6 +40,7 @@
|
||||
"features/software-catalog/references",
|
||||
"features/software-catalog/well-known-annotations",
|
||||
"features/software-catalog/well-known-relations",
|
||||
"features/software-catalog/well-known-statuses",
|
||||
"features/software-catalog/extending-the-model",
|
||||
"features/software-catalog/external-integrations",
|
||||
"features/software-catalog/software-catalog-api"
|
||||
|
||||
@@ -1,13 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="500px" height="500px" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>Export</title>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ship" transform="translate(249.680798, 211.000000) scale(-1, 1) translate(-249.680798, -211.000000) translate(35.680798, -39.000000)" fill-rule="nonzero">
|
||||
<g id="Flamez" transform="translate(279.925187, 455.280081) rotate(-90.000000) translate(-279.925187, -455.280081) translate(235.660848, 411.639183)">
|
||||
<path d="M77.6240648,9.79348504 C64.5660848,-3.26449501 42.8017456,-3.26449501 29.7437656,9.79348504 C11.6072319,27.9300187 0.725685786,80.8882481 8.85963511e-15,83.064682 C8.85963511e-15,84.5154302 8.85963511e-15,85.241116 0.725685786,85.9668017 C2.17643392,86.6924875 3.62780549,86.6924875 5.07855362,86.6924875 C7.25498753,85.9668017 60.213217,75.810318 78.3497506,56.9487219 C91.4077307,43.8901185 91.4077307,22.8514651 77.6240648,9.79348504 Z" id="Path" fill="#F79548"></path>
|
||||
<path d="M75.4476309,10.5185474 C68.9183292,3.98924564 58.036783,3.98924564 51.5074813,10.5185474 C42.0766833,19.9493454 36.9981297,46.0659289 36.9981297,46.7916147 C36.9981297,47.5173005 36.9981297,48.2423628 37.7238155,48.2423628 C38.4495012,48.9680486 38.4495012,48.9680486 39.1745636,48.9680486 C40.6253117,48.9680486 66.7418953,43.1644327 75.4476309,34.458697 C81.9769327,27.9300187 81.9769327,17.0478491 75.4476309,10.5185474 Z" id="Path" fill="#FCBB76"></path>
|
||||
</g>
|
||||
<path d="M216.186409,55.2394015 C218.49257,55.2394015 220.58047,56.1742348 222.091833,57.6855981 C223.534498,59.128263 224.451854,61.0962436 224.532269,63.2779325 L224.53803,63.5910224 L224.53803,91.005836 L353.369587,261.704121 C354.323776,262.968115 354.87911,264.447677 355.019478,265.965658 C355.159883,267.484039 354.88511,269.040862 354.179061,270.458806 C353.472845,271.876805 352.395871,273.033852 351.099552,273.836436 C349.895645,274.581806 348.502551,275.021453 347.041547,275.080457 L346.703242,275.087282 L224.53803,275.087282 L224.53803,303.904613 L346.684539,303.904613 C348.308638,303.904613 349.858968,304.375354 351.174692,305.21426 C352.490519,306.053232 353.571696,307.260417 354.25731,308.732969 C354.942424,310.205367 355.16974,311.809443 354.964363,313.356104 C354.77365,314.792333 354.20983,316.179047 353.29311,317.364769 L353.075304,317.634761 L309.451382,369.468132 C307.930114,371.274871 305.719044,372.349921 303.368443,372.436371 L303.061097,372.44202 L124.602244,372.44202 C122.240117,372.44202 119.994057,371.442358 118.41433,369.699238 L118.212103,369.467679 L74.5886595,317.634759 C73.5428392,316.392134 72.9047814,314.903039 72.6994228,313.356514 C72.494029,311.809724 72.7214803,310.205497 73.4066556,308.732969 C74.0917295,307.260659 75.1726391,306.053772 76.4882065,305.214939 C77.7099169,304.435952 79.1339993,303.974371 80.6313862,303.912406 L80.9781796,303.905237 L207.834788,303.905237 L207.834788,274.720698 L106.28616,274.720698 C103.979999,274.720698 101.892098,273.785865 100.380735,272.274502 C98.8693719,270.763138 97.9345387,268.675238 97.9345387,266.369077 C97.9345387,233.249109 111.496611,180.759139 130.891816,138.720038 C142.0216,114.595575 154.255888,95.1994886 167.266567,81.0803824 C183.02715,63.976526 199.471354,55.2394015 216.186409,55.2394015 Z M328.739655,320.607855 L98.9224399,320.607855 L128.488453,355.738155 L299.173642,355.738155 L328.739655,320.607855 Z M224.53803,118.732589 L224.53803,258.384663 L329.936488,258.384663 L224.53803,118.732589 Z M207.834165,73.0839035 C187.31365,78.5957312 165.169959,104.292863 146.058313,145.71761 C129.135086,182.399574 116.887708,227.020442 114.917014,258.016833 L114.917014,258.016833 L207.834165,258.016833 Z" id="Shape" stroke="#DDDDDD" stroke-width="2" fill="#E8E8E8" transform="translate(213.840829, 213.840711) rotate(45.000000) translate(-213.840829, -213.840711) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500" version="1.1" viewBox="0 0 500 500"><title>Export</title><g id="Page-1" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="ship" fill-rule="nonzero" transform="translate(249.680798, 211.000000) scale(-1, 1) translate(-249.680798, -211.000000) translate(35.680798, -39.000000)"><g id="Flamez" transform="translate(279.925187, 455.280081) rotate(-90.000000) translate(-279.925187, -455.280081) translate(235.660848, 411.639183)"><path id="Path" fill="#F79548" d="M77.6240648,9.79348504 C64.5660848,-3.26449501 42.8017456,-3.26449501 29.7437656,9.79348504 C11.6072319,27.9300187 0.725685786,80.8882481 8.85963511e-15,83.064682 C8.85963511e-15,84.5154302 8.85963511e-15,85.241116 0.725685786,85.9668017 C2.17643392,86.6924875 3.62780549,86.6924875 5.07855362,86.6924875 C7.25498753,85.9668017 60.213217,75.810318 78.3497506,56.9487219 C91.4077307,43.8901185 91.4077307,22.8514651 77.6240648,9.79348504 Z"/><path id="Path" fill="#FCBB76" d="M75.4476309,10.5185474 C68.9183292,3.98924564 58.036783,3.98924564 51.5074813,10.5185474 C42.0766833,19.9493454 36.9981297,46.0659289 36.9981297,46.7916147 C36.9981297,47.5173005 36.9981297,48.2423628 37.7238155,48.2423628 C38.4495012,48.9680486 38.4495012,48.9680486 39.1745636,48.9680486 C40.6253117,48.9680486 66.7418953,43.1644327 75.4476309,34.458697 C81.9769327,27.9300187 81.9769327,17.0478491 75.4476309,10.5185474 Z"/></g><path id="Shape" fill="#E8E8E8" stroke="#DDD" stroke-width="2" d="M216.186409,55.2394015 C218.49257,55.2394015 220.58047,56.1742348 222.091833,57.6855981 C223.534498,59.128263 224.451854,61.0962436 224.532269,63.2779325 L224.53803,63.5910224 L224.53803,91.005836 L353.369587,261.704121 C354.323776,262.968115 354.87911,264.447677 355.019478,265.965658 C355.159883,267.484039 354.88511,269.040862 354.179061,270.458806 C353.472845,271.876805 352.395871,273.033852 351.099552,273.836436 C349.895645,274.581806 348.502551,275.021453 347.041547,275.080457 L346.703242,275.087282 L224.53803,275.087282 L224.53803,303.904613 L346.684539,303.904613 C348.308638,303.904613 349.858968,304.375354 351.174692,305.21426 C352.490519,306.053232 353.571696,307.260417 354.25731,308.732969 C354.942424,310.205367 355.16974,311.809443 354.964363,313.356104 C354.77365,314.792333 354.20983,316.179047 353.29311,317.364769 L353.075304,317.634761 L309.451382,369.468132 C307.930114,371.274871 305.719044,372.349921 303.368443,372.436371 L303.061097,372.44202 L124.602244,372.44202 C122.240117,372.44202 119.994057,371.442358 118.41433,369.699238 L118.212103,369.467679 L74.5886595,317.634759 C73.5428392,316.392134 72.9047814,314.903039 72.6994228,313.356514 C72.494029,311.809724 72.7214803,310.205497 73.4066556,308.732969 C74.0917295,307.260659 75.1726391,306.053772 76.4882065,305.214939 C77.7099169,304.435952 79.1339993,303.974371 80.6313862,303.912406 L80.9781796,303.905237 L207.834788,303.905237 L207.834788,274.720698 L106.28616,274.720698 C103.979999,274.720698 101.892098,273.785865 100.380735,272.274502 C98.8693719,270.763138 97.9345387,268.675238 97.9345387,266.369077 C97.9345387,233.249109 111.496611,180.759139 130.891816,138.720038 C142.0216,114.595575 154.255888,95.1994886 167.266567,81.0803824 C183.02715,63.976526 199.471354,55.2394015 216.186409,55.2394015 Z M328.739655,320.607855 L98.9224399,320.607855 L128.488453,355.738155 L299.173642,355.738155 L328.739655,320.607855 Z M224.53803,118.732589 L224.53803,258.384663 L329.936488,258.384663 L224.53803,118.732589 Z M207.834165,73.0839035 C187.31365,78.5957312 165.169959,104.292863 146.058313,145.71761 C129.135086,182.399574 116.887708,227.020442 114.917014,258.016833 L114.917014,258.016833 L207.834165,258.016833 Z" transform="translate(213.840829, 213.840711) rotate(45.000000) translate(-213.840829, -213.840711)"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.8 KiB |
@@ -37,6 +37,7 @@ nav:
|
||||
- Entity References: 'features/software-catalog/references.md'
|
||||
- Well-known Annotations: 'features/software-catalog/well-known-annotations.md'
|
||||
- Well-known Relations: 'features/software-catalog/well-known-relations.md'
|
||||
- Well-known Statuses: 'features/software-catalog/well-known-statuses.md'
|
||||
- Extending the model: 'features/software-catalog/extending-the-model.md'
|
||||
- External integrations: 'features/software-catalog/external-integrations.md'
|
||||
- API: 'features/software-catalog/api.md'
|
||||
|
||||
+3
-7
@@ -30,7 +30,8 @@
|
||||
"prettier:check": "prettier --check .",
|
||||
"lerna": "lerna",
|
||||
"storybook": "yarn workspace storybook start",
|
||||
"build-storybook": "yarn workspace storybook build-storybook"
|
||||
"build-storybook": "yarn workspace storybook build-storybook",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
@@ -60,18 +61,13 @@
|
||||
"command-exists": "^1.2.9",
|
||||
"concurrently": "^6.0.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"husky": "^4.2.3",
|
||||
"husky": "^6.0.0",
|
||||
"lerna": "^4.0.0",
|
||||
"lint-staged": "^10.1.0",
|
||||
"prettier": "^2.2.1",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"shx": "^0.3.2"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "lint-staged"
|
||||
}
|
||||
},
|
||||
"prettier": "@spotify/prettier-config",
|
||||
"lint-staged": {
|
||||
"*.{js,jsx,ts,tsx}": [
|
||||
|
||||
@@ -1,5 +1,57 @@
|
||||
# example-app
|
||||
|
||||
## 0.2.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [2cd70e164]
|
||||
- Updated dependencies [0b033d07b]
|
||||
- Updated dependencies [3be844496]
|
||||
- Updated dependencies [5542de095]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [81ef1d57b]
|
||||
- Updated dependencies [ea21d46f0]
|
||||
- Updated dependencies [e3fc89df6]
|
||||
- Updated dependencies [f59a945b7]
|
||||
- Updated dependencies [889d89b6e]
|
||||
- Updated dependencies [16be1d093]
|
||||
- Updated dependencies [3f988cb63]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core@0.7.9
|
||||
- @backstage/integration-react@0.1.2
|
||||
- @backstage/plugin-api-docs@0.4.13
|
||||
- @backstage/plugin-badges@0.2.1
|
||||
- @backstage/plugin-catalog@0.5.7
|
||||
- @backstage/plugin-catalog-import@0.5.6
|
||||
- @backstage/plugin-catalog-react@0.1.6
|
||||
- @backstage/plugin-circleci@0.2.14
|
||||
- @backstage/plugin-cloudbuild@0.2.14
|
||||
- @backstage/plugin-code-coverage@0.1.3
|
||||
- @backstage/plugin-cost-insights@0.9.1
|
||||
- @backstage/plugin-explore@0.3.5
|
||||
- @backstage/plugin-gcp-projects@0.2.6
|
||||
- @backstage/plugin-github-actions@0.4.6
|
||||
- @backstage/plugin-graphiql@0.2.11
|
||||
- @backstage/plugin-jenkins@0.4.3
|
||||
- @backstage/plugin-kafka@0.2.7
|
||||
- @backstage/plugin-kubernetes@0.4.4
|
||||
- @backstage/plugin-lighthouse@0.2.16
|
||||
- @backstage/plugin-newrelic@0.2.7
|
||||
- @backstage/plugin-org@0.3.13
|
||||
- @backstage/plugin-pagerduty@0.3.4
|
||||
- @backstage/plugin-rollbar@0.3.5
|
||||
- @backstage/plugin-scaffolder@0.9.4
|
||||
- @backstage/plugin-search@0.3.6
|
||||
- @backstage/plugin-sentry@0.3.10
|
||||
- @backstage/plugin-shortcuts@0.1.2
|
||||
- @backstage/plugin-tech-radar@0.3.11
|
||||
- @backstage/plugin-techdocs@0.9.2
|
||||
- @backstage/plugin-todo@0.1.1
|
||||
- @backstage/plugin-user-settings@0.2.10
|
||||
- @backstage/cli@0.6.11
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.2.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
+36
-36
@@ -1,42 +1,42 @@
|
||||
{
|
||||
"name": "example-app",
|
||||
"version": "0.2.27",
|
||||
"version": "0.2.28",
|
||||
"private": true,
|
||||
"bundled": true,
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.7.8",
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/core": "^0.7.8",
|
||||
"@backstage/integration-react": "^0.1.1",
|
||||
"@backstage/plugin-api-docs": "^0.4.12",
|
||||
"@backstage/plugin-badges": "^0.2.0",
|
||||
"@backstage/plugin-catalog": "^0.5.6",
|
||||
"@backstage/plugin-catalog-import": "^0.5.5",
|
||||
"@backstage/plugin-catalog-react": "^0.1.5",
|
||||
"@backstage/plugin-circleci": "^0.2.13",
|
||||
"@backstage/plugin-cloudbuild": "^0.2.13",
|
||||
"@backstage/plugin-code-coverage": "^0.1.2",
|
||||
"@backstage/plugin-cost-insights": "^0.9.0",
|
||||
"@backstage/plugin-explore": "^0.3.4",
|
||||
"@backstage/plugin-gcp-projects": "^0.2.5",
|
||||
"@backstage/plugin-github-actions": "^0.4.5",
|
||||
"@backstage/plugin-graphiql": "^0.2.10",
|
||||
"@backstage/plugin-jenkins": "^0.4.2",
|
||||
"@backstage/plugin-kafka": "^0.2.6",
|
||||
"@backstage/plugin-kubernetes": "^0.4.3",
|
||||
"@backstage/plugin-lighthouse": "^0.2.15",
|
||||
"@backstage/plugin-newrelic": "^0.2.6",
|
||||
"@backstage/plugin-org": "^0.3.12",
|
||||
"@backstage/plugin-pagerduty": "0.3.3",
|
||||
"@backstage/plugin-rollbar": "^0.3.4",
|
||||
"@backstage/plugin-scaffolder": "^0.9.3",
|
||||
"@backstage/plugin-search": "^0.3.5",
|
||||
"@backstage/plugin-sentry": "^0.3.9",
|
||||
"@backstage/plugin-shortcuts": "^0.1.1",
|
||||
"@backstage/plugin-tech-radar": "^0.3.10",
|
||||
"@backstage/plugin-techdocs": "^0.9.1",
|
||||
"@backstage/plugin-todo": "^0.1.0",
|
||||
"@backstage/plugin-user-settings": "^0.2.8",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/core": "^0.7.9",
|
||||
"@backstage/integration-react": "^0.1.2",
|
||||
"@backstage/plugin-api-docs": "^0.4.13",
|
||||
"@backstage/plugin-badges": "^0.2.1",
|
||||
"@backstage/plugin-catalog": "^0.5.7",
|
||||
"@backstage/plugin-catalog-import": "^0.5.6",
|
||||
"@backstage/plugin-catalog-react": "^0.1.6",
|
||||
"@backstage/plugin-circleci": "^0.2.14",
|
||||
"@backstage/plugin-cloudbuild": "^0.2.14",
|
||||
"@backstage/plugin-code-coverage": "^0.1.3",
|
||||
"@backstage/plugin-cost-insights": "^0.9.1",
|
||||
"@backstage/plugin-explore": "^0.3.5",
|
||||
"@backstage/plugin-gcp-projects": "^0.2.6",
|
||||
"@backstage/plugin-github-actions": "^0.4.6",
|
||||
"@backstage/plugin-graphiql": "^0.2.11",
|
||||
"@backstage/plugin-jenkins": "^0.4.3",
|
||||
"@backstage/plugin-kafka": "^0.2.7",
|
||||
"@backstage/plugin-kubernetes": "^0.4.4",
|
||||
"@backstage/plugin-lighthouse": "^0.2.16",
|
||||
"@backstage/plugin-newrelic": "^0.2.7",
|
||||
"@backstage/plugin-org": "^0.3.13",
|
||||
"@backstage/plugin-pagerduty": "0.3.4",
|
||||
"@backstage/plugin-rollbar": "^0.3.5",
|
||||
"@backstage/plugin-scaffolder": "^0.9.4",
|
||||
"@backstage/plugin-search": "^0.3.6",
|
||||
"@backstage/plugin-sentry": "^0.3.10",
|
||||
"@backstage/plugin-shortcuts": "^0.1.2",
|
||||
"@backstage/plugin-tech-radar": "^0.3.11",
|
||||
"@backstage/plugin-techdocs": "^0.9.2",
|
||||
"@backstage/plugin-todo": "^0.1.1",
|
||||
"@backstage/plugin-user-settings": "^0.2.10",
|
||||
"@backstage/theme": "^0.2.7",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -56,11 +56,11 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@testing-library/cypress": "^7.0.1",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/jquery": "^3.3.34",
|
||||
"@types/node": "^14.14.32",
|
||||
|
||||
@@ -1,5 +1,62 @@
|
||||
# @backstage/backend-common
|
||||
|
||||
## 0.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 22fd8ce2a: Introducing: a standard API for App Integrators to configure cache stores and Plugin Developers to interact with them.
|
||||
|
||||
Two cache stores are currently supported.
|
||||
|
||||
- `memory`, which is a very simple in-memory key/value store, intended for local development.
|
||||
- `memcache`, which can be used to connect to a memcache host.
|
||||
|
||||
Configuring and working with cache stores is very similar to the process for database connections.
|
||||
|
||||
```yaml
|
||||
backend:
|
||||
cache:
|
||||
store: memcache
|
||||
connection: user:pass@cache.example.com:11211
|
||||
```
|
||||
|
||||
```typescript
|
||||
import { CacheManager } from '@backstage/backend-common';
|
||||
|
||||
// Instantiating a cache client for a plugin.
|
||||
const cacheManager = CacheManager.fromConfig(config);
|
||||
const somePluginCache = cacheManager.forPlugin('somePlugin');
|
||||
const cacheClient = somePluginCache.getClient();
|
||||
|
||||
// Using the cache client:
|
||||
const cachedValue = await cacheClient.get('someKey');
|
||||
if (cachedValue) {
|
||||
return cachedValue;
|
||||
} else {
|
||||
const someValue = await someExpensiveProcess();
|
||||
await cacheClient.set('someKey', someValue);
|
||||
}
|
||||
await cacheClient.delete('someKey');
|
||||
```
|
||||
|
||||
Cache clients deal with TTLs in milliseconds. A TTL can be provided as a defaultTtl when getting a client, or may be passed when setting specific objects. If no TTL is provided, data will be persisted indefinitely.
|
||||
|
||||
```typescript
|
||||
// Getting a client with a default TTL
|
||||
const cacheClient = somePluginCache.getClient({
|
||||
defaultTtl: 3600000,
|
||||
});
|
||||
|
||||
// Setting a TTL on a per-object basis.
|
||||
cacheClient.set('someKey', data, { ttl: 3600000 });
|
||||
```
|
||||
|
||||
Configuring a cache store is optional. Even when no cache store is configured, the cache manager will dutifully pass plugins a manager that resolves a cache client that does not actually write or read any data.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f9fb4a205: Prep work for mysql support in backend-common
|
||||
|
||||
## 0.7.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -16,6 +16,7 @@ import { GithubCredentialsProvider } from '@backstage/integration';
|
||||
import { GitHubIntegration } from '@backstage/integration';
|
||||
import { GitLabIntegration } from '@backstage/integration';
|
||||
import * as http from 'http';
|
||||
import { JsonValue } from '@backstage/config';
|
||||
import { Knex } from 'knex';
|
||||
import { Logger } from 'winston';
|
||||
import { MergeResult } from 'isomorphic-git';
|
||||
@@ -62,6 +63,19 @@ export class BitbucketUrlReader implements UrlReader {
|
||||
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>;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class CacheManager {
|
||||
forPlugin(pluginId: string): PluginCacheManager;
|
||||
static fromConfig(config: Config): CacheManager;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export const coloredFormat: winston.Logform.Format;
|
||||
|
||||
@@ -238,6 +252,11 @@ export function loadBackendConfig(options: Options): Promise<Config>;
|
||||
// @public
|
||||
export function notFoundHandler(): RequestHandler;
|
||||
|
||||
// @public
|
||||
export type PluginCacheManager = {
|
||||
getClient: (options?: ClientOptions) => CacheClient;
|
||||
};
|
||||
|
||||
// @public
|
||||
export interface PluginDatabaseManager {
|
||||
getClient(): Promise<Knex>;
|
||||
|
||||
Vendored
+14
@@ -68,6 +68,20 @@ export interface Config {
|
||||
connection: string | object;
|
||||
};
|
||||
|
||||
/** Cache connection configuration, select cache type using the `store` field */
|
||||
cache?:
|
||||
| {
|
||||
store: 'memory';
|
||||
}
|
||||
| {
|
||||
store: 'memcache';
|
||||
/**
|
||||
* A memcache connection string in the form `user:pass@host:port`.
|
||||
* @secret
|
||||
*/
|
||||
connection: string;
|
||||
};
|
||||
|
||||
cors?: {
|
||||
origin?: string | string[];
|
||||
methods?: string | string[];
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/backend-common",
|
||||
"description": "Common functionality library for Backstage backends",
|
||||
"version": "0.7.0",
|
||||
"version": "0.8.0",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -51,6 +51,8 @@
|
||||
"git-url-parse": "^11.4.4",
|
||||
"helmet": "^4.0.0",
|
||||
"isomorphic-git": "^1.8.0",
|
||||
"keyv": "^4.0.3",
|
||||
"keyv-memcache": "^1.2.5",
|
||||
"knex": "^0.95.1",
|
||||
"lodash": "^4.17.15",
|
||||
"logform": "^2.1.1",
|
||||
@@ -62,7 +64,8 @@
|
||||
"stoppable": "^1.1.0",
|
||||
"tar": "^6.0.5",
|
||||
"unzipper": "^0.10.11",
|
||||
"winston": "^3.2.1"
|
||||
"winston": "^3.2.1",
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"pg-connection-string": "^2.3.0"
|
||||
@@ -73,8 +76,8 @@
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@types/archiver": "^5.1.0",
|
||||
"@types/compression": "^1.7.0",
|
||||
"@types/concat-stream": "^1.6.0",
|
||||
@@ -94,6 +97,7 @@
|
||||
"jest": "^26.0.1",
|
||||
"mock-fs": "^4.13.0",
|
||||
"msw": "^0.21.2",
|
||||
"mysql2": "^2.2.5",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"supertest": "^6.1.3"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { DefaultCacheClient } from './CacheClient';
|
||||
import Keyv from 'keyv';
|
||||
|
||||
describe('CacheClient', () => {
|
||||
let client: Keyv;
|
||||
const b64 = (k: string) => Buffer.from(k).toString('base64');
|
||||
|
||||
beforeEach(() => {
|
||||
client = new Keyv();
|
||||
client.get = jest.fn();
|
||||
client.set = jest.fn();
|
||||
client.delete = jest.fn();
|
||||
});
|
||||
|
||||
afterEach(() => jest.resetAllMocks());
|
||||
|
||||
describe('CacheClient.get', () => {
|
||||
it('calls client with normalized key', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const key = 'somekey';
|
||||
|
||||
await sut.get(key);
|
||||
|
||||
expect(client.get).toHaveBeenCalledWith(b64(key));
|
||||
});
|
||||
|
||||
it('calls client with normalized key (very long key)', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const key = 'x'.repeat(251);
|
||||
|
||||
await sut.get(key);
|
||||
|
||||
const spy = client.get as jest.Mock;
|
||||
const actualKey = spy.mock.calls[0][0];
|
||||
expect(actualKey).not.toEqual(b64(key));
|
||||
expect(actualKey.length).toBeLessThan(250);
|
||||
});
|
||||
|
||||
it('rejects on underlying error', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const expectedError = new Error('Some runtime error');
|
||||
client.get = jest.fn().mockRejectedValue(expectedError);
|
||||
|
||||
return expect(sut.get('someKey')).rejects.toEqual(expectedError);
|
||||
});
|
||||
|
||||
it('resolves what underlying client resolves', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const expectedValue = 'some value';
|
||||
client.get = jest.fn().mockResolvedValue(expectedValue);
|
||||
|
||||
const actualValue = await sut.get('someKey');
|
||||
|
||||
return expect(actualValue).toEqual(expectedValue);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CacheClient.set', () => {
|
||||
it('calls client with normalized key', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const key = 'somekey';
|
||||
|
||||
await sut.set(key, {});
|
||||
|
||||
const spy = client.set as jest.Mock;
|
||||
const actualKey = spy.mock.calls[0][0];
|
||||
expect(actualKey).toEqual(b64(key));
|
||||
});
|
||||
|
||||
it('passes ttl to client when given', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const expectedTtl = 3600;
|
||||
|
||||
await sut.set('someKey', {}, { ttl: expectedTtl });
|
||||
|
||||
const spy = client.set as jest.Mock;
|
||||
const actualTtl = spy.mock.calls[0][2];
|
||||
expect(actualTtl).toEqual(expectedTtl);
|
||||
});
|
||||
|
||||
it('rejects on underlying error if configured', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const expectedError = new Error('Some runtime error');
|
||||
client.set = jest.fn().mockRejectedValue(expectedError);
|
||||
|
||||
return expect(sut.set('someKey', {})).rejects.toEqual(expectedError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CacheClient.delete', () => {
|
||||
it('calls client with normalized key', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const key = 'somekey';
|
||||
|
||||
await sut.delete(key);
|
||||
|
||||
const spy = client.delete as jest.Mock;
|
||||
const actualKey = spy.mock.calls[0][0];
|
||||
expect(actualKey).toEqual(b64(key));
|
||||
});
|
||||
|
||||
it('rejects on underlying error if configured', async () => {
|
||||
const sut = new DefaultCacheClient({ client });
|
||||
const expectedError = new Error('Some runtime error');
|
||||
client.delete = jest.fn().mockRejectedValue(expectedError);
|
||||
|
||||
return expect(sut.delete('someKey')).rejects.toEqual(expectedError);
|
||||
});
|
||||
});
|
||||
});
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { JsonValue } from '@backstage/config';
|
||||
import { createHash } from 'crypto';
|
||||
import Keyv from 'keyv';
|
||||
|
||||
type CacheClientArgs = {
|
||||
client: Keyv;
|
||||
};
|
||||
|
||||
type CacheSetOptions = {
|
||||
/**
|
||||
* Optional TTL in milliseconds. Defaults to the TTL provided when the client
|
||||
* was set up (or no TTL if none are provided).
|
||||
*/
|
||||
ttl?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pre-configured, storage agnostic cache client suitable for use by
|
||||
* Backstage plugins.
|
||||
*/
|
||||
export interface CacheClient {
|
||||
/**
|
||||
* Reads data from a cache store for the given key. If no data was found,
|
||||
* returns undefined.
|
||||
*/
|
||||
get(key: string): Promise<JsonValue | undefined>;
|
||||
|
||||
/**
|
||||
* Writes the given data to a cache store, associated with the given key. An
|
||||
* optional TTL may also be provided, otherwise it defaults to the TTL that
|
||||
* was provided when the client was instantiated.
|
||||
*/
|
||||
set(key: string, value: JsonValue, options?: CacheSetOptions): Promise<void>;
|
||||
|
||||
/**
|
||||
* Removes the given key from the cache store.
|
||||
*/
|
||||
delete(key: string): Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A basic, concrete implementation of the CacheClient, suitable for almost
|
||||
* all uses in Backstage.
|
||||
*/
|
||||
export class DefaultCacheClient implements CacheClient {
|
||||
private readonly client: Keyv;
|
||||
|
||||
constructor({ client }: CacheClientArgs) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
async get(key: string): Promise<JsonValue | undefined> {
|
||||
const k = this.getNormalizedKey(key);
|
||||
return await this.client.get(k);
|
||||
}
|
||||
|
||||
async set(
|
||||
key: string,
|
||||
value: JsonValue,
|
||||
opts: CacheSetOptions = {},
|
||||
): Promise<void> {
|
||||
const k = this.getNormalizedKey(key);
|
||||
await this.client.set(k, value, opts.ttl);
|
||||
}
|
||||
|
||||
async delete(key: string): Promise<void> {
|
||||
const k = this.getNormalizedKey(key);
|
||||
await this.client.delete(k);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures keys are well-formed for any/all cache stores.
|
||||
*/
|
||||
private getNormalizedKey(candidateKey: string): string {
|
||||
// Remove potentially invalid characters.
|
||||
const wellFormedKey = Buffer.from(candidateKey).toString('base64');
|
||||
|
||||
// Memcache in particular doesn't do well with keys > 250 bytes.
|
||||
if (wellFormedKey.length < 250) {
|
||||
return wellFormedKey;
|
||||
}
|
||||
|
||||
return createHash('md5').update(candidateKey).digest('base64');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import Keyv from 'keyv';
|
||||
/* @ts-expect-error */
|
||||
import KeyvMemcache from 'keyv-memcache';
|
||||
import { DefaultCacheClient } from './CacheClient';
|
||||
import { CacheManager } from './CacheManager';
|
||||
import { NoStore } from './NoStore';
|
||||
|
||||
jest.createMockFromModule('keyv');
|
||||
jest.mock('keyv');
|
||||
jest.createMockFromModule('keyv-memcache');
|
||||
jest.mock('keyv-memcache');
|
||||
jest.mock('./CacheClient', () => {
|
||||
return {
|
||||
DefaultCacheClient: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('CacheManager', () => {
|
||||
const defaultConfigOptions = {
|
||||
backend: {
|
||||
cache: {
|
||||
store: 'memory',
|
||||
},
|
||||
},
|
||||
};
|
||||
const defaultConfig = () => new ConfigReader(defaultConfigOptions);
|
||||
|
||||
afterEach(() => jest.resetAllMocks());
|
||||
|
||||
describe('CacheManager.fromConfig', () => {
|
||||
it('accesses the backend.cache key', () => {
|
||||
const getOptionalString = jest.fn();
|
||||
const config = defaultConfig();
|
||||
config.getOptionalString = getOptionalString;
|
||||
|
||||
CacheManager.fromConfig(config);
|
||||
|
||||
expect(getOptionalString.mock.calls[0][0]).toEqual('backend.cache.store');
|
||||
expect(getOptionalString.mock.calls[1][0]).toEqual(
|
||||
'backend.cache.connection',
|
||||
);
|
||||
});
|
||||
|
||||
it('does not require the backend.cache key', () => {
|
||||
const config = new ConfigReader({ backend: {} });
|
||||
expect(() => {
|
||||
CacheManager.fromConfig(config);
|
||||
}).not.toThrowError();
|
||||
});
|
||||
|
||||
it('throws on unknown cache store', () => {
|
||||
const config = new ConfigReader({
|
||||
backend: { cache: { store: 'notreal' } },
|
||||
});
|
||||
expect(() => {
|
||||
CacheManager.fromConfig(config);
|
||||
}).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('CacheManager.forPlugin', () => {
|
||||
const manager = CacheManager.fromConfig(defaultConfig());
|
||||
|
||||
it('connects to a cache store scoped to the plugin', async () => {
|
||||
const pluginId = 'test1';
|
||||
manager.forPlugin(pluginId).getClient();
|
||||
|
||||
const client = DefaultCacheClient as jest.Mock;
|
||||
expect(client).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('provides different plugins different cache clients', async () => {
|
||||
const plugin1Id = 'test1';
|
||||
const plugin2Id = 'test2';
|
||||
const expectedTtl = 3600;
|
||||
manager.forPlugin(plugin1Id).getClient({ defaultTtl: expectedTtl });
|
||||
manager.forPlugin(plugin2Id).getClient({ defaultTtl: expectedTtl });
|
||||
|
||||
const client = DefaultCacheClient as jest.Mock;
|
||||
const cache = (Keyv as unknown) as jest.Mock;
|
||||
expect(cache).toHaveBeenCalledTimes(2);
|
||||
expect(client).toHaveBeenCalledTimes(2);
|
||||
|
||||
const plugin1CallArgs = cache.mock.calls[0];
|
||||
const plugin2CallArgs = cache.mock.calls[1];
|
||||
expect(plugin1CallArgs[0].namespace).not.toEqual(
|
||||
plugin2CallArgs[0].namespace,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CacheManager.forPlugin stores', () => {
|
||||
it('returns none client when no cache is configured', () => {
|
||||
const manager = CacheManager.fromConfig(
|
||||
new ConfigReader({ backend: {} }),
|
||||
);
|
||||
const expectedNamespace = 'test-plugin';
|
||||
manager.forPlugin(expectedNamespace).getClient();
|
||||
|
||||
const cache = (Keyv as unknown) as jest.Mock;
|
||||
const mockCalls = cache.mock.calls.splice(-1);
|
||||
const callArgs = mockCalls[0];
|
||||
expect(callArgs[0].store).toBeInstanceOf(NoStore);
|
||||
});
|
||||
|
||||
it('returns memory client when explicitly configured', () => {
|
||||
const manager = CacheManager.fromConfig(defaultConfig());
|
||||
const expectedTtl = 3600;
|
||||
const expectedNamespace = 'test-plugin';
|
||||
manager
|
||||
.forPlugin(expectedNamespace)
|
||||
.getClient({ defaultTtl: expectedTtl });
|
||||
|
||||
const cache = (Keyv as unknown) as jest.Mock;
|
||||
const mockCalls = cache.mock.calls.splice(-1);
|
||||
const callArgs = mockCalls[0];
|
||||
expect(callArgs[0]).toMatchObject({
|
||||
ttl: expectedTtl,
|
||||
namespace: expectedNamespace,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a memcache client when configured', () => {
|
||||
const expectedHost = '127.0.0.1:11211';
|
||||
const manager = CacheManager.fromConfig(
|
||||
new ConfigReader({
|
||||
backend: {
|
||||
cache: {
|
||||
store: 'memcache',
|
||||
connection: expectedHost,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
const expectedTtl = 3600;
|
||||
manager.forPlugin('test').getClient({ defaultTtl: expectedTtl });
|
||||
|
||||
const cache = (Keyv as unknown) as jest.Mock;
|
||||
const mockCacheCalls = cache.mock.calls.splice(-1);
|
||||
expect(mockCacheCalls[0][0]).toMatchObject({
|
||||
ttl: expectedTtl,
|
||||
});
|
||||
expect(mockCacheCalls[0][0].store).toBeInstanceOf(KeyvMemcache);
|
||||
const memcache = KeyvMemcache as jest.Mock;
|
||||
const mockMemcacheCalls = memcache.mock.calls.splice(-1);
|
||||
expect(mockMemcacheCalls[0][0]).toEqual(expectedHost);
|
||||
});
|
||||
});
|
||||
});
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import Keyv from 'keyv';
|
||||
// @ts-expect-error
|
||||
import KeyvMemcache from 'keyv-memcache';
|
||||
import { DefaultCacheClient, CacheClient } from './CacheClient';
|
||||
import { NoStore } from './NoStore';
|
||||
import { PluginCacheManager } from './types';
|
||||
|
||||
/**
|
||||
* Implements a Cache Manager which will automatically create new cache clients
|
||||
* for plugins when requested. All requested cache clients are created with the
|
||||
* connection details provided.
|
||||
*/
|
||||
export class CacheManager {
|
||||
/**
|
||||
* Keys represent supported `backend.cache.store` values, mapped to factories
|
||||
* that return Keyv instances appropriate to the store.
|
||||
*/
|
||||
private readonly storeFactories = {
|
||||
memcache: this.getMemcacheClient,
|
||||
memory: this.getMemoryClient,
|
||||
none: this.getNoneClient,
|
||||
};
|
||||
|
||||
private readonly store: keyof CacheManager['storeFactories'];
|
||||
private readonly connection: string;
|
||||
|
||||
/**
|
||||
* Creates a new CacheManager instance by reading from the `backend` config
|
||||
* section, specifically the `.cache` key.
|
||||
*
|
||||
* @param config The loaded application configuration.
|
||||
*/
|
||||
static fromConfig(config: Config): CacheManager {
|
||||
// If no `backend.cache` config is provided, instantiate the CacheManager
|
||||
// with a "NoStore" cache client.
|
||||
const store = config.getOptionalString('backend.cache.store') || 'none';
|
||||
const connectionString =
|
||||
config.getOptionalString('backend.cache.connection') || '';
|
||||
return new CacheManager(store, connectionString);
|
||||
}
|
||||
|
||||
private constructor(store: string, connectionString: string) {
|
||||
if (!this.storeFactories.hasOwnProperty(store)) {
|
||||
throw new Error(`Unknown cache store: ${store}`);
|
||||
}
|
||||
this.store = store as keyof CacheManager['storeFactories'];
|
||||
this.connection = connectionString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a CacheManagerInstance for consumption by plugins.
|
||||
*
|
||||
* @param pluginId The plugin that the cache manager should be created for. Plugin names should be unique.
|
||||
*/
|
||||
forPlugin(pluginId: string): PluginCacheManager {
|
||||
return {
|
||||
getClient: (opts = {}): CacheClient => {
|
||||
const concreteClient = this.getClientWithTtl(pluginId, opts.defaultTtl);
|
||||
return new DefaultCacheClient({
|
||||
client: concreteClient,
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private getClientWithTtl(pluginId: string, ttl: number | undefined): Keyv {
|
||||
return this.storeFactories[this.store].call(this, pluginId, ttl);
|
||||
}
|
||||
|
||||
private getMemcacheClient(
|
||||
pluginId: string,
|
||||
defaultTtl: number | undefined,
|
||||
): Keyv {
|
||||
return new Keyv({
|
||||
namespace: pluginId,
|
||||
ttl: defaultTtl,
|
||||
store: new KeyvMemcache(this.connection),
|
||||
});
|
||||
}
|
||||
|
||||
private getMemoryClient(
|
||||
pluginId: string,
|
||||
defaultTtl: number | undefined,
|
||||
): Keyv {
|
||||
return new Keyv({
|
||||
namespace: pluginId,
|
||||
ttl: defaultTtl,
|
||||
});
|
||||
}
|
||||
|
||||
private getNoneClient(pluginId: string): Keyv {
|
||||
return new Keyv({
|
||||
namespace: pluginId,
|
||||
store: new NoStore(),
|
||||
});
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Storage class compatible with Keyv which always results in a no-op. This is
|
||||
* used when no cache store is configured in a Backstage backend instance.
|
||||
*/
|
||||
export class NoStore extends Map<string, any> {
|
||||
clear(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
delete(_key: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
get(_key: string) {
|
||||
return;
|
||||
}
|
||||
|
||||
has(_key: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
set(_key: string, _value: any): this {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2021 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type { CacheClient } from './CacheClient';
|
||||
export { CacheManager } from './CacheManager';
|
||||
export type { PluginCacheManager } from './types';
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { CacheClient } from './CacheClient';
|
||||
|
||||
type ClientOptions = {
|
||||
/**
|
||||
* An optional default TTL (in milliseconds) to be set when getting a client
|
||||
* instance. If not provided, data will persist indefinitely by default (or
|
||||
* can be configured per entry at set-time).
|
||||
*/
|
||||
defaultTtl?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* The PluginCacheManager manages access to cache stores that Plugins get.
|
||||
*/
|
||||
export type PluginCacheManager = {
|
||||
/**
|
||||
* getClient provides backend plugins cache connections for itself.
|
||||
*
|
||||
* The purpose of this method is to allow plugins to get isolated data
|
||||
* stores so that plugins are discouraged from cache-level integration
|
||||
* and/or cache key collisions.
|
||||
*/
|
||||
getClient: (options?: ClientOptions) => CacheClient;
|
||||
};
|
||||
@@ -46,11 +46,11 @@ describe('database connection', () => {
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('tries to create a mysql connection as a passthrough', () => {
|
||||
it('returns a mysql connection', () => {
|
||||
expect(() =>
|
||||
createDatabaseClient(
|
||||
new ConfigReader({
|
||||
client: 'mysql',
|
||||
client: 'mysql2',
|
||||
connection: {
|
||||
host: '127.0.0.1',
|
||||
user: 'foo',
|
||||
@@ -59,7 +59,7 @@ describe('database connection', () => {
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toThrowError(/Cannot find module 'mysql'/);
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('accepts overrides', () => {
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import knexFactory, { Knex } from 'knex';
|
||||
import { Config } from '@backstage/config';
|
||||
import knexFactory, { Knex } from 'knex';
|
||||
import { mergeDatabaseConfig } from './config';
|
||||
import { createMysqlDatabaseClient, ensureMysqlDatabaseExists } from './mysql';
|
||||
import { createPgDatabaseClient, ensurePgDatabaseExists } from './postgres';
|
||||
import { createSqliteDatabaseClient } from './sqlite3';
|
||||
|
||||
@@ -36,6 +37,8 @@ export function createDatabaseClient(
|
||||
|
||||
if (client === 'pg') {
|
||||
return createPgDatabaseClient(dbConfig, overrides);
|
||||
} else if (client === 'mysql' || client === 'mysql2') {
|
||||
return createMysqlDatabaseClient(dbConfig, overrides);
|
||||
} else if (client === 'sqlite3') {
|
||||
return createSqliteDatabaseClient(dbConfig, overrides);
|
||||
}
|
||||
@@ -60,6 +63,8 @@ export async function ensureDatabaseExists(
|
||||
|
||||
if (client === 'pg') {
|
||||
return ensurePgDatabaseExists(dbConfig, ...databases);
|
||||
} else if (client === 'mysql' || client === 'mysql2') {
|
||||
return ensureMysqlDatabaseExists(dbConfig, ...databases);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Config, ConfigReader } from '@backstage/config';
|
||||
import {
|
||||
buildMysqlDatabaseConfig,
|
||||
createMysqlDatabaseClient,
|
||||
getMysqlConnectionConfig,
|
||||
parseMysqlConnectionString,
|
||||
} from './mysql';
|
||||
|
||||
describe('mysql', () => {
|
||||
const createMockConnection = () => ({
|
||||
host: 'acme',
|
||||
user: 'foo',
|
||||
password: 'bar',
|
||||
database: 'foodb',
|
||||
});
|
||||
|
||||
const createMockConnectionString = () => 'mysql://foo:bar@acme:3306/foodb';
|
||||
|
||||
const createConfig = (connection: any): Config =>
|
||||
new ConfigReader({ client: 'mysql2', connection });
|
||||
|
||||
describe('buildMysqlDatabaseConfig', () => {
|
||||
it('builds a mysql config', () => {
|
||||
const mockConnection = createMockConnection();
|
||||
|
||||
expect(buildMysqlDatabaseConfig(createConfig(mockConnection))).toEqual({
|
||||
client: 'mysql2',
|
||||
connection: mockConnection,
|
||||
useNullAsDefault: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('builds a connection string config', () => {
|
||||
const mockConnectionString = createMockConnectionString();
|
||||
|
||||
expect(
|
||||
buildMysqlDatabaseConfig(createConfig(mockConnectionString)),
|
||||
).toEqual({
|
||||
client: 'mysql2',
|
||||
connection: mockConnectionString,
|
||||
useNullAsDefault: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('overrides the database name', () => {
|
||||
const mockConnection = createMockConnection();
|
||||
|
||||
expect(
|
||||
buildMysqlDatabaseConfig(createConfig(mockConnection), {
|
||||
connection: { database: 'other_db' },
|
||||
}),
|
||||
).toEqual({
|
||||
client: 'mysql2',
|
||||
connection: {
|
||||
...mockConnection,
|
||||
database: 'other_db',
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('adds additional config settings', () => {
|
||||
const mockConnection = createMockConnection();
|
||||
|
||||
expect(
|
||||
buildMysqlDatabaseConfig(createConfig(mockConnection), {
|
||||
connection: { database: 'other_db' },
|
||||
pool: { min: 0, max: 7 },
|
||||
debug: true,
|
||||
}),
|
||||
).toEqual({
|
||||
client: 'mysql2',
|
||||
connection: {
|
||||
...mockConnection,
|
||||
database: 'other_db',
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
pool: { min: 0, max: 7 },
|
||||
debug: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('overrides the database from connection string', () => {
|
||||
const mockConnectionString = createMockConnectionString();
|
||||
const mockConnection = createMockConnection();
|
||||
|
||||
expect(
|
||||
buildMysqlDatabaseConfig(createConfig(mockConnectionString), {
|
||||
connection: { database: 'other_db' },
|
||||
}),
|
||||
).toEqual({
|
||||
client: 'mysql2',
|
||||
connection: {
|
||||
...mockConnection,
|
||||
port: 3306,
|
||||
database: 'other_db',
|
||||
},
|
||||
useNullAsDefault: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMysqlConnectionConfig', () => {
|
||||
it('returns the connection object back', () => {
|
||||
const mockConnection = createMockConnection();
|
||||
const config = createConfig(mockConnection);
|
||||
|
||||
expect(getMysqlConnectionConfig(config)).toEqual(mockConnection);
|
||||
});
|
||||
|
||||
it('does not parse the connection string', () => {
|
||||
const mockConnection = createMockConnection();
|
||||
const config = createConfig(mockConnection);
|
||||
|
||||
expect(getMysqlConnectionConfig(config, true)).toEqual(mockConnection);
|
||||
});
|
||||
|
||||
it('automatically parses the connection string', () => {
|
||||
const mockConnection = createMockConnection();
|
||||
const mockConnectionString = createMockConnectionString();
|
||||
const config = createConfig(mockConnectionString);
|
||||
|
||||
expect(getMysqlConnectionConfig(config)).toEqual({
|
||||
...mockConnection,
|
||||
port: 3306,
|
||||
});
|
||||
});
|
||||
|
||||
it('parses the connection string', () => {
|
||||
const mockConnection = createMockConnection();
|
||||
const mockConnectionString = createMockConnectionString();
|
||||
const config = createConfig(mockConnectionString);
|
||||
|
||||
expect(getMysqlConnectionConfig(config, true)).toEqual({
|
||||
...mockConnection,
|
||||
port: 3306,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('createMysqlDatabaseClient', () => {
|
||||
it('creates a mysql knex instance', () => {
|
||||
expect(
|
||||
createMysqlDatabaseClient(
|
||||
createConfig({
|
||||
host: 'acme',
|
||||
user: 'foo',
|
||||
password: 'bar',
|
||||
database: 'foodb',
|
||||
}),
|
||||
),
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('parseMysqlConnectionString', () => {
|
||||
it('parses a connection string uri', () => {
|
||||
expect(
|
||||
parseMysqlConnectionString(
|
||||
'mysql://u:pass@foobar:3307/dbname?ssl=require',
|
||||
),
|
||||
).toEqual({
|
||||
host: 'foobar',
|
||||
user: 'u',
|
||||
password: 'pass',
|
||||
port: 3307,
|
||||
database: 'dbname',
|
||||
ssl: 'require',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import knexFactory, { Knex } from 'knex';
|
||||
import { mergeDatabaseConfig } from './config';
|
||||
import yn from 'yn';
|
||||
|
||||
/**
|
||||
* Creates a knex mysql database connection
|
||||
*
|
||||
* @param dbConfig The database config
|
||||
* @param overrides Additional options to merge with the config
|
||||
*/
|
||||
export function createMysqlDatabaseClient(
|
||||
dbConfig: Config,
|
||||
overrides?: Knex.Config,
|
||||
) {
|
||||
const knexConfig = buildMysqlDatabaseConfig(dbConfig, overrides);
|
||||
const database = knexFactory(knexConfig);
|
||||
return database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a knex mysql database connection
|
||||
*
|
||||
* @param dbConfig The database config
|
||||
* @param overrides Additional options to merge with the config
|
||||
*/
|
||||
export function buildMysqlDatabaseConfig(
|
||||
dbConfig: Config,
|
||||
overrides?: Knex.Config,
|
||||
) {
|
||||
return mergeDatabaseConfig(
|
||||
dbConfig.get(),
|
||||
{
|
||||
connection: getMysqlConnectionConfig(dbConfig, !!overrides),
|
||||
useNullAsDefault: true,
|
||||
},
|
||||
overrides,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mysql connection config
|
||||
*
|
||||
* @param dbConfig The database config
|
||||
* @param parseConnectionString Flag to explicitly control connection string parsing
|
||||
*/
|
||||
export function getMysqlConnectionConfig(
|
||||
dbConfig: Config,
|
||||
parseConnectionString?: boolean,
|
||||
): Knex.MySqlConnectionConfig | string {
|
||||
const connection = dbConfig.get('connection') as any;
|
||||
const isConnectionString =
|
||||
typeof connection === 'string' || connection instanceof String;
|
||||
const autoParse = typeof parseConnectionString !== 'boolean';
|
||||
|
||||
const shouldParseConnectionString = autoParse
|
||||
? isConnectionString
|
||||
: parseConnectionString && isConnectionString;
|
||||
|
||||
return shouldParseConnectionString
|
||||
? parseMysqlConnectionString(connection as string)
|
||||
: connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a mysql connection string.
|
||||
*
|
||||
* e.g. mysql://examplename:somepassword@examplehost:3306/dbname
|
||||
* @param connectionString The mysql connection string
|
||||
*/
|
||||
export function parseMysqlConnectionString(
|
||||
connectionString: string,
|
||||
): Knex.MySqlConnectionConfig {
|
||||
try {
|
||||
const {
|
||||
protocol,
|
||||
username,
|
||||
password,
|
||||
port,
|
||||
hostname,
|
||||
pathname,
|
||||
searchParams,
|
||||
} = new URL(connectionString);
|
||||
|
||||
if (protocol !== 'mysql:') {
|
||||
throw new Error(`Unknown protocol ${protocol}`);
|
||||
} else if (!username || !password) {
|
||||
throw new Error(`Missing username/password`);
|
||||
} else if (!pathname.match(/^\/[^/]+$/)) {
|
||||
throw new Error(`Expected single path segment`);
|
||||
}
|
||||
|
||||
const result: Knex.MySqlConnectionConfig = {
|
||||
user: username,
|
||||
password,
|
||||
host: hostname,
|
||||
port: Number(port || 3306),
|
||||
database: decodeURIComponent(pathname.substr(1)),
|
||||
};
|
||||
|
||||
const ssl = searchParams.get('ssl');
|
||||
if (ssl) {
|
||||
result.ssl = ssl;
|
||||
}
|
||||
|
||||
const debug = searchParams.get('debug');
|
||||
if (debug) {
|
||||
result.debug = yn(debug);
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
throw new InputError(
|
||||
`Error while parsing MySQL connection string, ${e}`,
|
||||
e,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the missing mysql database if it does not exist
|
||||
*
|
||||
* @param dbConfig The database config
|
||||
* @param databases The names of the databases to create
|
||||
*/
|
||||
export async function ensureMysqlDatabaseExists(
|
||||
dbConfig: Config,
|
||||
...databases: Array<string>
|
||||
) {
|
||||
const admin = createMysqlDatabaseClient(dbConfig, {
|
||||
connection: {
|
||||
database: (null as unknown) as string,
|
||||
},
|
||||
});
|
||||
|
||||
try {
|
||||
const ensureDatabase = async (database: string) => {
|
||||
await admin.raw(`CREATE DATABASE IF NOT EXISTS ??`, [database]);
|
||||
};
|
||||
await Promise.all(databases.map(ensureDatabase));
|
||||
} finally {
|
||||
await admin.destroy();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './cache';
|
||||
export * from './config';
|
||||
export * from './database';
|
||||
export * from './discovery';
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# example-backend
|
||||
|
||||
## 0.2.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [22fd8ce2a]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [82ca1ac22]
|
||||
- Updated dependencies [f9fb4a205]
|
||||
- Updated dependencies [9a207f052]
|
||||
- Updated dependencies [16be1d093]
|
||||
- Updated dependencies [fd39d4662]
|
||||
- Updated dependencies [f9f9d633d]
|
||||
- @backstage/plugin-scaffolder-backend@0.11.1
|
||||
- @backstage/backend-common@0.8.0
|
||||
- @backstage/catalog-model@0.7.9
|
||||
- @backstage/plugin-catalog-backend@0.9.0
|
||||
- @backstage/plugin-kubernetes-backend@0.3.7
|
||||
- example-app@0.2.28
|
||||
- @backstage/plugin-app-backend@0.3.13
|
||||
- @backstage/plugin-auth-backend@0.3.10
|
||||
- @backstage/plugin-badges-backend@0.1.4
|
||||
- @backstage/plugin-code-coverage-backend@0.1.5
|
||||
- @backstage/plugin-graphql-backend@0.1.8
|
||||
- @backstage/plugin-kafka-backend@0.2.5
|
||||
- @backstage/plugin-proxy-backend@0.2.8
|
||||
- @backstage/plugin-rollbar-backend@0.1.11
|
||||
- @backstage/plugin-search-backend@0.1.5
|
||||
- @backstage/plugin-techdocs-backend@0.8.1
|
||||
- @backstage/plugin-todo-backend@0.1.5
|
||||
|
||||
## 0.2.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "example-backend",
|
||||
"version": "0.2.27",
|
||||
"version": "0.2.28",
|
||||
"main": "dist/index.cjs.js",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -27,30 +27,30 @@
|
||||
"migrate:create": "knex migrate:make -x ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.7.0",
|
||||
"@backstage/backend-common": "^0.8.0",
|
||||
"@backstage/catalog-client": "^0.3.11",
|
||||
"@backstage/catalog-model": "^0.7.8",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/plugin-app-backend": "^0.3.12",
|
||||
"@backstage/plugin-auth-backend": "^0.3.9",
|
||||
"@backstage/plugin-badges-backend": "^0.1.3",
|
||||
"@backstage/plugin-catalog-backend": "^0.8.2",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.4",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.7",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.3.6",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.4",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.7",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.10",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.11.0",
|
||||
"@backstage/plugin-search-backend": "^0.1.4",
|
||||
"@backstage/plugin-app-backend": "^0.3.13",
|
||||
"@backstage/plugin-auth-backend": "^0.3.10",
|
||||
"@backstage/plugin-badges-backend": "^0.1.4",
|
||||
"@backstage/plugin-catalog-backend": "^0.9.0",
|
||||
"@backstage/plugin-code-coverage-backend": "^0.1.5",
|
||||
"@backstage/plugin-graphql-backend": "^0.1.8",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.3.7",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.5",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.8",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.11",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.11.1",
|
||||
"@backstage/plugin-search-backend": "^0.1.5",
|
||||
"@backstage/plugin-search-backend-node": "^0.1.3",
|
||||
"@backstage/plugin-techdocs-backend": "^0.8.0",
|
||||
"@backstage/plugin-todo-backend": "^0.1.4",
|
||||
"@backstage/plugin-techdocs-backend": "^0.8.1",
|
||||
"@backstage/plugin-todo-backend": "^0.1.5",
|
||||
"@gitbeaker/node": "^28.0.2",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"azure-devops-node-api": "^10.1.1",
|
||||
"dockerode": "^3.2.1",
|
||||
"example-app": "^0.2.27",
|
||||
"example-app": "^0.2.28",
|
||||
"express": "^4.17.1",
|
||||
"express-promise-router": "^4.1.0",
|
||||
"knex": "^0.95.1",
|
||||
@@ -60,7 +60,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/dockerode": "^3.2.1",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/express-serve-static-core": "^4.17.5"
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
import Router from 'express-promise-router';
|
||||
import {
|
||||
CacheManager,
|
||||
createServiceBuilder,
|
||||
getRootLogger,
|
||||
loadBackendConfig,
|
||||
@@ -59,11 +60,13 @@ function makeCreateEnv(config: Config) {
|
||||
root.info(`Created UrlReader ${reader}`);
|
||||
|
||||
const databaseManager = SingleConnectionDatabaseManager.fromConfig(config);
|
||||
const cacheManager = CacheManager.fromConfig(config);
|
||||
|
||||
return (plugin: string): PluginEnvironment => {
|
||||
const logger = root.child({ type: 'plugin', plugin });
|
||||
const database = databaseManager.forPlugin(plugin);
|
||||
return { logger, database, config, reader, discovery };
|
||||
const cache = cacheManager.forPlugin(plugin);
|
||||
return { logger, cache, database, config, reader, discovery };
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import { Logger } from 'winston';
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
PluginCacheManager,
|
||||
PluginDatabaseManager,
|
||||
PluginEndpointDiscovery,
|
||||
UrlReader,
|
||||
@@ -24,6 +25,7 @@ import {
|
||||
|
||||
export type PluginEnvironment = {
|
||||
logger: Logger;
|
||||
cache: PluginCacheManager;
|
||||
database: PluginDatabaseManager;
|
||||
config: Config;
|
||||
reader: UrlReader;
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/catalog-model
|
||||
|
||||
## 0.7.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 10c008a3a: Renamed parameters to input in template schema
|
||||
- 16be1d093: Improve error messages when schema validation fails
|
||||
|
||||
## 0.7.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -112,6 +112,7 @@ export type Entity = {
|
||||
metadata: EntityMeta;
|
||||
spec?: JsonObject;
|
||||
relations?: EntityRelation[];
|
||||
status?: Record<string, JsonObject>;
|
||||
};
|
||||
|
||||
// @public
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/catalog-model",
|
||||
"version": "0.7.8",
|
||||
"version": "0.7.9",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -39,7 +39,7 @@
|
||||
"yup": "^0.29.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/lodash": "^4.14.151",
|
||||
|
||||
@@ -48,6 +48,14 @@ export type Entity = {
|
||||
* The relations that this entity has with other entities.
|
||||
*/
|
||||
relations?: EntityRelation[];
|
||||
|
||||
/**
|
||||
* The current status of the entity, as claimed by various sources.
|
||||
*
|
||||
* The keys are implementation defined and the values can be any JSON object
|
||||
* with semantics that match that implementation.
|
||||
*/
|
||||
status?: Record<string, JsonObject>;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,11 +42,9 @@ export function generateEntityEtag(): string {
|
||||
* the next version of this entity.
|
||||
*
|
||||
* Significance, in this case, means that we do not compare generated fields
|
||||
* such as uid, etag and generation, and we only check that no new annotations
|
||||
* are added or existing annotations were changed (since they are effectively
|
||||
* merged when doing updates).
|
||||
* such as uid, etag and generation.
|
||||
*
|
||||
* Note that this comparison does NOT take state, relations or similar into
|
||||
* Note that this comparison does NOT take status, relations or similar into
|
||||
* account. It only compares the actual input entity data, i.e. metadata and
|
||||
* spec.
|
||||
*
|
||||
@@ -86,7 +84,9 @@ export function entityHasChanges(previous: Entity, next: Entity): boolean {
|
||||
|
||||
// Remove things that we explicitly do not compare
|
||||
delete e1.relations;
|
||||
delete e1.status;
|
||||
delete e2.relations;
|
||||
delete e2.status;
|
||||
|
||||
return !lodash.isEqual(e1, e2);
|
||||
}
|
||||
|
||||
@@ -62,6 +62,15 @@
|
||||
"items": {
|
||||
"$ref": "common#relation"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"type": "object",
|
||||
"description": "The current status of the entity, as claimed by various sources.",
|
||||
"patternProperties": {
|
||||
"^.+$": {
|
||||
"$ref": "common#status"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"$id": "#relation",
|
||||
"type": "object",
|
||||
"description": "A directed relation from one entity to another.",
|
||||
"required": ["type", "source", "target"],
|
||||
"required": ["type", "target"],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"type": {
|
||||
@@ -38,13 +38,16 @@
|
||||
"pattern": "^\\w+$",
|
||||
"description": "The type of relation."
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#reference"
|
||||
},
|
||||
"target": {
|
||||
"$ref": "#reference"
|
||||
}
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"$id": "#status",
|
||||
"type": "object",
|
||||
"description": "A specific status of an entity.",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @backstage/cli
|
||||
|
||||
## 0.6.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2cd70e164: Add context for versions:bump on what version it was bumped to. Updated tests for the same.
|
||||
- 3be844496: chore: bump `ts-node` versions to 9.1.1
|
||||
- e3fc89df6: update plugins created to use react-use 17.2.4
|
||||
|
||||
## 0.6.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/cli",
|
||||
"description": "CLI for developing Backstage plugins and apps",
|
||||
"version": "0.6.10",
|
||||
"version": "0.6.11",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@@ -117,11 +117,11 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/backend-common": "^0.7.0",
|
||||
"@backstage/backend-common": "^0.8.0",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/core": "^0.7.8",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/core": "^0.7.9",
|
||||
"@backstage/dev-utils": "^0.1.14",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@backstage/theme": "^0.2.7",
|
||||
"@types/diff": "^5.0.0",
|
||||
"@types/express": "^4.17.6",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"msw": "^0.21.2",
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"ajv": "^7.0.3",
|
||||
"fs-extra": "^9.0.0",
|
||||
"json-schema": "^0.3.0",
|
||||
"json-schema-merge-allof": "^0.7.0",
|
||||
"json-schema-merge-allof": "^0.8.1",
|
||||
"typescript-json-schema": "^0.49.0",
|
||||
"yaml": "^1.9.2",
|
||||
"yup": "^0.29.3"
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/core-api
|
||||
|
||||
## 0.2.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- 675a569a9: chore: bump `react-use` dependency in all packages
|
||||
|
||||
## 0.2.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/core-api",
|
||||
"description": "Internal Core API used by Backstage plugins and apps",
|
||||
"version": "0.2.17",
|
||||
"version": "0.2.18",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -42,13 +42,13 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.9",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@backstage/test-utils-core": "^0.1.1",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/react-hooks": "^3.3.0",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"@types/zen-observable": "^0.8.0",
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @backstage/core
|
||||
|
||||
## 0.7.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- 889d89b6e: Fix state persisted in the URL make search input in the table toolbar lose their
|
||||
focus.
|
||||
- 3f988cb63: Add count of older messages when multiple messages exist in AlertDisplay
|
||||
- 675a569a9: chore: bump `react-use` dependency in all packages
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core-api@0.2.18
|
||||
|
||||
## 0.7.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/core",
|
||||
"description": "Core API used by Backstage plugins and apps",
|
||||
"version": "0.7.8",
|
||||
"version": "0.7.9",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/core-api": "^0.2.17",
|
||||
"@backstage/core-api": "^0.2.18",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/theme": "^0.2.7",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
@@ -71,11 +71,11 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/classnames": "^2.2.9",
|
||||
"@types/d3-selection": "^2.0.0",
|
||||
"@types/d3-shape": "^2.0.0",
|
||||
|
||||
@@ -1,5 +1,52 @@
|
||||
# @backstage/create-app
|
||||
|
||||
## 0.3.22
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3be844496: chore: bump `ts-node` versions to 9.1.1
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [2cd70e164]
|
||||
- Updated dependencies [0b033d07b]
|
||||
- Updated dependencies [3be844496]
|
||||
- Updated dependencies [5542de095]
|
||||
- Updated dependencies [22fd8ce2a]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [82ca1ac22]
|
||||
- Updated dependencies [81ef1d57b]
|
||||
- Updated dependencies [f9fb4a205]
|
||||
- Updated dependencies [e3fc89df6]
|
||||
- Updated dependencies [9a207f052]
|
||||
- Updated dependencies [889d89b6e]
|
||||
- Updated dependencies [16be1d093]
|
||||
- Updated dependencies [fd39d4662]
|
||||
- Updated dependencies [3f988cb63]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core@0.7.9
|
||||
- @backstage/integration-react@0.1.2
|
||||
- @backstage/test-utils@0.1.11
|
||||
- @backstage/plugin-api-docs@0.4.13
|
||||
- @backstage/plugin-catalog@0.5.7
|
||||
- @backstage/plugin-catalog-import@0.5.6
|
||||
- @backstage/plugin-explore@0.3.5
|
||||
- @backstage/plugin-github-actions@0.4.6
|
||||
- @backstage/plugin-lighthouse@0.2.16
|
||||
- @backstage/plugin-scaffolder@0.9.4
|
||||
- @backstage/plugin-scaffolder-backend@0.11.1
|
||||
- @backstage/plugin-search@0.3.6
|
||||
- @backstage/plugin-tech-radar@0.3.11
|
||||
- @backstage/plugin-techdocs@0.9.2
|
||||
- @backstage/plugin-user-settings@0.2.10
|
||||
- @backstage/cli@0.6.11
|
||||
- @backstage/backend-common@0.8.0
|
||||
- @backstage/catalog-model@0.7.9
|
||||
- @backstage/plugin-catalog-backend@0.9.0
|
||||
- @backstage/plugin-app-backend@0.3.13
|
||||
- @backstage/plugin-auth-backend@0.3.10
|
||||
- @backstage/plugin-proxy-backend@0.2.8
|
||||
- @backstage/plugin-rollbar-backend@0.1.11
|
||||
- @backstage/plugin-techdocs-backend@0.8.1
|
||||
|
||||
## 0.3.21
|
||||
|
||||
### Patch Changes
|
||||
@@ -15,8 +62,6 @@
|
||||
|
||||
+ import { DockerContainerRunner } from '@backstage/backend-common';
|
||||
|
||||
// ...
|
||||
|
||||
export default async function createPlugin({
|
||||
logger,
|
||||
config,
|
||||
@@ -76,7 +121,6 @@
|
||||
+ SingleHostDiscovery,
|
||||
+ } from '@backstage/backend-common';
|
||||
|
||||
|
||||
export default async function createPlugin({
|
||||
logger,
|
||||
config,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/create-app",
|
||||
"description": "Create app package for Backstage",
|
||||
"version": "0.3.21",
|
||||
"version": "0.3.22",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @backstage/dev-utils
|
||||
|
||||
## 0.1.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [889d89b6e]
|
||||
- Updated dependencies [16be1d093]
|
||||
- Updated dependencies [3f988cb63]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core@0.7.9
|
||||
- @backstage/integration-react@0.1.2
|
||||
- @backstage/test-utils@0.1.11
|
||||
- @backstage/plugin-catalog-react@0.1.6
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/dev-utils",
|
||||
"description": "Utilities for developing Backstage plugins.",
|
||||
"version": "0.1.13",
|
||||
"version": "0.1.14",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -29,17 +29,17 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@backstage/catalog-model": "^0.7.3",
|
||||
"@backstage/integration-react": "^0.1.1",
|
||||
"@backstage/plugin-catalog-react": "^0.1.1",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@backstage/core": "^0.7.9",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/integration-react": "^0.1.2",
|
||||
"@backstage/plugin-catalog-react": "^0.1.6",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/react": "^16.9",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
@@ -48,7 +48,7 @@
|
||||
"react-router-dom": "6.0.0-beta.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# @backstage/integration-react
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- 675a569a9: chore: bump `react-use` dependency in all packages
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [889d89b6e]
|
||||
- Updated dependencies [3f988cb63]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core@0.7.9
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/integration-react",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/config": "^0.1.2",
|
||||
"@backstage/core": "^0.7.0",
|
||||
"@backstage/core": "^0.7.9",
|
||||
"@backstage/integration": "^0.5.0",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
@@ -32,12 +32,12 @@
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.3",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.8",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/dev-utils": "^0.1.14",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"msw": "^0.21.2",
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# @backstage/techdocs-common
|
||||
|
||||
## 0.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- e04f1ccfb: Fixed a bug that prevented loading static assets from GCS, S3, Azure, and OpenStackSwift whose keys contain spaces or other special characters.
|
||||
- Updated dependencies [22fd8ce2a]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [f9fb4a205]
|
||||
- Updated dependencies [16be1d093]
|
||||
- @backstage/backend-common@0.8.0
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/techdocs-common",
|
||||
"description": "Common functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"private": false,
|
||||
@@ -38,8 +38,8 @@
|
||||
"dependencies": {
|
||||
"@azure/identity": "^1.2.2",
|
||||
"@azure/storage-blob": "^12.4.0",
|
||||
"@backstage/backend-common": "^0.7.0",
|
||||
"@backstage/catalog-model": "^0.7.8",
|
||||
"@backstage/backend-common": "^0.8.0",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/integration": "^0.5.2",
|
||||
@@ -60,7 +60,7 @@
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/fs-extra": "^9.0.5",
|
||||
"@types/git-url-parse": "^9.0.0",
|
||||
"@types/js-yaml": "^4.0.0",
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# @backstage/test-utils
|
||||
|
||||
## 0.1.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core-api@0.2.18
|
||||
|
||||
## 0.1.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/test-utils",
|
||||
"description": "Utilities to test Backstage plugins and apps.",
|
||||
"version": "0.1.10",
|
||||
"version": "0.1.11",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
@@ -29,13 +29,13 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/core-api": "^0.2.16",
|
||||
"@backstage/core-api": "^0.2.18",
|
||||
"@backstage/test-utils-core": "^0.1.1",
|
||||
"@backstage/theme": "^0.2.3",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/react": "^16.9",
|
||||
"msw": "^0.21.3",
|
||||
"react": "^16.12.0",
|
||||
@@ -45,7 +45,7 @@
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.7",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @backstage/plugin-api-docs
|
||||
|
||||
## 0.4.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- 889d89b6e: Fix state persisted in the URL make search input in the table toolbar lose their
|
||||
focus.
|
||||
- 675a569a9: chore: bump `react-use` dependency in all packages
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [889d89b6e]
|
||||
- Updated dependencies [16be1d093]
|
||||
- Updated dependencies [3f988cb63]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core@0.7.9
|
||||
- @backstage/plugin-catalog-react@0.1.6
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.4.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-api-docs",
|
||||
"version": "0.4.12",
|
||||
"version": "0.4.13",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,9 +30,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@asyncapi/react-component": "^0.23.0",
|
||||
"@backstage/catalog-model": "^0.7.7",
|
||||
"@backstage/core": "^0.7.8",
|
||||
"@backstage/plugin-catalog-react": "^0.1.4",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/core": "^0.7.9",
|
||||
"@backstage/plugin-catalog-react": "^0.1.6",
|
||||
"@backstage/theme": "^0.2.7",
|
||||
"@material-icons/font": "^1.0.2",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
@@ -49,12 +49,12 @@
|
||||
"swagger-ui-react": "^3.37.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/dev-utils": "^0.1.14",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"@types/swagger-ui-react": "^3.23.3",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @backstage/plugin-app-backend
|
||||
|
||||
## 0.3.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [22fd8ce2a]
|
||||
- Updated dependencies [f9fb4a205]
|
||||
- @backstage/backend-common@0.8.0
|
||||
|
||||
## 0.3.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-app-backend",
|
||||
"version": "0.3.12",
|
||||
"version": "0.3.13",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -29,7 +29,7 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.7.0",
|
||||
"@backstage/backend-common": "^0.8.0",
|
||||
"@backstage/config-loader": "^0.6.1",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@types/express": "^4.17.6",
|
||||
@@ -40,7 +40,7 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"msw": "^0.20.5",
|
||||
"supertest": "^6.1.3"
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @backstage/plugin-auth-backend
|
||||
|
||||
## 0.3.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [22fd8ce2a]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [f9fb4a205]
|
||||
- Updated dependencies [16be1d093]
|
||||
- @backstage/test-utils@0.1.11
|
||||
- @backstage/backend-common@0.8.0
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.3.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-auth-backend",
|
||||
"version": "0.3.9",
|
||||
"version": "0.3.10",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -29,12 +29,12 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.7.0",
|
||||
"@backstage/backend-common": "^0.8.0",
|
||||
"@backstage/catalog-client": "^0.3.11",
|
||||
"@backstage/catalog-model": "^0.7.8",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/passport": "^1.0.3",
|
||||
"compression": "^1.7.4",
|
||||
@@ -68,7 +68,7 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/body-parser": "^1.19.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express-session": "^1.17.2",
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# @backstage/plugin-badges-backend
|
||||
|
||||
## 0.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [22fd8ce2a]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [f9fb4a205]
|
||||
- Updated dependencies [16be1d093]
|
||||
- @backstage/backend-common@0.8.0
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-badges-backend",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.4",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,9 +30,9 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.7.0",
|
||||
"@backstage/backend-common": "^0.8.0",
|
||||
"@backstage/catalog-client": "^0.3.11",
|
||||
"@backstage/catalog-model": "^0.7.8",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/config": "^0.1.5",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@types/express": "^4.17.6",
|
||||
@@ -45,7 +45,7 @@
|
||||
"yn": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"supertest": "^6.1.3"
|
||||
},
|
||||
|
||||
@@ -65,4 +65,28 @@ describe('BadgeFactories', () => {
|
||||
expect(badge.kind).toEqual('entity');
|
||||
}
|
||||
});
|
||||
|
||||
it('returns valid link for entity', () => {
|
||||
const entity: Entity = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'service',
|
||||
metadata: {
|
||||
name: 'test',
|
||||
},
|
||||
};
|
||||
|
||||
const context: BadgeContext = {
|
||||
badgeUrl: '/dummy/url',
|
||||
config,
|
||||
entity,
|
||||
};
|
||||
|
||||
expect.assertions(Object.keys(badgeFactories).length);
|
||||
for (const badgeFactory of Object.values(badgeFactories)) {
|
||||
const badge = badgeFactory.createBadge(context);
|
||||
expect(badge.link).toContain(
|
||||
'http://localhost/catalog/default/service/test',
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,8 +24,8 @@ function appTitle(context: BadgeContext): string {
|
||||
|
||||
function entityUrl(context: BadgeContext): string {
|
||||
const e = context.entity!;
|
||||
const entityUri = `${e.kind}/${
|
||||
e.metadata.namespace || ENTITY_DEFAULT_NAMESPACE
|
||||
const entityUri = `${e.metadata.namespace || ENTITY_DEFAULT_NAMESPACE}/${
|
||||
e.kind
|
||||
}/${e.metadata.name}`;
|
||||
const catalogUrl = `${context.config.getString('app.baseUrl')}/catalog`;
|
||||
return `${catalogUrl}/${entityUri}`.toLowerCase();
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @backstage/plugin-badges
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- 675a569a9: chore: bump `react-use` dependency in all packages
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [889d89b6e]
|
||||
- Updated dependencies [16be1d093]
|
||||
- Updated dependencies [3f988cb63]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core@0.7.9
|
||||
- @backstage/plugin-catalog-react@0.1.6
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-badges",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -20,10 +20,10 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.7.6",
|
||||
"@backstage/core": "^0.7.8",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/core": "^0.7.9",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
"@backstage/plugin-catalog-react": "^0.1.3",
|
||||
"@backstage/plugin-catalog-react": "^0.1.6",
|
||||
"@backstage/theme": "^0.2.7",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -34,12 +34,12 @@
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/dev-utils": "^0.1.14",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"cross-fetch": "^3.0.6",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @backstage/plugin-bitrise
|
||||
|
||||
## 0.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 062bbf90f: chore: bump `@testing-library/user-event` from 12.8.3 to 13.1.8
|
||||
- 675a569a9: chore: bump `react-use` dependency in all packages
|
||||
- Updated dependencies [062bbf90f]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [889d89b6e]
|
||||
- Updated dependencies [16be1d093]
|
||||
- Updated dependencies [3f988cb63]
|
||||
- Updated dependencies [675a569a9]
|
||||
- @backstage/core@0.7.9
|
||||
- @backstage/plugin-catalog-react@0.1.6
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@backstage/plugin-bitrise",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -20,9 +20,9 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/catalog-model": "^0.7.2",
|
||||
"@backstage/core": "^0.7.8",
|
||||
"@backstage/plugin-catalog-react": "^0.1.2",
|
||||
"@backstage/catalog-model": "^0.7.9",
|
||||
"@backstage/core": "^0.7.9",
|
||||
"@backstage/plugin-catalog-react": "^0.1.6",
|
||||
"@backstage/theme": "^0.2.7",
|
||||
"@material-ui/core": "^4.11.0",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -37,12 +37,12 @@
|
||||
"recharts": "^1.8.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.6.10",
|
||||
"@backstage/dev-utils": "^0.1.13",
|
||||
"@backstage/test-utils": "^0.1.10",
|
||||
"@backstage/cli": "^0.6.11",
|
||||
"@backstage/dev-utils": "^0.1.14",
|
||||
"@backstage/test-utils": "^0.1.11",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"@types/recharts": "^1.8.15",
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @backstage/plugin-catalog-backend
|
||||
|
||||
## 0.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 9a207f052: Port `GithubOrgReaderProcessor` to support configuration via
|
||||
[`integrations`](https://backstage.io/docs/integrations/github/locations) in
|
||||
addition to [`catalog.processors.githubOrg.providers`](https://backstage.io/docs/integrations/github/org#configuration).
|
||||
The `integrations` package supports authentication with both personal access
|
||||
tokens and GitHub apps.
|
||||
|
||||
This deprecates the `catalog.processors.githubOrg.providers` configuration.
|
||||
A [`integrations` configuration](https://backstage.io/docs/integrations/github/locations)
|
||||
for the same host takes precedence over the provider configuration.
|
||||
You might need to add additional scopes for the credentials.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [22fd8ce2a]
|
||||
- Updated dependencies [10c008a3a]
|
||||
- Updated dependencies [f9fb4a205]
|
||||
- Updated dependencies [16be1d093]
|
||||
- @backstage/backend-common@0.8.0
|
||||
- @backstage/catalog-model@0.7.9
|
||||
|
||||
## 0.8.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
Vendored
+2
@@ -114,6 +114,8 @@ export interface Config {
|
||||
processors?: {
|
||||
/**
|
||||
* GithubOrgReaderProcessor configuration
|
||||
*
|
||||
* @deprecated Configure a GitHub integration instead.
|
||||
*/
|
||||
githubOrg?: {
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user