Merge branch 'master' of github.com:spotify/backstage into mob/catalog-in-gql

* 'master' of github.com:spotify/backstage: (43 commits)
  chore(deps): bump material-table from 1.62.0 to 1.68.0 (#1841)
  chore(deps-dev): bump @types/http-errors from 1.6.3 to 1.8.0 (#1884)
  chore(deps-dev): bump @types/jquery from 3.3.38 to 3.5.1 (#1886)
  chore(deps): bump react-lazylog from 4.5.2 to 4.5.3 (#1888)
  chore(deps): bump rollup-plugin-dts from 1.4.7 to 1.4.10 (#1887)
  chore(deps-dev): bump concurrently from 5.2.0 to 5.3.0 (#1885)
  docs: added configuration docs (#1863)
  chore(deps): bump replace-in-file from 6.0.0 to 6.1.0 (#1840)
  cli: eslint.backend: disallow default winston import
  feat: add rollbar to explore plugin (#1878)
  fix: update the winston logger to use namespace fix #1874
  Add backstage.io/github-actions-id to metadata
  docs: fix link to plugin documentation (#1869)
  CHANGELOG: bump to alpha.18 + note about auth CSP fix
  update gitignore
  v0.1.1-alpha.18
  package: always bump all package versions
  fix: add migration file for entity_search column fix
  Add docs for creating a GitHub OAuth application (#1857)
  auth backend: fix CSP by setting script hash
  ...
This commit is contained in:
blam
2020-08-10 10:31:39 +02:00
91 changed files with 1322 additions and 721 deletions
-6
View File
@@ -3,12 +3,6 @@
.vscode/
.vsls.json
# @spotify/web-script build output
cjs/
esm/
types/
build/
# Logs
logs
*.log
+15 -3
View File
@@ -8,16 +8,28 @@ If you encounter issues while upgrading to a newer version, don't hesitate to re
> Collect changes for the next release below
## v0.1.1-alpha.18
### @backstage/catalog-backend
- Fixed an issue with duplicated location logs. Applying the database migrations from this fix will clear the existing migration logs. https://github.com/spotify/backstage/pull/1836
- Fixed an issue with duplicated location logs. Applying the database migrations from this fix will clear the existing migration logs. [#1836](https://github.com/spotify/backstage/pull/1836)
### @backstage/auth-backend
This version fixes a breakage in CSP policies set by the auth backend. If you're facing trouble with auth in alpha.17, upgrade to alpha.18.
- OAuth redirect URLs no longer receive the `env` parameter, as it is now passed through state instead. This will likely require a reconfiguration of the OAuth app, where a redirect URL like `http://localhost:7000/auth/google/handler/frame?env=development` should now be configured as `http://localhost:7000/auth/google/handler/frame`. [#1812](https://github.com/spotify/backstage/pull/1812)
### @backstage/core
- `SignInPage` props have been changed to receive a list of provider objects instead of simple string identifiers for all but the `'guest'` and `'custom'` providers. This opens up for configuration of custom providers, but may break existing configurations. See [packages/app/src/App.tsx](https://github.com/spotify/backstage/blob/032ba401af36a760efdac41668d7000ccf09bc57/packages/app/src/App.tsx#L36) and [packages/app/src/identityProviders.ts](https://github.com/spotify/backstage/blob/032ba401af36a760efdac41668d7000ccf09bc57/packages/app/src/identityProviders.ts#L24) for how to bring back the existing providers. [#1816](https://github.com/spotify/backstage/pull/1816)
## v0.1.1-alpha.17
### @backstage/techdocs-backend
- The techdocs backend now requires more configuration to be supplied when creating the router. See [packages/backend/src/plugins/techdocs.ts](https://github.com/spotify/backstage/blob/0201fd9b4a52429519dd59e9184106ba69456deb/packages/backend/src/plugins/techdocs.ts#L42) for an example. https://github.com/spotify/backstage/pull/1736
- The techdocs backend now requires more configuration to be supplied when creating the router. See [packages/backend/src/plugins/techdocs.ts](https://github.com/spotify/backstage/blob/0201fd9b4a52429519dd59e9184106ba69456deb/packages/backend/src/plugins/techdocs.ts#L42) for an example. [#1736](https://github.com/spotify/backstage/pull/1736)
### @backstage/cli
- The `create-app` command was moved out from the CLI to a standalone package. It's now invoked with `npx @backstage/create-app` instead. https://github.com/spotify/backstage/pull/1745
- The `create-app` command was moved out from the CLI to a standalone package. It's now invoked with `npx @backstage/create-app` instead. [#1745](https://github.com/spotify/backstage/pull/1745)
+2 -1
View File
@@ -5,7 +5,8 @@ metadata:
description: |
Backstage is an open-source developer portal that puts the developer experience first.
annotations:
github.com/project-slug: 'spotify/backstage'
github.com/project-slug: spotify/backstage
backstage.io/github-actions-id: spotify/backstage
spec:
type: library
owner: Spotify
+5
View File
@@ -64,6 +64,11 @@ better yet, a pull request.
- Publishing
- [Open source and NPM](plugins/publishing.md)
- [Private/internal (non-open source)](plugins/publish-private.md)
- Configuration
- [Overview](conf/index.md)
- [Reading Configuration](conf/reading.md)
- [Writing Configuration](conf/writing.md)
- [Defining Configuration](conf/defining.md)
- Authentication and identity
- [Overview](auth/index.md)
- [Add auth provider](auth/add-auth-provider.md)
+15
View File
@@ -0,0 +1,15 @@
# Defining Configuration for your Plugin
There is currently no tooling support or helpers for defining plugin
configuration. But it's on the roadmap.
Meanwhile, document the config values that you are reading in your plugin
README.
## Format
When defining configuration for your plugin, keep keys camelCased and stick to
existing casing conventions such as `baseUrl`.
It is also usually best to prefer objects over arrays, as it makes it possible
to override individual values using separate files or environment variables.
+48
View File
@@ -0,0 +1,48 @@
# Static Configuration in Backstage
## Summary
Backstage ships with a flexible configuration system that provides a simple way
to configure Backstage apps and plugins for both local development and
production deployments. It helps get you up and running fast while adapting
Backstage for your specific environment. It also serves as a tool for plugin
authors to use to make it simple to pick up and install a plugin, while still
allowing for customization.
## Supplying Configuration
Configuration is stored in `app-config.yaml` files, with support for suffixes
such as `app-config.production.yaml` to override values for specific
environments. The configuration files themselves contain plain YAML, but with
support for loading in secrets from various sources using a `$secret` key.
It is also possible to supply configuration through environment variables, for
example `APP_CONFIG_app_baseUrl=https://staging.example.com`. However these
should be used sparingly, usually just for temporary overrides during
development or small tweaks to be able to reuse deployment artifacts in
different environments.
The configuration is shared between the frontend and backend, meaning that
values that are common between the two only needs to be defined once. Such as
the `backend.baseUrl`.
For more details, see [Writing Configuration](./writing.md).
## Reading Configuration
As a plugin developer, you likely end up wanting to define configuration that
you want users of your plugin to supply, as well as reading that configuration
in frontend and backend plugins. For more details, see
[Reading Configuration](./reading.md) and
[Defining Configuration](./defining.md).
## Further Reading
More details are provided in dedicated sections of the documentation.
- [Reading Configuration](./reading.md): How to read configuration in your
plugin.
- [Writing Configuration](./writing.md): How to provide configuration for your
Backstage deployment.
- [Defining Configuration](./defining.md): How to define configuration for users
of your plugin.
+128
View File
@@ -0,0 +1,128 @@
# Reading Backstage Configuration
## Config API
There's a common configuration API for by both frontend and backend plugins. An
API reference can be found [here](../reference/utility-apis/Config.md).
The configuration API is tailored towards failing fast in case of missing or bad
config. That's because configuration errors can always be considered programming
mistakes, and will fail deterministically.
### Type Safety
The methods for reading primitive values are typed, and validate that type at
runtime. For example `getNumber()` requires the underlying value to be a number,
and there will be no attempt to coerce other types into the desired one. If
`getNumber()` receives a string value, it will throw an error, explaining where
the bad config came from, and what the desired and actual types where.
### Reading Nested Configuration
The backing configuration data is a nested JSON structure, meaning there will be
object, within objects, arrays within objects, and so on. There are a couple of
different ways to access nested values when reading configuration, but the
primary one is to use dot-separated paths.
For example, given the following configuration:
```yaml
app:
baseUrl: http://localhost:3000
```
We can access the `baseUrl` using `config.getString('app.baseUrl')`. Because of
this syntax, configuration keys are not allowed to contain dots. In fact,
configuration keys are validated using the following RegEx:
`/^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i`.
Another option of accessing the `baseUrl` value is to create a sub-view of the
configuration, `config.getConfig('app').getString('baseUrl')`. When reading out
single values the dot-path pattern is preferred, but creating sub-views can be
useful for when you want to pass on parts of configuration to be read out by a
separate function. For example, given something like
```yaml
my-plugin:
items:
a:
title: Item A
path: /a
b:
title: Item B
path: /b
```
You can get the list of all items using the `.keys()` method, and then pass on
each sub-view to be handled individually.
```ts
for (const itemKey of config.keys('my-plugin.items')) {
const itemConfig = config.getConfig(`my-plugin.items`).getConfig(key);
const item = createItemFromConfig(itemConfig);
}
```
Another option for iterating through configuration keys is to call
`config.get('my-plugin.items')`, which simply returns the JSON structure for
that position without any validation. This can be handy to use sometimes,
especially if you're passing on config to an external library. There's a clear
benefit to the sub-view approach though, which is that the user will receive
much more detailed and relevant error messages. For example, if
`itemConfig.getString('title')` fails in the above example because a boolean was
supplied, the user will receive an error message with the full path, e.g.
`my-plugin.items.b.title`, as well as the name of the config file with the bad
value.
Note that no matter what method is used for reading out nested config, the same
merging rules apply. You will always get the same value for any way of accessing
nested config:
```ts
// Equivalent as long as a.b.c exists and is a string
config.getString('a.b.c');
config.getConfig('a.b').getString('c');
config.get('a').b.c;
```
### Required vs Optional Configuration
Reading configuration can be divided into two categories: required, and
optional. When reading optional configuration you use the optional methods such
as `getOptionalString`. These methods will simply return `undefined` if
configuration values are missing, allowing the called to fall back to default
values. The optional methods still validate types however, so receiving a string
in a call to `config.getOptionalNumber` will still throw an error.
A good pattern for reading optional configuration values is to use the `??`
operator. For example:
```ts
const title = config.getString('my-plugin.title') ?? 'My Plugin';
```
To read required configuration, simply use the methods without `Optional`, for
example `getString`. These will throw an error if there is no value available.
## Accessing ConfigApi in Frontend Plugins
The [ConfigApi](../reference/utility-apis/Config.md) in the frontend is a
[UtilityApi](../api/utility-apis.md). It's accessible as usual via the
`configApiRef` exported from `@backstage/core`.
Depending on the config api in another API is slightly different though, as the
`ConfigApi` implementation is supplied via the App itself and not instantiated
like other APIs. See
[packages/app/src/apis.ts](https://github.com/spotify/backstage/blob/244eef851f5aa19f91c7c9b5c12d5df95cf482ca/packages/app/src/apis.ts#L66)
for an example of how this wiring is done.
For standalone plugin setups in `dev/index.ts`, register a factory with a
statically mocked implementation of the config API. Use the `ConfigReader` from
`@backstage/config` to create an instance and register it for the `configApiRef`
from `@backstage/core`.
## Accessing ConfigApi in Backend Plugins
In backend plugins the configuration is passed in via options from the main
backend package. See for example
[packages/backend/src/plugins/auth.ts](https://github.com/spotify/backstage/blob/244eef851f5aa19f91c7c9b5c12d5df95cf482ca/packages/backend/src/plugins/auth.ts#L23).
+157
View File
@@ -0,0 +1,157 @@
# Writing Backstage Configuration Files
## File Format
Configuration is stored in YAML format in `app-config.yaml` files, looking
something like this:
```yaml
app:
title: Backstage Example App
baseUrl: http://localhost:3000
backend:
listen: 0.0.0.0:7000
baseUrl: http://localhost:7000
organization:
name: Spotify
proxy:
/my/api:
target: https://example.com/api/
changeOrigin: true
pathRewrite:
^/proxy/my/api/: /
```
Configuration files are typically checked in and stored in the repo that houses
the rest of the Backstage application.
## Environment Variable Overrides
Individual configuration values can be overridden using environment variables
prefixed with `APP_CONFIG_`. Everything following that prefix in the environment
variable name will be used as the config key, with `_` replaced by `.`. For
example, to override the `app.baseUrl` value, set the `APP_CONFIG_app_baseUrl`
environment variable to the desired value.
The value of the environment variable is parsed as JSON, but it will fall back
to being interpreted as a string if it fails to parse. Note that if you for
example want to pass on the string `"false"`, you need to wrap it in double
quotes, e.g. `export APP_CONFIG_example='"false"'`.
While it may be tempting to use environment variable overrides for supplying a
lot of configuration values, we recommend using them sparingly. Try to stick to
using configuration files, and only use environment variables for things like
reusing deployment artifacts across staging and production environments.
Note that environment variables work for frontend configuration too. They are
picked up by the serve tasks of `@backstage/cli` for local development, and are
injected by the entrypoint of the nginx container serving the frontend in a
production build.
## File Resolution
It is possible to have multiple configuration files, both to support different
environments, but also to define configuration that is local to specific
packages.
All `app-config.yaml` files inside the monorepo root and package root are
considered, as are files with additional `local` and environment affixes such as
`development`, for example `app-config.local.yaml`,
`app-config.production.yaml`, and `app-config.development.local.yaml`. Which
environment config files are loaded is determined by the `NODE_ENV` environment
variable. Local configuration files are always loaded, but are meant for local
development overrides and should typically be `.gitignore`'d.
All loaded configuration files are merged together using the following rules:
- Configurations have different priority, higher priority means you replace
values from configurations with lower priority.
- Primitive values are completely replaced, as are arrays and all of their
contents.
- Objects are merged together deeply, meaning that if any of the included
configs contain a value for a given path, it will be found.
The priority of the configurations is determined by the following rules, in
order:
- Configuration from the `APP_CONFIG_` environment variables has the highest
priority, followed by files.
- Files inside package directories have higher priority than those in the root
directory.
- Files with environment affixes have higher priority than ones without.
- Files with the `local` affix have higher priority than ones without.
## Secrets
Secrets are supported via a special `$secret` key, which in turn provides a
number of different ways to read in secrets. To load a configuration value as a
secret, supply an object with a single `$secret` key, and within that supply an
object that describes how the secret is loaded. For example, the following will
read the config key `backend.mySecretKey` from the environment variable
`MY_SECRET_KEY`:
```yaml
backend:
mySecretKey:
$secret:
env: MY_SECRET_KEY
```
With the above configuration, calling `config.getString('backend.mySecretKey')`
will return the value of the environment variable `MY_SECRET_KEY` when the
backend started up. All secrets are loaded at startup, so changing the contents
of secret files or environment variables will not be reflected at runtime.
Note that secrets will never be included in the frontend bundle or development
builds. When loading configuration you have to explicitly enable reading of
secrets, which is only done for the backend configuration.
As hinted at, secrets can be loaded from a bunch of different sources, and can
be extended with more. Below is a list of the currently supported methods for
loading secrets.
### Env Secrets
This reads a secret from an environment variable. For example, the following
config loads the secret from the `MY_SECRET` env var.
```yaml
$secret:
env: MY_SECRET
```
### File Secrets
This reads a secret from the entire contents of a file. The file path is
relative to the `app-config.yaml` the defines the secrets. For example, the
following reads the contents of `my-secret.txt` relative to the config file
itself:
```yaml
$secret:
file: ./my-secret.txt
```
### Data File Secrets
This reads secrets from a path within a JSON-like data file. The file path
behaves similar to file secrets, but in addition a `path` is used to point to a
specific value inside the file. Supported file extensions are `.json`, `.yaml`,
and `.yml`. For example, the following would read out `my-secret-key` from
`my-secrets.json`:
```yaml
$secret:
data: ./my-secrets.json
path: deployment.key
# my-secrets.json
{
"deployment": {
"key": "my-secret-key"
}
}
```
+1 -1
View File
@@ -2,5 +2,5 @@
"packages": ["packages/*", "plugins/*"],
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.1.1-alpha.17"
"version": "0.1.1-alpha.18"
}
+5
View File
@@ -62,6 +62,11 @@ nav:
- Publishing:
- Open source and NPM: 'plugins/publishing.md'
- Private/internal (non-open source): 'plugins/publish-private.md'
- Configuration:
- Overview: 'conf/index.md'
- Reading Configuration: 'conf/reading.md'
- Writing Configuration: 'conf/writing.md'
- Defining Configuration: 'conf/defining.md'
- Authentication and identity:
- Overview: 'auth/index.md'
- Add auth provider: 'auth/add-auth-provider.md'
+1 -1
View File
@@ -22,7 +22,7 @@
"docker-build:all": "yarn tsc && yarn build && yarn docker-build && yarn workspace example-backend build-image",
"create-plugin": "backstage-cli create-plugin",
"remove-plugin": "backstage-cli remove-plugin",
"release": "if [ \"$(git symbolic-ref --short HEAD)\" = master ]; then echo \"don't try to release master\"; exit 1; else lerna version --no-push; fi",
"release": "if [ \"$(git symbolic-ref --short HEAD)\" = master ]; then echo \"don't try to release master\"; exit 1; else lerna version --no-push --force-publish; fi",
"lerna": "lerna",
"storybook": "yarn workspace storybook start",
"build-storybook": "yarn workspace storybook build-storybook"
-1
View File
@@ -1 +0,0 @@
build/
+19 -19
View File
@@ -1,26 +1,26 @@
{
"name": "example-app",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": true,
"dependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/plugin-catalog": "^0.1.1-alpha.17",
"@backstage/plugin-circleci": "^0.1.1-alpha.17",
"@backstage/plugin-explore": "^0.1.1-alpha.17",
"@backstage/plugin-github-actions": "^0.1.1-alpha.17",
"@backstage/plugin-gitops-profiles": "^0.1.1-alpha.17",
"@backstage/plugin-graphiql": "^0.1.1-alpha.17",
"@backstage/plugin-lighthouse": "^0.1.1-alpha.17",
"@backstage/plugin-register-component": "^0.1.1-alpha.17",
"@backstage/plugin-rollbar": "^0.1.1-alpha.17",
"@backstage/plugin-scaffolder": "^0.1.1-alpha.17",
"@backstage/plugin-sentry": "^0.1.1-alpha.17",
"@backstage/plugin-tech-radar": "^0.1.1-alpha.17",
"@backstage/plugin-techdocs": "^0.1.1-alpha.17",
"@backstage/plugin-welcome": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/plugin-circleci": "^0.1.1-alpha.18",
"@backstage/plugin-explore": "^0.1.1-alpha.18",
"@backstage/plugin-github-actions": "^0.1.1-alpha.18",
"@backstage/plugin-gitops-profiles": "^0.1.1-alpha.18",
"@backstage/plugin-graphiql": "^0.1.1-alpha.18",
"@backstage/plugin-lighthouse": "^0.1.1-alpha.18",
"@backstage/plugin-register-component": "^0.1.1-alpha.18",
"@backstage/plugin-rollbar": "^0.1.1-alpha.18",
"@backstage/plugin-scaffolder": "^0.1.1-alpha.18",
"@backstage/plugin-sentry": "^0.1.1-alpha.18",
"@backstage/plugin-tech-radar": "^0.1.1-alpha.18",
"@backstage/plugin-techdocs": "^0.1.1-alpha.18",
"@backstage/plugin-welcome": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@octokit/rest": "^18.0.0",
+4 -7
View File
@@ -19,25 +19,22 @@ import {
AlertDisplay,
OAuthRequestDialog,
SignInPage,
useApi,
configApiRef,
} from '@backstage/core';
import React, { FC } from 'react';
import Root from './components/Root';
import * as plugins from './plugins';
import { apis } from './apis';
import { hot } from 'react-hot-loader/root';
import { providers } from './identityProviders';
const app = createApp({
apis,
plugins: Object.values(plugins),
components: {
SignInPage: props => {
const configApi = useApi(configApiRef);
const providersConfig = configApi.getOptionalConfig('auth.providers');
const providers = providersConfig?.keys() ?? [];
return <SignInPage {...props} providers={['guest', ...providers]} />;
return (
<SignInPage {...props} providers={['guest', 'custom', ...providers]} />
);
},
},
});
+49
View File
@@ -0,0 +1,49 @@
/*
* 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 {
googleAuthApiRef,
gitlabAuthApiRef,
oktaAuthApiRef,
githubAuthApiRef,
} from '@backstage/core';
export const providers = [
{
id: 'google-auth-provider',
title: 'Google',
message: 'Sign In using Google',
apiRef: googleAuthApiRef,
},
{
id: 'gitlab-auth-provider',
title: 'Gitlab',
message: 'Sign In using Gitlab',
apiRef: gitlabAuthApiRef,
},
{
id: 'github-auth-provider',
title: 'Github',
message: 'Sign In using Github',
apiRef: githubAuthApiRef,
},
{
id: 'okta-auth-provider',
title: 'Okta',
message: 'Sign In using Okta',
apiRef: oktaAuthApiRef,
},
];
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/backend-common",
"description": "Common functionality library for Backstage backends",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -29,9 +29,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/cli-common": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/config-loader": "^0.1.1-alpha.17",
"@backstage/cli-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/config-loader": "^0.1.1-alpha.18",
"@types/cors": "^2.8.6",
"@types/express": "^4.17.6",
"compression": "^1.7.4",
@@ -44,7 +44,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/compression": "^1.7.0",
"@types/http-errors": "^1.6.3",
"@types/morgan": "^1.9.0",
+14 -14
View File
@@ -1,6 +1,6 @@
{
"name": "example-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "dist/index.cjs.js",
"types": "src/index.ts",
"private": true,
@@ -18,18 +18,18 @@
"migrate:create": "knex migrate:make -x ts"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/plugin-auth-backend": "^0.1.1-alpha.17",
"@backstage/plugin-catalog-backend": "^0.1.1-alpha.17",
"@backstage/plugin-graphql-backend": "^0.1.1-alpha.17",
"@backstage/plugin-identity-backend": "^0.1.1-alpha.17",
"@backstage/plugin-proxy-backend": "^0.1.1-alpha.17",
"@backstage/plugin-rollbar-backend": "^0.1.1-alpha.17",
"@backstage/plugin-scaffolder-backend": "^0.1.1-alpha.17",
"@backstage/plugin-sentry-backend": "^0.1.1-alpha.17",
"@backstage/plugin-techdocs-backend": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/plugin-auth-backend": "^0.1.1-alpha.18",
"@backstage/plugin-catalog-backend": "^0.1.1-alpha.18",
"@backstage/plugin-graphql-backend": "^0.1.1-alpha.18",
"@backstage/plugin-identity-backend": "^0.1.1-alpha.18",
"@backstage/plugin-proxy-backend": "^0.1.1-alpha.18",
"@backstage/plugin-rollbar-backend": "^0.1.1-alpha.18",
"@backstage/plugin-scaffolder-backend": "^0.1.1-alpha.18",
"@backstage/plugin-sentry-backend": "^0.1.1-alpha.18",
"@backstage/plugin-techdocs-backend": "^0.1.1-alpha.18",
"@octokit/rest": "^18.0.0",
"dockerode": "^3.2.0",
"express": "^4.17.1",
@@ -39,7 +39,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/dockerode": "^2.5.32",
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/catalog-model",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.18",
"@types/json-schema": "^7.0.5",
"@types/yup": "^0.28.2",
"json-schema": "^0.2.5",
@@ -29,7 +29,7 @@
"yup": "^0.29.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/express": "^4.17.6",
"@types/jest": "^26.0.7",
"@types/lodash": "^4.14.151",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli-common",
"description": "Common functionality used by cli, backend, and create-app",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"main": "src/index.ts",
"types": "src/index.ts",
@@ -29,7 +29,7 @@
"clean": "backstage-cli clean"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/jest": "^26.0.7",
"@types/node": "^12.0.0"
},
+10
View File
@@ -55,6 +55,16 @@ module.exports = {
],
// Avoid cross-package imports
'no-restricted-imports': [2, { patterns: ['**/../../**/*/src/**'] }],
// Avoid default import from winston as it breaks at runtime
'no-restricted-syntax': [
'error',
{
message:
'Default import from winston is not allowed, import `* as winston` instead.',
selector:
'ImportDeclaration[source.value="winston"] ImportDefaultSpecifier',
},
],
},
overrides: [
{
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/cli",
"description": "CLI for developing Backstage plugins and apps",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public"
@@ -29,9 +29,9 @@
"backstage-cli": "bin/backstage-cli"
},
"dependencies": {
"@backstage/cli-common": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/config-loader": "^0.1.1-alpha.17",
"@backstage/cli-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/config-loader": "^0.1.1-alpha.18",
"@hot-loader/react-dom": "^16.13.0",
"@lerna/package-graph": "^3.18.5",
"@lerna/project": "^3.18.0",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/config-loader",
"description": "Config loading functionality used by Backstage backend, and CLI",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -30,7 +30,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.18",
"fs-extra": "^9.0.0",
"yaml": "^1.9.2",
"yup": "^0.29.1"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/config",
"description": "Config API used by Backstage core, backend, and CLI",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core-api",
"description": "Internal Core API used by Backstage plugins and apps",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,8 +29,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@types/react": "^16.9",
@@ -41,8 +41,8 @@
"zen-observable": "^0.8.15"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/test-utils-core": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/test-utils-core": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+8 -8
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/core",
"description": "Core API used by Backstage plugins and apps",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,9 +29,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/core-api": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/core-api": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -40,7 +40,7 @@
"classnames": "^2.2.6",
"clsx": "^1.1.0",
"lodash": "^4.17.15",
"material-table": "1.62.x",
"material-table": "1.68.x",
"prop-types": "^15.7.2",
"rc-progress": "^3.0.0",
"react": "^16.12.0",
@@ -50,12 +50,12 @@
"react-router": "6.0.0-beta.0",
"react-router-dom": "6.0.0-beta.0",
"react-sparklines": "^1.7.0",
"react-syntax-highlighter": "^12.2.1",
"react-syntax-highlighter": "^13.2.1",
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+1 -1
View File
@@ -166,7 +166,7 @@ export function Table<T extends object = {}>({
const MTColumns = convertColumns(columns, theme);
const defaultOptions: Options = {
const defaultOptions: Options<T> = {
headerStyle: {
textTransform: 'uppercase',
},
@@ -21,17 +21,22 @@ import { Content } from '../Content/Content';
import { ContentHeader } from '../ContentHeader/ContentHeader';
import { Grid } from '@material-ui/core';
import { SignInPageProps, useApi, configApiRef } from '@backstage/core-api';
import { useSignInProviders, SignInProviderId } from './providers';
import { useSignInProviders, getSignInProviders } from './providers';
import { IdentityProviders } from './types';
import { Progress } from '../../components/Progress';
export type Props = SignInPageProps & {
providers: SignInProviderId[];
providers: IdentityProviders;
};
export const SignInPage: FC<Props> = ({ onResult, providers }) => {
export const SignInPage: FC<Props> = ({ onResult, providers = [] }) => {
const configApi = useApi(configApiRef);
const [loading, providerElements] = useSignInProviders(providers, onResult);
const signInProviders = getSignInProviders(providers);
const [loading, providerElements] = useSignInProviders(
signInProviders,
onResult,
);
if (loading) {
return <Progress />;
@@ -17,28 +17,34 @@
import React from 'react';
import { Grid, Typography, Button } from '@material-ui/core';
import { InfoCard } from '../InfoCard/InfoCard';
import { ProviderComponent, ProviderLoader, SignInProvider } from './types';
import { useApi, githubAuthApiRef, errorApiRef } from '@backstage/core-api';
import {
ProviderComponent,
ProviderLoader,
SignInProvider,
SignInConfig,
} from './types';
import { useApi, errorApiRef } from '@backstage/core-api';
const Component: ProviderComponent = ({ onResult }) => {
const githubAuthApi = useApi(githubAuthApiRef);
const Component: ProviderComponent = ({ config, onResult }) => {
const { apiRef, title, message } = config as SignInConfig;
const authApi = useApi(apiRef);
const errorApi = useApi(errorApiRef);
const handleLogin = async () => {
try {
const identity = await githubAuthApi.getBackstageIdentity({
const identity = await authApi.getBackstageIdentity({
instantPopup: true,
});
const profile = await githubAuthApi.getProfile();
const profile = await authApi.getProfile();
onResult({
userId: identity!.id,
profile: profile!,
getIdToken: () => {
return githubAuthApi.getBackstageIdentity().then(i => i!.idToken);
return authApi.getBackstageIdentity().then(i => i!.idToken);
},
logout: async () => {
await githubAuthApi.logout();
await authApi.logout();
},
});
} catch (error) {
@@ -49,23 +55,23 @@ const Component: ProviderComponent = ({ onResult }) => {
return (
<Grid item>
<InfoCard
title="Github"
title={title}
actions={
<Button color="primary" variant="outlined" onClick={handleLogin}>
Sign In
</Button>
}
>
<Typography variant="body1">Sign In using Github</Typography>
<Typography variant="body1">{message}</Typography>
</InfoCard>
</Grid>
);
};
const loader: ProviderLoader = async apis => {
const githubAuthApi = apis.get(githubAuthApiRef)!;
const loader: ProviderLoader = async (apis, apiRef) => {
const authApi = apis.get(apiRef)!;
const identity = await githubAuthApi.getBackstageIdentity({
const identity = await authApi.getBackstageIdentity({
optional: true,
});
@@ -73,17 +79,16 @@ const loader: ProviderLoader = async apis => {
return undefined;
}
const profile = await githubAuthApi.getProfile();
const profile = await authApi.getProfile();
return {
userId: identity.id,
profile: profile!,
getIdToken: () =>
githubAuthApi.getBackstageIdentity().then(i => i!.idToken),
getIdToken: () => authApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await githubAuthApi.logout();
await authApi.logout();
},
};
};
export const githubProvider: SignInProvider = { Component, loader };
export const commonProvider: SignInProvider = { Component, loader };
@@ -1,88 +0,0 @@
/*
* 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 React from 'react';
import { Grid, Typography, Button } from '@material-ui/core';
import { InfoCard } from '../InfoCard/InfoCard';
import { ProviderComponent, ProviderLoader, SignInProvider } from './types';
import { useApi, gitlabAuthApiRef, errorApiRef } from '@backstage/core-api';
const Component: ProviderComponent = ({ onResult }) => {
const gitlabAuthApi = useApi(gitlabAuthApiRef);
const errorApi = useApi(errorApiRef);
const handleLogin = async () => {
try {
const identity = await gitlabAuthApi.getBackstageIdentity({
instantPopup: true,
});
const profile = await gitlabAuthApi.getProfile();
onResult({
userId: identity!.id,
profile: profile!,
getIdToken: () =>
gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await gitlabAuthApi.logout();
},
});
} catch (error) {
errorApi.post(error);
}
};
return (
<Grid item>
<InfoCard
title="Gitlab"
actions={
<Button color="primary" variant="outlined" onClick={handleLogin}>
Sign In
</Button>
}
>
<Typography variant="body1">Sign In using Gitlab</Typography>
</InfoCard>
</Grid>
);
};
const loader: ProviderLoader = async apis => {
const gitlabAuthApi = apis.get(gitlabAuthApiRef)!;
const identity = await gitlabAuthApi.getBackstageIdentity({
optional: true,
});
if (!identity) {
return undefined;
}
const profile = await gitlabAuthApi.getProfile();
return {
userId: identity.id,
profile: profile!,
getIdToken: () =>
gitlabAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await gitlabAuthApi.logout();
},
};
};
export const gitlabProvider: SignInProvider = { Component, loader };
@@ -1,89 +0,0 @@
/*
* 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 React from 'react';
import { Grid, Typography, Button } from '@material-ui/core';
import { InfoCard } from '../InfoCard/InfoCard';
import { ProviderComponent, ProviderLoader, SignInProvider } from './types';
import { useApi, googleAuthApiRef, errorApiRef } from '@backstage/core-api';
const Component: ProviderComponent = ({ onResult }) => {
const googleAuthApi = useApi(googleAuthApiRef);
const errorApi = useApi(errorApiRef);
const handleLogin = async () => {
try {
const identity = await googleAuthApi.getBackstageIdentity({
instantPopup: true,
});
const profile = await googleAuthApi.getProfile();
onResult({
userId: identity!.id,
profile: profile!,
getIdToken: () =>
googleAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await googleAuthApi.logout();
},
});
} catch (error) {
errorApi.post(error);
}
};
return (
<Grid item>
<InfoCard
title="Google"
actions={
<Button color="primary" variant="outlined" onClick={handleLogin}>
Sign In
</Button>
}
>
<Typography variant="body1">Sign In using Google</Typography>
</InfoCard>
</Grid>
);
};
const loader: ProviderLoader = async apis => {
const googleAuthApi = apis.get(googleAuthApiRef)!;
const identity = await googleAuthApi.getBackstageIdentity({
optional: true,
});
if (!identity) {
return undefined;
}
const profile = await googleAuthApi.getProfile();
return {
userId: identity.id,
profile: profile!,
getIdToken: () =>
googleAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await googleAuthApi.logout();
},
};
};
export const googleProvider: SignInProvider = { Component, loader };
@@ -1,93 +0,0 @@
/*
* 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 React from 'react';
import { Grid, Typography, Button } from '@material-ui/core';
import { InfoCard } from '../InfoCard/InfoCard';
import { ProviderComponent, ProviderLoader, SignInProvider } from './types';
import {
useApi,
oktaAuthApiRef,
errorApiRef,
} from '@backstage/core-api';
const Component: ProviderComponent = ({ onResult }) => {
const oktaAuthApi = useApi(oktaAuthApiRef);
const errorApi = useApi(errorApiRef);
const handleLogin = async () => {
try {
const identity = await oktaAuthApi.getBackstageIdentity({
instantPopup: true,
});
const profile = await oktaAuthApi.getProfile();
onResult({
userId: identity!.id,
profile: profile!,
getIdToken: () =>
oktaAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await oktaAuthApi.logout();
},
});
} catch (error) {
errorApi.post(error);
}
};
return (
<Grid item>
<InfoCard
title="Okta"
actions={
<Button color="primary" variant="outlined" onClick={handleLogin}>
Sign In
</Button>
}
>
<Typography variant="body1">Sign In using Okta</Typography>
</InfoCard>
</Grid>
);
};
const loader: ProviderLoader = async apis => {
const oktaAuthApi = apis.get(oktaAuthApiRef)!;
const identity = await oktaAuthApi.getBackstageIdentity({
optional: true,
});
if (!identity) {
return undefined;
}
const profile = await oktaAuthApi.getProfile();
return {
userId: identity.id,
profile: profile!,
getIdToken: () =>
oktaAuthApi.getBackstageIdentity().then(i => i!.idToken),
logout: async () => {
await oktaAuthApi.logout();
},
};
};
export const oktaProvider: SignInProvider = { Component, loader };
@@ -15,12 +15,6 @@
*/
import React, { useLayoutEffect, useState, useMemo, useCallback } from 'react';
import { guestProvider } from './guestProvider';
import { googleProvider } from './googleProvider';
import { customProvider } from './customProvider';
import { gitlabProvider } from './gitlabProvider';
import { oktaProvider } from './oktaProvider';
import { githubProvider } from './githubProvider';
import {
SignInPageProps,
SignInResult,
@@ -28,24 +22,61 @@ import {
useApiHolder,
errorApiRef,
} from '@backstage/core-api';
import { SignInProvider } from './types';
import { SignInConfig, IdentityProviders, SignInProvider } from './types';
import { commonProvider } from './commonProvider';
import { guestProvider } from './guestProvider';
import { customProvider } from './customProvider';
const PROVIDER_STORAGE_KEY = '@backstage/core:SignInPage:provider';
// Separate list here to avoid exporting internal types
export type SignInProviderId = 'guest' | string;
const signInProviders: { [id in SignInProviderId]: SignInProvider } = {
guest: guestProvider,
google: googleProvider,
gitlab: gitlabProvider,
oauth2: customProvider,
okta: oktaProvider,
github: githubProvider,
export type SignInProviderType = {
[key: string]: {
components: SignInProvider;
id: string;
config?: SignInConfig;
};
};
const signInProviders: { [key: string]: SignInProvider } = {
guest: guestProvider,
custom: customProvider,
common: commonProvider,
};
function validateIDs(id: string, providers: SignInProviderType): void {
if (id in providers)
throw new Error(
`"${id}" ID is duplicated. IDs of identity providers have to be unique.`,
);
}
export function getSignInProviders(
identityProviders: IdentityProviders,
): SignInProviderType {
const providers = identityProviders.reduce(
(acc: SignInProviderType, config) => {
if (typeof config === 'string') {
validateIDs(config, acc);
acc[config] = { components: signInProviders[config], id: config };
return acc;
}
const { id } = config as SignInConfig;
validateIDs(id, acc);
acc[id] = { components: signInProviders.common, id, config };
return acc;
},
{},
);
return providers;
}
export const useSignInProviders = (
providers: SignInProviderId[],
providers: SignInProviderType,
onResult: SignInPageProps['onResult'],
) => {
const errorApi = useApi(errorApiRef);
@@ -74,25 +105,26 @@ export const useSignInProviders = (
}
// We can't use storageApi here, as it might have a dependency on the IdentityApi
const selectedProvider = localStorage.getItem(
const selectedProviderId = localStorage.getItem(
PROVIDER_STORAGE_KEY,
) as SignInProviderId;
) as string;
// No provider selected, let the user pick one
if (selectedProvider === null) {
if (selectedProviderId === null) {
setLoading(false);
return undefined;
}
const provider = signInProviders[selectedProvider];
const provider = providers[selectedProviderId];
if (!provider) {
setLoading(false);
return undefined;
}
let didCancel = false;
provider
.loader(apiHolder)
provider.components
.loader(apiHolder, provider.config?.apiRef!)
.then(result => {
if (didCancel) {
return;
@@ -119,20 +151,24 @@ export const useSignInProviders = (
// This renders all available sign-in providers
const elements = useMemo(
() =>
providers.map(providerId => {
const provider = signInProviders[providerId];
if (!provider) {
throw new Error(`Unknown sign-in provider: ${providerId}`);
}
const { Component } = provider;
Object.keys(providers).map(key => {
const provider = providers[key];
const { Component } = provider.components;
const handleResult = (result: SignInResult) => {
localStorage.setItem(PROVIDER_STORAGE_KEY, providerId);
localStorage.setItem(PROVIDER_STORAGE_KEY, provider.id);
handleWrappedResult(result);
};
return <Component key={providerId} onResult={handleResult} />;
return (
<Component
key={provider.id}
config={provider.config!}
onResult={handleResult}
/>
);
}),
[providers, handleWrappedResult],
);
+27 -2
View File
@@ -15,12 +15,37 @@
*/
import { ComponentType } from 'react';
import { SignInPageProps, SignInResult, ApiHolder } from '@backstage/core-api';
import {
SignInPageProps,
SignInResult,
ApiHolder,
ApiRef,
OAuthApi,
ProfileInfoApi,
BackstageIdentityApi,
SessionStateApi,
} from '@backstage/core-api';
export type ProviderComponent = ComponentType<SignInPageProps>;
export type SignInConfig = {
id: string;
title: string;
message: string;
apiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi
>;
};
export type IdentityProviders = ('guest' | 'custom' | SignInConfig)[];
export type ProviderComponent = ComponentType<
SignInPageProps & { config: SignInConfig }
>;
export type ProviderLoader = (
apis: ApiHolder,
apiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionStateApi
>,
) => Promise<SignInResult | undefined>;
export type SignInProvider = {
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/create-app",
"description": "Create app package for Backstage",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public"
@@ -25,7 +25,7 @@
"lint": "backstage-cli lint"
},
"dependencies": {
"@backstage/cli-common": "^0.1.1-alpha.17",
"@backstage/cli-common": "^0.1.1-alpha.18",
"chalk": "^4.0.0",
"commander": "^4.1.1",
"fs-extra": "^9.0.0",
-5
View File
@@ -15,7 +15,6 @@
*/
import program from 'commander';
import chalk from 'chalk';
import { exitWithError } from './lib/errors';
import { version } from '../package.json';
import createApp from './createApp';
@@ -31,10 +30,6 @@ const main = (argv: string[]) => {
)
.action(createApp);
if (!process.argv.slice(2).length) {
program.outputHelp(chalk.yellow);
}
program.parse(argv);
};
@@ -71,7 +71,7 @@ const WelcomePage: FC<{}> = () => {
</Typography>
<Typography variant="body1" paragraph>
We suggest you either check out the documentation for{' '}
<Link href="https://github.com/spotify/backstage/blob/master/docs/getting-started/create-a-plugin.md">
<Link href="https://github.com/spotify/backstage/blob/master/docs/plugins/create-a-plugin.md">
creating a plugin
</Link>{' '}
or have a look in the code for the{' '}
@@ -90,7 +90,7 @@ const WelcomePage: FC<{}> = () => {
<Link href="https://backstage.io">backstage.io</Link>
</ListItem>
<ListItem>
<Link href="https://github.com/spotify/backstage/blob/master/docs/getting-started/create-a-plugin.md">
<Link href="https://github.com/spotify/backstage/blob/master/docs/plugins/create-a-plugin.md">
Create a plugin
</Link>
</ListItem>
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/dev-utils",
"description": "Utilities for developing Backstage plugins.",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,10 +29,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@testing-library/jest-dom": "^5.10.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "docgen",
"description": "Tool for generating API Documentation for itself",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": true,
"homepage": "https://backstage.io",
"repository": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "storybook",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"description": "Storybook build for core package",
"private": true,
"scripts": {
@@ -14,7 +14,7 @@
]
},
"dependencies": {
"@backstage/theme": "^0.1.1-alpha.17"
"@backstage/theme": "^0.1.1-alpha.18"
},
"devDependencies": {
"@storybook/addon-actions": "^5.3.17",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@techdocs/cli",
"description": "CLI for running TechDocs locally.",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public"
@@ -44,7 +44,7 @@
"ext": "ts"
},
"dependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"commander": "^5.1.0",
"fs-extra": "^9.0.1",
"http-proxy": "^1.18.1",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/test-utils-core",
"description": "Utilities to test Backstage core",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
+5 -5
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/test-utils",
"description": "Utilities to test Backstage plugins and apps.",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -29,10 +29,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/core-api": "^0.1.1-alpha.17",
"@backstage/test-utils-core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/core-api": "^0.1.1-alpha.18",
"@backstage/test-utils-core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/theme",
"description": "material-ui theme for use with Backstage.",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -31,7 +31,7 @@
"@material-ui/core": "^4.9.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17"
"@backstage/cli": "^0.1.1-alpha.18"
},
"files": [
"dist"
+10
View File
@@ -27,6 +27,16 @@ export AUTH_GOOGLE_CLIENT_SECRET=x
### Github
#### Creating a GitHub OAuth application
Follow this link, [Create new OAuth App](https://github.com/settings/applications/new).
1. Set Application Name to `backstage-dev` or something along those lines.
1. You can set the Homepage URL to whatever you want to.
1. The Authorization Callback URL should match the redirect URI set in Backstage.
1. Set this to `http://localhost:7000/auth/github` for local development.
1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/auth/github` for non-local deployments.
```bash
export AUTH_GITHUB_CLIENT_ID=x
export AUTH_GITHUB_CLIENT_SECRET=x
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-auth-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,8 +20,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@types/express": "^4.17.6",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
@@ -48,7 +48,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/body-parser": "^1.19.0",
"@types/cookie-parser": "^1.4.2",
"@types/jwt-decode": "2.2.1",
@@ -15,7 +15,10 @@
*/
import express from 'express';
import { AuthProviderRouteHandlers } from '../providers/types';
import {
AuthProviderRouteHandlers,
EnvironmentIdentifierFn,
} from '../providers/types';
export type EnvironmentHandlers = {
[key: string]: AuthProviderRouteHandlers;
@@ -25,13 +28,14 @@ export class EnvironmentHandler implements AuthProviderRouteHandlers {
constructor(
private readonly providerId: string,
private readonly providers: EnvironmentHandlers,
private readonly envIdentifier: EnvironmentIdentifierFn,
) {}
private getProviderForEnv(
req: express.Request,
res: express.Response,
): AuthProviderRouteHandlers | undefined {
const env = req.query.env?.toString();
const env: string | undefined = this.envIdentifier(req);
if (env && this.providers.hasOwnProperty(env)) {
return this.providers[env];
@@ -21,6 +21,7 @@ import {
THOUSAND_DAYS_MS,
TEN_MINUTES_MS,
verifyNonce,
encodeState,
OAuthProvider,
} from './OAuthProvider';
import { WebMessageResponse, OAuthProviderHandlers } from '../providers/types';
@@ -43,10 +44,11 @@ const mockResponseData = {
describe('OAuthProvider Utils', () => {
describe('verifyNonce', () => {
it('should throw error if cookie nonce missing', () => {
const state = { nonce: 'NONCE', env: 'development' };
const mockRequest = ({
cookies: {},
query: {
state: 'NONCE',
state: encodeState(state),
},
} as unknown) as express.Request;
expect(() => {
@@ -63,16 +65,17 @@ describe('OAuthProvider Utils', () => {
} as unknown) as express.Request;
expect(() => {
verifyNonce(mockRequest, 'providera');
}).toThrowError('Auth response is missing state nonce');
}).toThrowError('Invalid state passed via request');
});
it('should throw error if nonce mismatch', () => {
const state = { nonce: 'NONCEB', env: 'development' };
const mockRequest = ({
cookies: {
'providera-nonce': 'NONCEA',
},
query: {
state: 'NONCEB',
state: encodeState(state),
},
} as unknown) as express.Request;
expect(() => {
@@ -81,12 +84,13 @@ describe('OAuthProvider Utils', () => {
});
it('should not throw any error if nonce matches', () => {
const state = { nonce: 'NONCE', env: 'development' };
const mockRequest = ({
cookies: {
'providera-nonce': 'NONCE',
},
query: {
state: 'NONCE',
state: encodeState(state),
},
} as unknown) as express.Request;
expect(() => {
@@ -217,6 +221,7 @@ describe('OAuthProvider', () => {
const mockRequest = ({
query: {
scope: 'user',
env: 'development',
},
} as unknown) as express.Request;
@@ -249,12 +254,13 @@ describe('OAuthProvider', () => {
disableRefresh: false,
});
const state = { nonce: 'nonce', env: 'development' };
const mockRequest = ({
cookies: {
'test-provider-nonce': 'nonce',
},
query: {
state: 'nonce',
state: encodeState(state),
},
} as unknown) as express.Request;
+60 -8
View File
@@ -22,6 +22,7 @@ import {
OAuthProviderHandlers,
WebMessageResponse,
BackstageIdentity,
OAuthState,
} from '../providers/types';
import { InputError } from '@backstage/backend-common';
import { TokenIssuer } from '../identity';
@@ -39,14 +40,41 @@ export type Options = {
tokenIssuer: TokenIssuer;
};
const readState = (stateString: string): OAuthState => {
const state = Object.fromEntries(
new URLSearchParams(decodeURIComponent(stateString)),
);
if (
!state.nonce ||
!state.env ||
state.nonce?.length === 0 ||
state.env?.length === 0
) {
throw Error(`Invalid state passed via request`);
}
return {
nonce: state.nonce,
env: state.env,
};
};
export const encodeState = (state: OAuthState): string => {
const searchParams = new URLSearchParams();
searchParams.append('nonce', state.nonce);
searchParams.append('env', state.env);
return encodeURIComponent(searchParams.toString());
};
export const verifyNonce = (req: express.Request, providerId: string) => {
const cookieNonce = req.cookies[`${providerId}-nonce`];
const stateNonce = req.query.state;
const state: OAuthState = readState(req.query.state?.toString() ?? '');
const stateNonce = state.nonce;
if (!cookieNonce) {
throw new Error('Auth response is missing cookie nonce');
}
if (!stateNonce) {
if (stateNonce.length === 0) {
throw new Error('Auth response is missing state nonce');
}
if (cookieNonce !== stateNonce) {
@@ -64,16 +92,19 @@ export const postMessageResponse = (
res.setHeader('Content-Type', 'text/html');
res.setHeader('X-Frame-Options', 'sameorigin');
res.setHeader('Content-Security-Policy', "script-src 'unsafe-inline'");
// TODO: Make target app origin configurable globally
const script = `
(window.opener || window.parent).postMessage(JSON.parse(atob('${base64Data}')), '${appOrigin}')
window.close()
`;
const hash = crypto.createHash('sha256').update(script).digest('base64');
res.setHeader('Content-Security-Policy', `script-src 'sha256-${hash}'`);
res.end(`
<html>
<body>
<script>
(window.opener || window.parent).postMessage(JSON.parse(atob('${base64Data}')), '${appOrigin}')
window.close()
</script>
<script>${script}</script>
</body>
</html>
`);
@@ -104,6 +135,11 @@ export class OAuthProvider implements AuthProviderRouteHandlers {
async start(req: express.Request, res: express.Response): Promise<void> {
// retrieve scopes from request
const scope = req.query.scope?.toString() ?? '';
const env = req.query.env?.toString();
if (!env) {
throw new InputError('No env provided in request query parameters');
}
if (this.options.persistScopes) {
this.setScopesCookie(res, scope);
@@ -113,9 +149,12 @@ export class OAuthProvider implements AuthProviderRouteHandlers {
// set a nonce cookie before redirecting to oauth provider
this.setNonceCookie(res, nonce);
const stateObject = { nonce: nonce, env: env };
const stateParameter = encodeState(stateObject);
const queryParameters = {
scope,
state: nonce,
state: stateParameter,
};
const { url, status } = await this.providerHandlers.start(
@@ -225,6 +264,19 @@ export class OAuthProvider implements AuthProviderRouteHandlers {
}
}
identifyEnv(req: express.Request): string | undefined {
const reqEnv = req.query.env?.toString();
if (reqEnv) {
return reqEnv;
}
const stateParams = req.query.state?.toString();
if (!stateParams) {
return undefined;
}
const env = readState(stateParams).env;
return env;
}
/**
* If the response from the OAuth provider includes a Backstage identity, we
* make sure it's populated with all the information we can derive from the user ID.
@@ -23,7 +23,11 @@ import { createGoogleProvider } from './google';
import { createOAuth2Provider } from './oauth2';
import { createOktaProvider } from './okta';
import { createSamlProvider } from './saml';
import { AuthProviderConfig, AuthProviderFactory } from './types';
import {
AuthProviderConfig,
AuthProviderFactory,
EnvironmentIdentifierFn,
} from './types';
import { Config } from '@backstage/config';
import {
EnvironmentHandlers,
@@ -54,16 +58,26 @@ export const createAuthProviderRouter = (
const router = Router();
const envs = providerConfig.keys();
const envProviders: EnvironmentHandlers = {};
let envIdentifier: EnvironmentIdentifierFn | undefined;
for (const env of envs) {
const envConfig = providerConfig.getConfig(env);
const provider = factory(globalConfig, env, envConfig, logger, issuer);
if (provider) {
envProviders[env] = provider;
envIdentifier = provider.identifyEnv;
}
}
const handler = new EnvironmentHandler(providerId, envProviders);
if (typeof envIdentifier === 'undefined') {
throw Error(`No envIdentifier provided for '${providerId}'`);
}
const handler = new EnvironmentHandler(
providerId,
envProviders,
envIdentifier,
);
router.get('/start', handler.start.bind(handler));
router.get('/handler/frame', handler.frameHandler.bind(handler));
@@ -126,7 +126,7 @@ export class GithubAuthProvider implements OAuthProviderHandlers {
export function createGithubProvider(
{ baseUrl }: AuthProviderConfig,
env: string,
_: string,
envConfig: Config,
logger: Logger,
tokenIssuer: TokenIssuer,
@@ -148,7 +148,7 @@ export function createGithubProvider(
const userProfileURL = enterpriseInstanceUrl
? `${enterpriseInstanceUrl}/api/v3/user`
: undefined;
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
const callbackURL = `${baseUrl}/${providerId}/handler/frame`;
const opts = {
clientID,
@@ -133,7 +133,7 @@ export class GitlabAuthProvider implements OAuthProviderHandlers {
export function createGitlabProvider(
{ baseUrl }: AuthProviderConfig,
env: string,
_: string,
envConfig: Config,
logger: Logger,
tokenIssuer: TokenIssuer,
@@ -145,7 +145,7 @@ export function createGitlabProvider(
const clientSecret = envConfig.getString('clientSecret');
const audience = envConfig.getString('audience');
const baseURL = audience || 'https://gitlab.com';
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
const callbackURL = `${baseUrl}/${providerId}/handler/frame`;
const opts = {
clientID,
@@ -145,7 +145,7 @@ export class GoogleAuthProvider implements OAuthProviderHandlers {
export function createGoogleProvider(
{ baseUrl }: AuthProviderConfig,
env: string,
_: string,
envConfig: Config,
logger: Logger,
tokenIssuer: TokenIssuer,
@@ -155,7 +155,7 @@ export function createGoogleProvider(
const appOrigin = envConfig.getString('appOrigin');
const clientID = envConfig.getString('clientId');
const clientSecret = envConfig.getString('clientSecret');
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
const callbackURL = `${baseUrl}/${providerId}/handler/frame`;
const opts = {
clientID,
@@ -143,7 +143,7 @@ export class OAuth2AuthProvider implements OAuthProviderHandlers {
export function createOAuth2Provider(
{ baseUrl }: AuthProviderConfig,
env: string,
_: string,
envConfig: Config,
logger: Logger,
tokenIssuer: TokenIssuer,
@@ -153,7 +153,7 @@ export function createOAuth2Provider(
const appOrigin = envConfig.getString('appOrigin');
const clientID = envConfig.getString('clientId');
const clientSecret = envConfig.getString('clientSecret');
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
const callbackURL = `${baseUrl}/${providerId}/handler/frame`;
const authorizationURL = envConfig.getString('authorizationURL');
const tokenURL = envConfig.getString('tokenURL');
@@ -165,7 +165,7 @@ export class OktaAuthProvider implements OAuthProviderHandlers {
export function createOktaProvider(
{ baseUrl }: AuthProviderConfig,
env: string,
_: string,
envConfig: Config,
logger: Logger,
tokenIssuer: TokenIssuer,
@@ -176,7 +176,7 @@ export function createOktaProvider(
const clientID = envConfig.getString('clientId');
const clientSecret = envConfig.getString('clientSecret');
const audience = envConfig.getString('audience');
const callbackURL = `${baseUrl}/${providerId}/handler/frame?env=${env}`;
const callbackURL = `${baseUrl}/${providerId}/handler/frame`;
const opts = {
audience,
@@ -106,6 +106,10 @@ export class SamlAuthProvider implements AuthProviderRouteHandlers {
async logout(_req: express.Request, res: express.Response): Promise<void> {
res.send('noop');
}
identifyEnv(): string | undefined {
return undefined;
}
}
type SAMLProviderOptions = {
@@ -203,6 +203,15 @@ export interface AuthProviderRouteHandlers {
* @param {express.Response} res
*/
logout?(req: express.Request, res: express.Response): Promise<void>;
/**
*(Optional) A method to identify the environment Context of the Request
*
*Request
*- contains the environment context information encoded in the request
* @param {express.Request} req
*/
identifyEnv?(req: express.Request): string | undefined;
}
export type AuthProviderFactory = (
@@ -332,3 +341,14 @@ export type SAMLProviderConfig = {
export type SAMLEnvironmentProviderConfig = {
[key: string]: SAMLProviderConfig;
};
export type OAuthState = {
/* A type for the serialized value in the `state` parameter of the OAuth authorization flow
*/
nonce: string;
env: string;
};
export type EnvironmentIdentifierFn = (
req: express.Request,
) => string | undefined;
@@ -0,0 +1,43 @@
/*
* 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.
*/
// @ts-check
/**
* @param {import('knex')} knex
*/
exports.up = async function up(knex) {
try {
await knex.schema.alterTable('entities_search', table => {
table.text('value').nullable().alter();
});
} catch (e) {
// Sqlite does not support alter column.
}
};
/**
* @param {import('knex')} knex
*/
exports.down = async function down(knex) {
try {
await knex.schema.alterTable('entities_search', table => {
table.string('value').nullable().alter();
});
} catch (e) {
// Sqlite does not support alter column.
}
};
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
@@ -39,7 +39,7 @@
"yup": "^0.29.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/lodash": "^4.14.151",
"@types/node-fetch": "^2.5.7",
"@types/supertest": "^2.0.8",
+10 -10
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-catalog",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,12 +21,12 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/plugin-github-actions": "^0.1.1-alpha.17",
"@backstage/plugin-scaffolder": "^0.1.1-alpha.17",
"@backstage/plugin-sentry": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-github-actions": "^0.1.1-alpha.18",
"@backstage/plugin-scaffolder": "^0.1.1-alpha.18",
"@backstage/plugin-sentry": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -39,9 +39,9 @@
"swr": "^0.2.2"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/react-hooks": "^3.3.0",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-circleci",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"postpack": "backstage-cli postpack"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -36,8 +36,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-explore",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -32,9 +32,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -88,6 +88,15 @@ const toolsCards = [
image: 'https://miro.medium.com/max/801/1*R28u8gj-hVdDFISoYqPhrQ.png',
tags: ['gitops', 'dev'],
},
{
title: 'Rollbar',
description:
'Error monitoring and crash reporting for agile development and continuous delivery',
url: '/rollbar',
image:
'https://images.ctfassets.net/cj4mgtttlyx7/4DfiWj9CbuHBi10uWK7JHn/5e94a6c5dbd5d50bdcd8d9e78f88689b/rollbar-seo.png',
tags: ['rollbar', 'monitoring', 'errors'],
},
];
const ExplorePluginPage: FC<{}> = () => {
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-github-actions",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,11 +22,11 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/core-api": "^0.1.1-alpha.17",
"@backstage/plugin-catalog": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/core-api": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -39,8 +39,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+5
View File
@@ -23,6 +23,10 @@ export const rootRouteRef = createRouteRef({
path: '/github-actions',
title: 'GitHub Actions',
});
export const projectRouteRef = createRouteRef({
path: '/github-actions/:kind/:optionalNamespaceAndName/',
title: 'GitHub Actions for project',
});
export const buildRouteRef = createRouteRef({
path: '/github-actions/workflow-run/:id',
title: 'GitHub Actions Workflow Run',
@@ -32,6 +36,7 @@ export const plugin = createPlugin({
id: 'github-actions',
register({ router }) {
router.addRoute(rootRouteRef, WorkflowRunsPage);
router.addRoute(projectRouteRef, WorkflowRunsPage);
router.addRoute(buildRouteRef, WorkflowRunDetailsPage);
},
});
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-gitops-profiles",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -32,8 +32,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6 -6
View File
@@ -1,7 +1,7 @@
{
"name": "@backstage/plugin-graphiql",
"description": "Backstage plugin for browsing GraphQL APIs",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"private": false,
"publishConfig": {
"access": "public",
@@ -31,8 +31,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -43,9 +43,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-graphql-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,9 +20,9 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/plugin-catalog-graphql": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@backstage/plugin-catalog-graphql": "^0.1.1-alpha.18",
"@graphql-modules/core": "^0.7.17",
"@types/express": "^4.17.6",
"apollo-server": "^2.16.0",
@@ -36,7 +36,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/supertest": "^2.0.8",
"eslint-plugin-graphql": "^4.0.0",
"msw": "^0.19.5",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-identity-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@types/express": "^4.17.6",
"compression": "^1.7.4",
"cors": "^2.8.5",
@@ -33,7 +33,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"jest-fetch-mock": "^3.0.3"
},
"files": [
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-lighthouse",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -33,9 +33,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-proxy-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -19,8 +19,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@types/express": "^4.17.6",
"express": "^4.17.1",
"express-promise-router": "^3.0.3",
@@ -34,7 +34,7 @@
"yup": "^0.29.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/node-fetch": "^2.5.7",
"@types/supertest": "^2.0.8",
"@types/uuid": "^8.0.0",
@@ -15,7 +15,7 @@
*/
import { createRouter } from './router';
import winston from 'winston';
import * as winston from 'winston';
import { ConfigReader } from '@backstage/config';
import { loadBackendConfig } from '@backstage/backend-common';
+7 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-register-component",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/plugin-catalog": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -36,8 +36,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-rollbar-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@types/express": "^4.17.6",
"axios": "^0.19.2",
"camelcase-keys": "^6.2.2",
@@ -36,7 +36,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/supertest": "^2.0.8",
"jest-fetch-mock": "^3.0.3",
"supertest": "^4.0.2"
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-rollbar",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -35,9 +35,9 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/react-hooks": "^3.3.0",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-scaffolder-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@octokit/rest": "^18.0.0",
"@types/dockerode": "^2.5.32",
"@types/express": "^4.17.6",
@@ -43,7 +43,7 @@
"yaml": "^1.10.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@octokit/types": "^5.0.1",
"@types/fs-extra": "^9.0.1",
"@types/git-url-parse": "^9.0.0",
@@ -1,6 +1,11 @@
name: Frontend CI
on: [push, pull_request]
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
@@ -3,6 +3,9 @@ kind: Component
metadata:
name: {{cookiecutter.component_id}}
description: {{cookiecutter.description}}
annotations:
github.com/project-slug: {{cookiecutter.storePath}}
backstage.io/github-actions-id: {{cookiecutter.storePath}}
spec:
type: website
lifecycle: experimental
@@ -0,0 +1,21 @@
name: Java CI with Maven
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Build with Maven
run: mvn -B package --file pom.xml
@@ -3,6 +3,9 @@ kind: Component
metadata:
name: {{cookiecutter.component_id}}
description: {{cookiecutter.description}}
annotations:
github.com/project-slug: {{cookiecutter.storePath}}
backstage.io/github-actions-id: {{cookiecutter.storePath}}
spec:
type: service
lifecycle: experimental
@@ -17,5 +17,5 @@ curl \
--location \
--request POST 'localhost:7000/catalog/locations' \
--header 'Content-Type: application/json' \
--data-raw "{\"type\": \"github\", \"target\": \"https://github.com/benjdlambert/cookiecutter-golang/blob/master/template.yaml\"}"
--data-raw "{\"type\": \"github\", \"target\": \"https://github.com/spotify/cookiecutter-golang/blob/master/template.yaml\"}"
echo
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import winston from 'winston';
import * as winston from 'winston';
import { JsonValue } from '@backstage/config';
export const makeLogStream = (meta: Record<string, JsonValue>) => {
+8 -8
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-scaffolder",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,10 +21,10 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/plugin-catalog": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/plugin-catalog": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -41,9 +41,9 @@
"swr": "^0.2.2"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-sentry-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -20,7 +20,7 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@types/express": "^4.17.6",
"axios": "^0.19.2",
"compression": "^1.7.4",
@@ -34,7 +34,7 @@
"yn": "^4.0.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"jest-fetch-mock": "^3.0.3"
},
"files": [
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-sentry",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,8 +21,8 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -34,8 +34,8 @@
"timeago.js": "^4.0.2"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-tech-radar",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/test-utils-core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/test-utils-core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -35,8 +35,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
-1
View File
@@ -1,2 +1 @@
static
!src/techdocs/stages/build
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs-backend",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -21,9 +21,9 @@
"mock-data": "./scripts/mock-data.sh"
},
"dependencies": {
"@backstage/backend-common": "^0.1.1-alpha.17",
"@backstage/catalog-model": "^0.1.1-alpha.17",
"@backstage/config": "^0.1.1-alpha.17",
"@backstage/backend-common": "^0.1.1-alpha.18",
"@backstage/catalog-model": "^0.1.1-alpha.18",
"@backstage/config": "^0.1.1-alpha.18",
"@types/dockerode": "^2.5.34",
"@types/express": "^4.17.6",
"dockerode": "^3.2.1",
@@ -35,7 +35,7 @@
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@types/node-fetch": "^2.5.7",
"supertest": "^4.0.2"
},
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-techdocs",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
@@ -22,9 +22,9 @@
"clean": "backstage-cli clean"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/test-utils": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/test-utils": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -36,8 +36,8 @@
"sanitize-html": "^1.27.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-welcome",
"version": "0.1.1-alpha.17",
"version": "0.1.1-alpha.18",
"main": "src/index.ts",
"types": "src/index.ts",
"private": false,
@@ -21,8 +21,8 @@
"start": "backstage-cli plugin:serve"
},
"dependencies": {
"@backstage/core": "^0.1.1-alpha.17",
"@backstage/theme": "^0.1.1-alpha.17",
"@backstage/core": "^0.1.1-alpha.18",
"@backstage/theme": "^0.1.1-alpha.18",
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
@@ -32,8 +32,8 @@
"react-use": "^15.3.3"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.17",
"@backstage/dev-utils": "^0.1.1-alpha.17",
"@backstage/cli": "^0.1.1-alpha.18",
"@backstage/dev-utils": "^0.1.1-alpha.18",
"@testing-library/jest-dom": "^5.10.1",
"@testing-library/react": "^10.4.1",
"@testing-library/user-event": "^12.0.7",
@@ -113,7 +113,7 @@ const WelcomePage = () => {
</Typography>
<Typography variant="body1" paragraph>
We suggest you either check out the documentation for{' '}
<Link href="https://github.com/spotify/backstage/blob/master/docs/getting-started/create-a-plugin.md">
<Link href="https://github.com/spotify/backstage/blob/master/docs/plugins/create-a-plugin.md">
creating a plugin
</Link>{' '}
or have a look in the code for the{' '}
@@ -135,7 +135,7 @@ const WelcomePage = () => {
<Link href="https://backstage.io">backstage.io</Link>
</ListItem>
<ListItem>
<Link href="https://github.com/spotify/backstage/blob/master/docs/getting-started/create-a-plugin.md">
<Link href="https://github.com/spotify/backstage/blob/master/docs/plugins/create-a-plugin.md">
Create a plugin
</Link>
</ListItem>
+312 -125
View File
@@ -1938,43 +1938,45 @@
aggregate-error "3.0.1"
tslib "~2.0.0"
"@hapi/address@^2.1.2":
version "2.1.4"
resolved "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==
"@hapi/formula@^1.2.0":
version "1.2.0"
resolved "https://registry.npmjs.org/@hapi/formula/-/formula-1.2.0.tgz#994649c7fea1a90b91a0a1e6d983523f680e10cd"
integrity sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA==
"@hapi/hoek@^8.2.4", "@hapi/hoek@^8.3.0":
version "8.5.1"
resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06"
integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==
"@hapi/joi@^16.1.8":
version "16.1.8"
resolved "https://registry.npmjs.org/@hapi/joi/-/joi-16.1.8.tgz#84c1f126269489871ad4e2decc786e0adef06839"
integrity sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg==
"@hapi/address@^4.0.1":
version "4.1.0"
resolved "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz#d60c5c0d930e77456fdcde2598e77302e2955e1d"
integrity sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==
dependencies:
"@hapi/address" "^2.1.2"
"@hapi/formula" "^1.2.0"
"@hapi/hoek" "^8.2.4"
"@hapi/pinpoint" "^1.0.2"
"@hapi/topo" "^3.1.3"
"@hapi/hoek" "^9.0.0"
"@hapi/pinpoint@^1.0.2":
version "1.0.2"
resolved "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-1.0.2.tgz#025b7a36dbbf4d35bf1acd071c26b20ef41e0d13"
integrity sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ==
"@hapi/formula@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz#edade0619ed58c8e4f164f233cda70211e787128"
integrity sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==
"@hapi/topo@^3.1.3":
version "3.1.6"
resolved "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29"
integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==
"@hapi/hoek@^9.0.0":
version "9.0.4"
resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz#e80ad4e8e8d2adc6c77d985f698447e8628b6010"
integrity sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw==
"@hapi/joi@^17.1.1":
version "17.1.1"
resolved "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz#9cc8d7e2c2213d1e46708c6260184b447c661350"
integrity sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==
dependencies:
"@hapi/hoek" "^8.3.0"
"@hapi/address" "^4.0.1"
"@hapi/formula" "^2.0.0"
"@hapi/hoek" "^9.0.0"
"@hapi/pinpoint" "^2.0.0"
"@hapi/topo" "^5.0.0"
"@hapi/pinpoint@^2.0.0":
version "2.0.0"
resolved "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz#805b40d4dbec04fc116a73089494e00f073de8df"
integrity sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==
"@hapi/topo@^5.0.0":
version "5.0.0"
resolved "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7"
integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hot-loader/react-dom@^16.13.0":
version "16.13.0"
@@ -3262,9 +3264,9 @@
react-lifecycles-compat "^3.0.4"
"@rjsf/core@^2.1.0":
version "2.1.0"
resolved "https://registry.npmjs.org/@rjsf/core/-/core-2.1.0.tgz#00130c89959850cc90224fd14c82feaecc2b9dc8"
integrity sha512-2A65RZ3I/RVVNfJUTYUkFs4snX02GHzql6o/KcLBBoG8G8+gr9ZeIi3+JEbe2mOEN02rIPnyJtBkl6C7QajyAw==
version "2.2.2"
resolved "https://registry.npmjs.org/@rjsf/core/-/core-2.2.2.tgz#1ebb6fe47448998f3b54e2dea8d58de8a46014dc"
integrity sha512-4d6DHIiTJEkUq5vyl4LIxLGIYYKKnHcprf94oVchUtGQvRFjNUDFxeFQoyr90oaxcBMs2WDDcCgjcFaKVyfErg==
dependencies:
"@babel/runtime-corejs2" "^7.8.7"
"@types/json-schema" "^7.0.4"
@@ -4574,9 +4576,9 @@
integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ==
"@types/http-errors@^1.6.3":
version "1.6.3"
resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.6.3.tgz#619a55768eab98299e8f76747339f3373f134e69"
integrity sha512-4KCE/agIcoQ9bIfa4sBxbZdnORzRjIw8JNQPLfqoNv7wQl/8f8mRbW68Q8wBsQFoJkPUHGlQYZ9sqi5WpfGSEQ==
version "1.8.0"
resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69"
integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA==
"@types/http-proxy-middleware@*":
version "0.19.3"
@@ -4636,9 +4638,9 @@
pretty-format "^25.2.1"
"@types/jquery@^3.3.34":
version "3.3.38"
resolved "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.38.tgz#6385f1e1b30bd2bff55ae8ee75ea42a999cc3608"
integrity sha512-nkDvmx7x/6kDM5guu/YpXkGZ/Xj/IwGiLDdKM99YA5Vag7pjGyTJ8BNUh/6hxEn/sEu5DKtyRgnONJ7EmOoKrA==
version "3.5.1"
resolved "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.1.tgz#cebb057acf5071c40e439f30e840c57a30d406c3"
integrity sha512-Tyctjh56U7eX2b9udu3wG853ASYP0uagChJcQJXLUXEU6C/JiW5qt5dl8ao01VRj1i5pgXPAf8f1mq4+FDLRQg==
dependencies:
"@types/sizzle" "*"
@@ -4647,12 +4649,7 @@
resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f"
integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==
"@types/json-schema@*", "@types/json-schema@^7.0.3":
version "7.0.4"
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
"@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5":
"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5":
version "7.0.5"
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==
@@ -5449,6 +5446,11 @@ JSONStream@^1.0.4, JSONStream@^1.3.4:
jsonparse "^1.2.0"
through ">=2.2.7 <3"
abab@^1.0.0:
version "1.0.4"
resolved "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=
abab@^2.0.0, abab@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a"
@@ -5467,6 +5469,13 @@ accepts@^1.3.5, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
mime-types "~2.1.24"
negotiator "0.6.2"
acorn-globals@^1.0.4:
version "1.0.9"
resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz#55bb5e98691507b74579d0513413217c380c54cf"
integrity sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=
dependencies:
acorn "^2.1.0"
acorn-globals@^4.1.0:
version "4.3.4"
resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
@@ -5498,6 +5507,11 @@ acorn-walk@^7.1.1:
resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e"
integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==
acorn@^2.1.0, acorn@^2.4.0:
version "2.7.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz#ab6e7d9d886aaca8b085bc3312b79a198433f0e7"
integrity sha1-q259nYhqrKiwhbwzEreaGYQz8Oc=
acorn@^5.5.3:
version "5.7.4"
resolved "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
@@ -6629,6 +6643,11 @@ balanced-match@^1.0.0:
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
base64-arraybuffer@^0.1.5:
version "0.1.5"
resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
base64-js@^1.0.2:
version "1.3.1"
resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
@@ -7243,6 +7262,16 @@ caniuse-lite@^1.0.30001093:
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001107.tgz#809360df7a5b3458f627aa46b0f6ed6d5239da9a"
integrity sha512-86rCH+G8onCmdN4VZzJet5uPELII59cUzDphko3thQFgAQG1RNa+sVLDoALIhRYmflo5iSIzWY3vu1XTWtNMQQ==
canvg@1.5.3:
version "1.5.3"
resolved "https://registry.npmjs.org/canvg/-/canvg-1.5.3.tgz#aad17915f33368bf8eb80b25d129e3ae922ddc5f"
integrity sha512-7Gn2IuQzvUQWPIuZuFHrzsTM0gkPz2RRT9OcbdmA03jeKk8kltrD8gqUzNX15ghY/4PV5bbe5lmD6yDLDY6Ybg==
dependencies:
jsdom "^8.1.0"
rgbcolor "^1.0.1"
stackblur-canvas "^1.4.1"
xmldom "^0.1.22"
capture-exit@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4"
@@ -7825,9 +7854,9 @@ concat-with-sourcemaps@^1.1.0:
source-map "^0.6.1"
concurrently@^5.2.0:
version "5.2.0"
resolved "https://registry.npmjs.org/concurrently/-/concurrently-5.2.0.tgz#ead55121d08a0fc817085584c123cedec2e08975"
integrity sha512-XxcDbQ4/43d6CxR7+iV8IZXhur4KbmEJk1CetVMUqCy34z9l0DkszbY+/9wvmSnToTej0SYomc2WSRH+L0zVJw==
version "5.3.0"
resolved "https://registry.npmjs.org/concurrently/-/concurrently-5.3.0.tgz#7500de6410d043c912b2da27de3202cb489b1e7b"
integrity sha512-8MhqOB6PWlBfA2vJ8a0bSFKATOdWlHiQlk11IfmQBPaHVP8oP2gsh2MObE6UR3hqDHqvaIvLTyceNW6obVuFHQ==
dependencies:
chalk "^2.4.2"
date-fns "^2.0.1"
@@ -8070,12 +8099,7 @@ core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.7, core-js@^2.6.5:
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
core-js@^3.0.1, core-js@^3.0.4:
version "3.6.4"
resolved "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647"
integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==
core-js@^3.5.0:
core-js@^3.0.1, core-js@^3.0.4, core-js@^3.5.0:
version "3.6.5"
resolved "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a"
integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==
@@ -8281,6 +8305,13 @@ css-in-js-utils@^2.0.0:
hyphenate-style-name "^1.0.2"
isobject "^3.0.1"
css-line-break@1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/css-line-break/-/css-line-break-1.0.1.tgz#19f2063a33e95fb2831b86446c0b80c188af450a"
integrity sha1-GfIGOjPpX7KDG4ZEbAuAwYivRQo=
dependencies:
base64-arraybuffer "^0.1.5"
css-loader@^3.0.0, css-loader@^3.5.3:
version "3.6.0"
resolved "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645"
@@ -8480,7 +8511,7 @@ csso@^4.0.2:
dependencies:
css-tree "1.0.0-alpha.37"
cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6:
cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0", "cssom@>= 0.3.2 < 0.4.0", cssom@~0.3.6:
version "0.3.8"
resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
@@ -8490,6 +8521,13 @@ cssom@^0.4.4:
resolved "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
"cssstyle@>= 0.2.34 < 0.3.0":
version "0.2.37"
resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54"
integrity sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=
dependencies:
cssom "0.3.x"
cssstyle@^1.0.0:
version "1.4.0"
resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1"
@@ -8643,12 +8681,7 @@ date-fns@^1.27.2:
resolved "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
date-fns@^2.0.0-alpha.27:
version "2.12.0"
resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.12.0.tgz#01754c8a2f3368fc1119cf4625c3dad8c1845ee6"
integrity sha512-qJgn99xxKnFgB1qL4jpxU7Q2t0LOn1p8KMIveef3UZD7kqjT3tpFNNdXJelEHhE+rUgffriXriw/sOSU+cS1Hw==
date-fns@^2.0.1:
date-fns@^2.0.0-alpha.27, date-fns@^2.0.1:
version "2.15.0"
resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.15.0.tgz#424de6b3778e4e69d3ff27046ec136af58ae5d5f"
integrity sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ==
@@ -9600,6 +9633,18 @@ escodegen@^1.14.1, escodegen@^1.9.1:
optionalDependencies:
source-map "~0.6.1"
escodegen@^1.6.1:
version "1.14.3"
resolved "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503"
integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==
dependencies:
esprima "^4.0.1"
estraverse "^4.2.0"
esutils "^2.0.2"
optionator "^0.8.1"
optionalDependencies:
source-map "~0.6.1"
eslint-config-prettier@^6.0.0:
version "6.10.0"
resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.0.tgz#7b15e303bf9c956875c948f6b21500e48ded6a7f"
@@ -10226,7 +10271,7 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
fault@^1.0.2:
fault@^1.0.0, fault@^1.0.2:
version "1.0.4"
resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13"
integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==
@@ -10332,6 +10377,11 @@ file-loader@^4.2.0:
loader-utils "^1.2.3"
schema-utils "^2.5.0"
"file-saver@github:eligrey/FileSaver.js#1.3.8":
version "1.3.8"
uid e865e37af9f9947ddcced76b549e27dc45c1cb2e
resolved "https://codeload.github.com/eligrey/FileSaver.js/tar.gz/e865e37af9f9947ddcced76b549e27dc45c1cb2e"
file-system-cache@^1.0.5:
version "1.0.5"
resolved "https://registry.npmjs.org/file-system-cache/-/file-system-cache-1.0.5.tgz#84259b36a2bbb8d3d6eb1021d3132ffe64cfff4f"
@@ -11532,16 +11582,16 @@ hex-color-regex@^1.1.0:
resolved "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
highlight.js@^10.1.1, highlight.js@~10.1.0:
version "10.1.2"
resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.1.2.tgz#c20db951ba1c22c055010648dfffd7b2a968e00c"
integrity sha512-Q39v/Mn5mfBlMff9r+zzA+gWxRsCRKwEMvYTiisLr/XUiFI/4puWt0Ojdko3R3JCNWGdOWaA5g/Yxqa23kC5AA==
highlight.js@~9.13.0:
version "9.13.1"
resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e"
integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A==
highlight.js@~9.15.0, highlight.js@~9.15.1:
version "9.15.10"
resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2"
integrity sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==
history@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/history/-/history-5.0.0.tgz#0cabbb6c4bbf835addb874f8259f6d25101efd08"
@@ -11669,6 +11719,13 @@ html-webpack-plugin@^4.0.0-beta.2, html-webpack-plugin@^4.3.0:
tapable "^1.1.3"
util.promisify "1.0.0"
html2canvas@1.0.0-alpha.12:
version "1.0.0-alpha.12"
resolved "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-alpha.12.tgz#3b1992e3c9b3f56063c35fd620494f37eba88513"
integrity sha1-OxmS48mz9WBjw1/WIElPN+uohRM=
dependencies:
css-line-break "1.0.1"
htmlparser2@^3.3.0:
version "3.10.1"
resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
@@ -11855,7 +11912,7 @@ hyphenate-style-name@^1.0.2, hyphenate-style-name@^1.0.3:
resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz#097bb7fa0b8f1a9cf0bd5c734cf95899981a9b48"
integrity sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==
iconv-lite@0.4.24, iconv-lite@^0.4.21, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
iconv-lite@0.4.24, iconv-lite@^0.4.13, iconv-lite@^0.4.21, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.24"
resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -13368,6 +13425,29 @@ jsdom@^16.2.2:
ws "^7.2.3"
xml-name-validator "^3.0.0"
jsdom@^8.1.0:
version "8.5.0"
resolved "https://registry.npmjs.org/jsdom/-/jsdom-8.5.0.tgz#d4d8f5dbf2768635b62a62823b947cf7071ebc98"
integrity sha1-1Nj12/J2hjW2KmKCO5R89wcevJg=
dependencies:
abab "^1.0.0"
acorn "^2.4.0"
acorn-globals "^1.0.4"
array-equal "^1.0.0"
cssom ">= 0.3.0 < 0.4.0"
cssstyle ">= 0.2.34 < 0.3.0"
escodegen "^1.6.1"
iconv-lite "^0.4.13"
nwmatcher ">= 1.3.7 < 2.0.0"
parse5 "^1.5.1"
request "^2.55.0"
sax "^1.1.4"
symbol-tree ">= 3.1.0 < 4.0.0"
tough-cookie "^2.2.0"
webidl-conversions "^3.0.1"
whatwg-url "^2.0.1"
xml-name-validator ">= 2.0.1 < 3.0.0"
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -13506,6 +13586,7 @@ jsonpointer@^4.0.1:
resolved "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk=
<<<<<<< HEAD
jsonwebtoken@^8.1.0:
version "8.5.1"
resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
@@ -13521,6 +13602,24 @@ jsonwebtoken@^8.1.0:
lodash.once "^4.0.0"
ms "^2.1.1"
semver "^5.6.0"
=======
jspdf-autotable@3.5.3:
version "3.5.3"
resolved "https://registry.npmjs.org/jspdf-autotable/-/jspdf-autotable-3.5.3.tgz#2f73adb07f340e7dbf22950e3e6c8bf853991479"
integrity sha512-K+cNWW3x6w0R/1B5m6PYOm6v8CTTDXy/g32lZouc7SuC6zhvzMN2dauhk6dDYxPD0pky0oyPIJFwSJ/tV8PAeg==
jspdf@1.5.3:
version "1.5.3"
resolved "https://registry.npmjs.org/jspdf/-/jspdf-1.5.3.tgz#5a12c011479defabef5735de55c913060ed219f2"
integrity sha512-J9X76xnncMw+wIqb15HeWfPMqPwYxSpPY8yWPJ7rAZN/ZDzFkjCSZObryCyUe8zbrVRNiuCnIeQteCzMn7GnWw==
dependencies:
canvg "1.5.3"
file-saver "github:eligrey/FileSaver.js#1.3.8"
html2canvas "1.0.0-alpha.12"
omggif "1.0.7"
promise-polyfill "8.1.0"
stackblur-canvas "2.2.0"
>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353
jsprim@^1.2.2:
version "1.4.1"
@@ -14246,13 +14345,13 @@ lowercase-keys@^2.0.0:
resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lowlight@1.12.1:
version "1.12.1"
resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.12.1.tgz#014acf8dd73a370e02ff1cc61debcde3bb1681eb"
integrity sha512-OqaVxMGIESnawn+TU/QMV5BJLbUghUfjDWPAtFqDYDmDtr4FnB+op8xM+pR7nKlauHNUHXGt0VgWatFB8voS5w==
lowlight@^1.14.0:
version "1.14.0"
resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.14.0.tgz#83ebc143fec0f9e6c0d3deffe01be129ce56b108"
integrity sha512-N2E7zTM7r1CwbzwspPxJvmjAbxljCPThTFawEX2Z7+P3NGrrvY54u8kyU16IY4qWfoVIxY8SYCS8jTkuG7TqYA==
dependencies:
fault "^1.0.2"
highlight.js "~9.15.0"
fault "^1.0.0"
highlight.js "~10.1.0"
lowlight@~1.11.0:
version "1.11.0"
@@ -14400,10 +14499,10 @@ markdown-to-jsx@^6.11.4:
prop-types "^15.6.2"
unquote "^1.1.0"
material-table@1.62.x:
version "1.62.0"
resolved "https://registry.npmjs.org/material-table/-/material-table-1.62.0.tgz#117793ebf16ab0fccbb6f8a670d849a7be0b5995"
integrity sha512-+3tnk32lXtkXeKM7k/hZ82jpSzlXU5CsWXqJHq4Tl0Un7ycjK2Kef6EMPqeE3i58vKNqbIvbrFf/ESH0D/Qwig==
material-table@1.68.x:
version "1.68.0"
resolved "https://registry.npmjs.org/material-table/-/material-table-1.68.0.tgz#275c3d9a885c40ae4bc5a7461c00e877f92397b9"
integrity sha512-dyJJaVsS3m+i6sn71AvYcVdA1P9X1XiUOM2PekfvEeeMtkdQb66oChGkk77ndYi3Ja6j4DovGVNrgeVLwXLZiw==
dependencies:
"@date-io/date-fns" "^1.1.0"
"@material-ui/pickers" "^3.2.2"
@@ -14412,6 +14511,8 @@ material-table@1.62.x:
debounce "^1.2.0"
fast-deep-equal "2.0.1"
filefy "0.1.10"
jspdf "1.5.3"
jspdf-autotable "3.5.3"
prop-types "^15.6.2"
react-beautiful-dnd "^13.0.0"
react-double-scrollbar "0.0.15"
@@ -15442,6 +15543,11 @@ number-is-nan@^1.0.0:
resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
"nwmatcher@>= 1.3.7 < 2.0.0":
version "1.4.4"
resolved "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e"
integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==
nwsapi@^2.0.7, nwsapi@^2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
@@ -15586,6 +15692,11 @@ octokit-pagination-methods@^1.1.0:
resolved "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4"
integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==
omggif@1.0.7:
version "1.0.7"
resolved "https://registry.npmjs.org/omggif/-/omggif-1.0.7.tgz#59d2eecb0263de84635b3feb887c0c9973f1e49d"
integrity sha1-WdLuywJj3oRjWz/riHwMmXPx5J0=
on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@@ -15961,7 +16072,23 @@ parse-entities@^1.1.0, parse-entities@^1.1.2:
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
<<<<<<< HEAD
parse-filepath@1.0.2, parse-filepath@^1.0.1:
=======
parse-entities@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8"
integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==
dependencies:
character-entities "^1.0.0"
character-entities-legacy "^1.0.0"
character-reference-invalid "^1.0.0"
is-alphanumerical "^1.0.0"
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
parse-filepath@^1.0.1:
>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353
version "1.0.2"
resolved "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=
@@ -16038,6 +16165,11 @@ parse5@5.1.1:
resolved "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
parse5@^1.5.1:
version "1.5.1"
resolved "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94"
integrity sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=
parseurl@^1.3.2, parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@@ -17017,6 +17149,7 @@ pretty-hrtime@^1.0.3:
resolved "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1"
integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=
<<<<<<< HEAD
prisma-json-schema@0.1.3:
version "0.1.3"
resolved "https://registry.npmjs.org/prisma-json-schema/-/prisma-json-schema-0.1.3.tgz#6c302db8f464f8b92e8694d3f7dd3f41ac9afcbe"
@@ -17050,6 +17183,12 @@ prismjs@^1.8.4:
version "1.19.0"
resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.19.0.tgz#713afbd45c3baca4b321569f2df39e17e729d4dc"
integrity sha512-IVFtbW9mCWm9eOIaEkNyo2Vl4NnEifis2GQ7/MLRG5TQe6t+4Sj9J5QWI9i3v+SS43uZBlCAOn+zYTVYQcPXJw==
=======
prismjs@^1.20.0, prismjs@^1.8.4, prismjs@~1.20.0:
version "1.20.0"
resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz#9b685fc480a3514ee7198eac6a3bf5024319ff03"
integrity sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==
>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353
optionalDependencies:
clipboard "^2.0.0"
@@ -17085,6 +17224,11 @@ promise-inflight@^1.0.1:
resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
promise-polyfill@8.1.0:
version "8.1.0"
resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.0.tgz#30059da54d1358ce905ac581f287e184aedf995d"
integrity sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA==
promise-polyfill@^8.1.3:
version "8.1.3"
resolved "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz#8c99b3cf53f3a91c68226ffde7bde81d7f904116"
@@ -17661,9 +17805,9 @@ react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-i
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-lazylog@^4.5.2:
version "4.5.2"
resolved "https://registry.npmjs.org/react-lazylog/-/react-lazylog-4.5.2.tgz#9b66a0997348690f56286f6afcda97ebd0c62b7c"
integrity sha512-XvAjlzs8tzbjmqyEdj8HwW8Kg5nfqZAzIGeeG1incZuhuXQkekIs6nYb3W/GQNxDpA1CowgNUR4UfP+7/C2Ang==
version "4.5.3"
resolved "https://registry.npmjs.org/react-lazylog/-/react-lazylog-4.5.3.tgz#289e24995b5599e75943556ac63f5e2c04d0001e"
integrity sha512-lyov32A/4BqihgXgtNXTHCajXSXkYHPlIEmV8RbYjHIMxCFSnmtdg4kDCI3vATz7dURtiFTvrw5yonHnrS+NNg==
dependencies:
"@mattiasbuelens/web-streams-polyfill" "^0.2.0"
fetch-readablestream "^0.2.0"
@@ -17781,16 +17925,16 @@ react-syntax-highlighter@^11.0.2:
prismjs "^1.8.4"
refractor "^2.4.1"
react-syntax-highlighter@^12.2.1:
version "12.2.1"
resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz#14d78352da1c1c3f93c6698b70ec7c706b83493e"
integrity sha512-CTsp0ZWijwKRYFg9xhkWD4DSpQqE4vb2NKVMdPAkomnILSmsNBHE0n5GuI5zB+PU3ySVvXvdt9jo+ViD9XibCA==
react-syntax-highlighter@^13.2.1:
version "13.2.1"
resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-13.2.1.tgz#3d5a3b655cd85ce06b9508e0365d01ef9b8560bb"
integrity sha512-O/AF/ll4I3Dp+2WuKbnF5yKG4b1BUncqcpTW6MIBDJPr2eGKqlNGS3Nv+lyCFtAIHx8N+/ktti8qH14Q5VjjcA==
dependencies:
"@babel/runtime" "^7.3.1"
highlight.js "~9.15.1"
lowlight "1.12.1"
prismjs "^1.8.4"
refractor "^2.4.1"
highlight.js "^10.1.1"
lowlight "^1.14.0"
prismjs "^1.20.0"
refractor "^3.0.0"
react-test-renderer@^16.13.1:
version "16.13.1"
@@ -18098,6 +18242,15 @@ refractor@^2.4.1:
parse-entities "^1.1.2"
prismjs "~1.17.0"
refractor@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/refractor/-/refractor-3.0.0.tgz#7c8072eaf49dbc1b333e7acc64fb52a1c9b17c75"
integrity sha512-eCGK/oP4VuyW/ERqjMZRZHxl2QsztbkedkYy/SxqE/+Gh1gLaAF17tWIOcVJDiyGhar1NZy/0B9dFef7J0+FDw==
dependencies:
hastscript "^5.0.0"
parse-entities "^2.0.0"
prismjs "~1.20.0"
regenerate-unicode-properties@^8.2.0:
version "8.2.0"
resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
@@ -18292,9 +18445,9 @@ replace-ext@1.0.0:
integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=
replace-in-file@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.0.0.tgz#a583be911c4af3ecbf709ca97c48f3f9e7f2b626"
integrity sha512-vMmJekpRgju0GA0UvRxauDbQ645wGXxasVZfw5l5HKk58OlAI1tMmXNcV+YAUKrS/XFdBPla5qgvjI5Tqvshvg==
version "6.1.0"
resolved "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.1.0.tgz#9f9ddd7bb70d6ad231d2ad692e1b646e73d06647"
integrity sha512-URzjyF3nucvejuY13HFd7O+Q6tFJRLKGHLYVvSh+LiZj3gFXzSYGnIkQflnJJulCAI2/RTZaZkpOtdVdW0EhQA==
dependencies:
chalk "^4.0.0"
glob "^7.1.6"
@@ -18328,7 +18481,11 @@ request-promise-native@^1.0.5, request-promise-native@^1.0.8:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
<<<<<<< HEAD
request@2.88.2, request@^2.85.0, request@^2.87.0, request@^2.88.0, request@^2.88.2:
=======
request@^2.55.0, request@^2.85.0, request@^2.87.0, request@^2.88.0, request@^2.88.2:
>>>>>>> f225b094e4651d478fa5925ef498fdbdab6ca353
version "2.88.2"
resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -18496,6 +18653,11 @@ rgba-regex@^1.0.0:
resolved "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
rgbcolor@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz#d6505ecdb304a6595da26fa4b43307306775945d"
integrity sha1-1lBezbMEplldom+ktDMHMGd1lF0=
rifm@^0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/rifm/-/rifm-0.7.0.tgz#debe951a9c83549ca6b33e5919f716044c2230be"
@@ -18533,11 +18695,11 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
inherits "^2.0.1"
rollup-plugin-dts@^1.4.6:
version "1.4.7"
resolved "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-1.4.7.tgz#6255147ac777314c0725a1efcb42df10fe282243"
integrity sha512-QkunbJ96yUNkW95k/Vd6SdTjCbWSG0rMVUtpHSCwfg078Z7vbDaBnfz/gkSqR5h8WFMxoccBT4aodHm6387Jvg==
version "1.4.10"
resolved "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-1.4.10.tgz#0373c4284a2ba4d2d72df69c289271a816bc2736"
integrity sha512-bL6MBXc8lK7D5b/tYbHaglxs4ZxMQTQilGA6Xm9KQBEj4h9ZwIDlAsvDooGjJ/cOw23r3POTRtSCEyTHxtzHJg==
optionalDependencies:
"@babel/code-frame" "^7.8.3"
"@babel/code-frame" "^7.10.4"
rollup-plugin-esbuild@^2.0.0:
version "2.3.0"
@@ -18659,14 +18821,7 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.3, rxjs@^6.5.4, rxjs@^6.5.5:
version "6.5.5"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec"
integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==
dependencies:
tslib "^1.9.0"
rxjs@^6.5.2:
rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.5.3, rxjs@^6.5.5:
version "6.6.0"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz#af2901eedf02e3a83ffa7f886240ff9018bbec84"
integrity sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==
@@ -18739,7 +18894,7 @@ sanitize-html@^1.27.0:
srcset "^2.0.1"
xtend "^4.0.1"
sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4:
sax@>=0.6.0, sax@^1.1.4, sax@^1.2.4, sax@~1.2.4:
version "1.2.4"
resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
@@ -19470,6 +19625,16 @@ stack-utils@^2.0.2:
dependencies:
escape-string-regexp "^2.0.0"
stackblur-canvas@2.2.0:
version "2.2.0"
resolved "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.2.0.tgz#cacc5924a0744b3e183eb2e6c1d8559c1a17c26e"
integrity sha512-5Gf8dtlf8k6NbLzuly2NkGrkS/Ahh+I5VUjO7TnFizdJtgpfpLLEdQlLe9umbcnZlitU84kfYjXE67xlSXfhfQ==
stackblur-canvas@^1.4.1:
version "1.4.1"
resolved "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-1.4.1.tgz#849aa6f94b272ff26f6471fa4130ed1f7e47955b"
integrity sha1-hJqm+UsnL/JvZHH6QTDtH35HlVs=
stackframe@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.1.1.tgz#ffef0a3318b1b60c3b58564989aca5660729ec71"
@@ -19493,9 +19658,9 @@ stacktrace-js@^2.0.0:
stacktrace-gps "^3.0.4"
start-server-and-test@^1.10.11:
version "1.11.0"
resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.11.0.tgz#1b1a83d062b0028ee6e296bb4e0231f2d8b2f4af"
integrity sha512-FhkJFYL/lvbd0tKWvbxWNWjtFtq3Zpa09QDjA8EUH88AsgNL4hkAAKYNmbac+fFM8/GIZoJ1Mj4mm3SMI0X1bA==
version "1.11.2"
resolved "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-1.11.2.tgz#9144b7b6f25197148f159f261ae80119afbb17d5"
integrity sha512-rk1zS5WQvdbc8slE5hPtzfji1dFSnBAfm+vSjToZNrBvozHJvuAG80xE5u8N4tQjg3Ej1Crjc19J++r28HGJgg==
dependencies:
bluebird "3.7.2"
check-more-types "2.24.0"
@@ -19503,7 +19668,7 @@ start-server-and-test@^1.10.11:
execa "3.4.0"
lazy-ass "1.6.0"
ps-tree "1.2.0"
wait-on "4.0.0"
wait-on "5.1.0"
start-server-webpack-plugin@^2.2.5:
version "2.2.5"
@@ -20001,7 +20166,7 @@ symbol-observable@^1.0.4, symbol-observable@^1.1.0, symbol-observable@^1.2.0:
resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
symbol-tree@^3.2.2, symbol-tree@^3.2.4:
"symbol-tree@>= 3.1.0 < 4.0.0", symbol-tree@^3.2.2, symbol-tree@^3.2.4:
version "3.2.4"
resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
@@ -20421,7 +20586,7 @@ touch@^3.1.0:
dependencies:
nopt "~1.0.10"
tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0:
tough-cookie@^2.2.0, tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
@@ -20452,6 +20617,11 @@ tr46@^2.0.2:
dependencies:
punycode "^2.1.1"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
tree-kill@^1.2.2:
version "1.2.2"
resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
@@ -21249,17 +21419,16 @@ w3c-xmlserializer@^2.0.0:
dependencies:
xml-name-validator "^3.0.0"
wait-on@4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/wait-on/-/wait-on-4.0.0.tgz#4d7e4485ca759968897fd3b0cc50720c0b4ca959"
integrity sha512-QrW3J8LzS5ADPfD9Rx5S6KJck66xkqyiFKQs9jmUTkIhiEOmkzU7WRZc+MjsnmkrgjitS2xQ4bb13hnlQnKBUQ==
wait-on@5.1.0:
version "5.1.0"
resolved "https://registry.npmjs.org/wait-on/-/wait-on-5.1.0.tgz#b697f21c6fea0908b9c7ad6ed56ace4736768b66"
integrity sha512-JM0kgaE+V0nCDvSl72iM05W8NDt2E2M56WC5mzR7M+T+k6xjt2yYpyom+xA8RasSunFGzbxIpAXbVzXqtweAnA==
dependencies:
"@hapi/joi" "^16.1.8"
lodash "^4.17.15"
minimist "^1.2.0"
request "^2.88.0"
request-promise-native "^1.0.8"
rxjs "^6.5.4"
"@hapi/joi" "^17.1.1"
axios "^0.19.2"
lodash "^4.17.19"
minimist "^1.2.5"
rxjs "^6.5.5"
walker@^1.0.7, walker@~1.0.5:
version "1.0.7"
@@ -21298,6 +21467,11 @@ wcwidth@^1.0.0, wcwidth@^1.0.1:
dependencies:
defaults "^1.0.3"
webidl-conversions@^3.0.0, webidl-conversions@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
webidl-conversions@^4.0.2:
version "4.0.2"
resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
@@ -21489,6 +21663,14 @@ whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0:
resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
whatwg-url@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-2.0.1.tgz#5396b2043f020ee6f704d9c45ea8519e724de659"
integrity sha1-U5ayBD8CDub3BNnEXqhRnnJN5lk=
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
whatwg-url@^6.4.1:
version "6.5.0"
resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8"
@@ -21771,6 +21953,11 @@ xml-encryption@^1.0.0:
xmldom "~0.1.15"
xpath "0.0.27"
"xml-name-validator@>= 2.0.1 < 3.0.0":
version "2.0.1"
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635"
integrity sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
@@ -21799,7 +21986,7 @@ xmldom@0.1.27:
resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk=
xmldom@0.1.x, xmldom@~0.1.15:
xmldom@0.1.x, xmldom@^0.1.22, xmldom@~0.1.15:
version "0.1.31"
resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff"
integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==