Merge branch 'master' into patch/sidebar-submenu-fix
Signed-off-by: hiba-aldalaty <hibaaldalaty@gmail.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
---
|
||||
|
||||
Fixes potential bug introduced in `0.4.10` which causes `OAuth2AuthProvider` to authenticate using credentials in both POST payload and headers.
|
||||
This might break some stricter OAuth2 implementations so there is now a `includeBasicAuth` config option that can manually be set to `true` to enable this behavior.
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
'@backstage/app-defaults': patch
|
||||
'@backstage/core-app-api': patch
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/core-plugin-api': patch
|
||||
'@backstage/dev-utils': patch
|
||||
'@backstage/integration-react': patch
|
||||
'@backstage/test-utils': patch
|
||||
'@backstage/version-bridge': patch
|
||||
'@backstage/plugin-allure': patch
|
||||
'@backstage/plugin-analytics-module-ga': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-azure-devops': patch
|
||||
'@backstage/plugin-badges': patch
|
||||
'@backstage/plugin-bazaar': patch
|
||||
'@backstage/plugin-bitrise': patch
|
||||
'@backstage/plugin-catalog': patch
|
||||
'@backstage/plugin-catalog-graph': patch
|
||||
'@backstage/plugin-catalog-import': patch
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
'@backstage/plugin-circleci': patch
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
'@backstage/plugin-code-coverage': patch
|
||||
'@backstage/plugin-config-schema': patch
|
||||
'@backstage/plugin-cost-insights': patch
|
||||
'@backstage/plugin-explore': patch
|
||||
'@backstage/plugin-firehydrant': patch
|
||||
'@backstage/plugin-fossa': patch
|
||||
'@backstage/plugin-gcp-projects': patch
|
||||
'@backstage/plugin-git-release-manager': patch
|
||||
'@backstage/plugin-github-actions': patch
|
||||
'@backstage/plugin-github-deployments': patch
|
||||
'@backstage/plugin-gitops-profiles': patch
|
||||
'@backstage/plugin-graphiql': patch
|
||||
'@backstage/plugin-home': patch
|
||||
'@backstage/plugin-ilert': patch
|
||||
'@backstage/plugin-jenkins': patch
|
||||
'@backstage/plugin-kafka': patch
|
||||
'@backstage/plugin-kubernetes': patch
|
||||
'@backstage/plugin-lighthouse': patch
|
||||
'@backstage/plugin-newrelic': patch
|
||||
'@backstage/plugin-org': patch
|
||||
'@backstage/plugin-pagerduty': patch
|
||||
'@backstage/plugin-permission-react': patch
|
||||
'@backstage/plugin-rollbar': patch
|
||||
'@backstage/plugin-scaffolder': patch
|
||||
'@backstage/plugin-search': patch
|
||||
'@backstage/plugin-sentry': patch
|
||||
'@backstage/plugin-shortcuts': patch
|
||||
'@backstage/plugin-sonarqube': patch
|
||||
'@backstage/plugin-splunk-on-call': patch
|
||||
'@backstage/plugin-tech-insights': patch
|
||||
'@backstage/plugin-tech-radar': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
'@backstage/plugin-todo': patch
|
||||
'@backstage/plugin-user-settings': patch
|
||||
'@backstage/plugin-xcmetrics': patch
|
||||
---
|
||||
|
||||
Moved React dependencies to `peerDependencies` and allow both React v16 and v17 to be used.
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/core-app-api': patch
|
||||
'@backstage/core-components': patch
|
||||
'@backstage/core-plugin-api': patch
|
||||
'@backstage/dev-utils': patch
|
||||
'@backstage/techdocs-common': patch
|
||||
'@backstage/test-utils': patch
|
||||
'@backstage/plugin-analytics-module-ga': patch
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
'@backstage/plugin-config-schema': patch
|
||||
'@backstage/plugin-github-deployments': patch
|
||||
'@backstage/plugin-pagerduty': patch
|
||||
'@backstage/plugin-permission-node': patch
|
||||
'@backstage/plugin-permission-react': patch
|
||||
'@backstage/plugin-search-backend': patch
|
||||
'@backstage/plugin-search-backend-module-elasticsearch': patch
|
||||
'@backstage/plugin-search-backend-module-pg': patch
|
||||
'@backstage/plugin-techdocs-backend': patch
|
||||
'@backstage/plugin-todo': patch
|
||||
'@backstage/plugin-todo-backend': patch
|
||||
---
|
||||
|
||||
Minor improvement to the API reports, by not unpacking arguments directly
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend-module-rails': minor
|
||||
---
|
||||
|
||||
update publish format from ESM to CJS
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Honor database migration configuration
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/core-components': patch
|
||||
---
|
||||
|
||||
Use ellipsis style for overflowed text in sidebar menu
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/cli': patch
|
||||
---
|
||||
|
||||
Updated the frontend plugin template to put React dependencies in `peerDependencies` by default, as well as allowing both React v16 and v17. This change can be applied to existing plugins by running `yarn backstage-cli plugin:diff` within the plugin package directory.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
---
|
||||
|
||||
Add options argument to support additional database migrations configuration
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
The problem of lowercase entity triplets which causes docs to not load on entity page is fixed.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Bump @spotify/prettier-config
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-react': patch
|
||||
---
|
||||
|
||||
Fix typo in catalog-react package.json
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/create-app': patch
|
||||
---
|
||||
|
||||
Removed the `scaffolder.github.visibility` configuration that is no longer used from the default app template.
|
||||
+1
-1
@@ -74,4 +74,4 @@
|
||||
| [LogMeIn](https://www.logmein.com) | [Lorenzo Orsatti](https://github.com/lorsatti) | Improve onboarding experience of new developers. Discover faster and painlessly developer documentation, API definitions and team information. Provide useful dev metrics in a central place. Provide easy-to-use templates for new services. |
|
||||
| [Telstra](https://www.telstra.com.au) | [@kiranpatel11](https://github.com/kiranpatel11), [JasonC](https://github.com/JasonC17) | Primary usage: software catalog and templates<br/> Emerging usage : TechDocs, Explore Ecosystem, TechRadar, etc |
|
||||
| [Mosaico](https://www.mosaico.com.br/) | [Wédney Yuri](https://github.com/wedneyyuri),[@tino.milton](https://github.com/miltonjacomini) | A centralized service catalog of our documentation for our service engineers. |
|
||||
| [Mox Bank](https://www.mox.com/) | [Nick Laqua](https://github.com/nick-laqua-dragon), [Gauthier Roebroeck](https://github.com/gauthier-roebroeck-mox) | "Single pane of glass" developer portal for providing a best-in-class developer experience to our product teams and making Mox the best tech environment in Hongkong 🥰🚀 |
|
||||
| [Mox Bank](https://www.mox.com/) | [Nick Laqua](https://github.com/nick-laqua-dragon), [Gauthier Roebroeck](https://github.com/gauthier-roebroeck-mox) | "Single pane of glass" developer portal for providing a best-in-class developer experience to our product teams and making Mox the best tech environment in Hongkong 🥰🚀 |
|
||||
|
||||
@@ -18,17 +18,31 @@ The next step is to add
|
||||
[add templates](http://backstage.io/docs/features/software-templates/adding-templates)
|
||||
to your Backstage app.
|
||||
|
||||
### GitHub
|
||||
### Publishing defaults
|
||||
|
||||
For GitHub, you can configure who can see the new repositories that are created
|
||||
by specifying `visibility` option. Valid options are `public`, `private` and
|
||||
`internal`. The `internal` option is for GitHub Enterprise clients, which means
|
||||
public within the enterprise.
|
||||
Software templates can define _publish_ actions, such as `publish:github`, to
|
||||
create new repositories or submit pull / merge requests to existing
|
||||
repositories. You can configure the author and commit message through the
|
||||
`scaffolder` configuration in `app-config.yaml`:
|
||||
|
||||
```yaml
|
||||
scaffolder:
|
||||
github:
|
||||
visibility: public # or 'internal' or 'private'
|
||||
defaultAuthor:
|
||||
name: M.C. Hammer # Defaults to `Scaffolder`
|
||||
email: hammer@donthurtem.com # Defaults to `scaffolder@backstage.io`
|
||||
defaultCommitMessage: "U can't touch this" # Defaults to 'Initial commit'
|
||||
```
|
||||
|
||||
To configure who can see the new repositories created from software templates,
|
||||
add the `repoVisibility` key within a software template:
|
||||
|
||||
```yaml
|
||||
- id: publish
|
||||
name: Publish
|
||||
action: publish:github
|
||||
input:
|
||||
repoUrl: '{{ parameters.repoUrl }}'
|
||||
repoVisibility: public # or 'internal' or 'private'
|
||||
```
|
||||
|
||||
### Disabling Docker in Docker situation (Optional)
|
||||
|
||||
@@ -35,9 +35,11 @@
|
||||
"@backstage/theme": "^0.2.14",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"react": "^16.12.0",
|
||||
"react-router-dom": "6.0.0-beta.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/test-utils": "^0.1.22",
|
||||
@@ -45,7 +47,7 @@
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@types/jest": "^26.0.7",
|
||||
"@types/node": "^14.14.32",
|
||||
"@types/react": "*"
|
||||
"@types/react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
"@roadiehq/backstage-plugin-travis-ci": "^1.0.11",
|
||||
"history": "^5.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-hot-loader": "^4.12.21",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
|
||||
@@ -175,23 +175,22 @@ export function createStatusCheckRouter(options: {
|
||||
// @public (undocumented)
|
||||
export class DatabaseManager {
|
||||
forPlugin(pluginId: string): PluginDatabaseManager;
|
||||
static fromConfig(config: Config): DatabaseManager;
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options?: DatabaseManagerOptions,
|
||||
): DatabaseManager;
|
||||
}
|
||||
|
||||
// @public
|
||||
export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export class DockerContainerRunner implements ContainerRunner {
|
||||
constructor({ dockerClient }: { dockerClient: Docker });
|
||||
constructor(options: { dockerClient: Docker });
|
||||
// (undocumented)
|
||||
runContainer({
|
||||
imageName,
|
||||
command,
|
||||
args,
|
||||
logStream,
|
||||
mountDirs,
|
||||
workingDir,
|
||||
envVars,
|
||||
pullImage,
|
||||
}: RunContainerOptions): Promise<void>;
|
||||
runContainer(options: RunContainerOptions): Promise<void>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -227,34 +226,17 @@ export function getVoidLogger(): winston.Logger;
|
||||
// @public (undocumented)
|
||||
export class Git {
|
||||
// (undocumented)
|
||||
add({ dir, filepath }: { dir: string; filepath: string }): Promise<void>;
|
||||
add(options: { dir: string; filepath: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
addRemote({
|
||||
dir,
|
||||
url,
|
||||
remote,
|
||||
}: {
|
||||
addRemote(options: {
|
||||
dir: string;
|
||||
remote: string;
|
||||
url: string;
|
||||
}): Promise<void>;
|
||||
// (undocumented)
|
||||
clone({
|
||||
url,
|
||||
dir,
|
||||
ref,
|
||||
}: {
|
||||
url: string;
|
||||
dir: string;
|
||||
ref?: string;
|
||||
}): Promise<void>;
|
||||
clone(options: { url: string; dir: string; ref?: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
commit({
|
||||
dir,
|
||||
message,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
commit(options: {
|
||||
dir: string;
|
||||
message: string;
|
||||
author: {
|
||||
@@ -267,41 +249,22 @@ export class Git {
|
||||
};
|
||||
}): Promise<string>;
|
||||
// (undocumented)
|
||||
currentBranch({
|
||||
dir,
|
||||
fullName,
|
||||
}: {
|
||||
currentBranch(options: {
|
||||
dir: string;
|
||||
fullName?: boolean;
|
||||
}): Promise<string | undefined>;
|
||||
// (undocumented)
|
||||
fetch({ dir, remote }: { dir: string; remote?: string }): Promise<void>;
|
||||
fetch(options: { dir: string; remote?: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
static fromAuth: ({
|
||||
username,
|
||||
password,
|
||||
logger,
|
||||
}: {
|
||||
username?: string | undefined;
|
||||
password?: string | undefined;
|
||||
logger?: Logger_2 | undefined;
|
||||
static fromAuth: (options: {
|
||||
username?: string;
|
||||
password?: string;
|
||||
logger?: Logger_2;
|
||||
}) => Git;
|
||||
// (undocumented)
|
||||
init({
|
||||
dir,
|
||||
defaultBranch,
|
||||
}: {
|
||||
dir: string;
|
||||
defaultBranch?: string;
|
||||
}): Promise<void>;
|
||||
init(options: { dir: string; defaultBranch?: string }): Promise<void>;
|
||||
// (undocumented)
|
||||
merge({
|
||||
dir,
|
||||
theirs,
|
||||
ours,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
merge(options: {
|
||||
dir: string;
|
||||
theirs: string;
|
||||
ours?: string;
|
||||
@@ -315,17 +278,11 @@ export class Git {
|
||||
};
|
||||
}): Promise<MergeResult>;
|
||||
// (undocumented)
|
||||
push({ dir, remote }: { dir: string; remote: string }): Promise<PushResult>;
|
||||
push(options: { dir: string; remote: string }): Promise<PushResult>;
|
||||
// (undocumented)
|
||||
readCommit({
|
||||
dir,
|
||||
sha,
|
||||
}: {
|
||||
dir: string;
|
||||
sha: string;
|
||||
}): Promise<ReadCommitResult>;
|
||||
readCommit(options: { dir: string; sha: string }): Promise<ReadCommitResult>;
|
||||
// (undocumented)
|
||||
resolveRef({ dir, ref }: { dir: string; ref: string }): Promise<string>;
|
||||
resolveRef(options: { dir: string; ref: string }): Promise<string>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -395,6 +352,9 @@ export type PluginCacheManager = {
|
||||
// @public
|
||||
export interface PluginDatabaseManager {
|
||||
getClient(): Promise<Knex>;
|
||||
migrations?: {
|
||||
skip?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -623,8 +583,8 @@ export type UrlReaderPredicateTuple = {
|
||||
|
||||
// @public
|
||||
export class UrlReaders {
|
||||
static create({ logger, config, factories }: UrlReadersOptions): UrlReader;
|
||||
static default({ logger, config, factories }: UrlReadersOptions): UrlReader;
|
||||
static create(options: UrlReadersOptions): UrlReader;
|
||||
static default(options: UrlReadersOptions): UrlReader;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
@@ -642,4 +602,8 @@ export function useHotCleanup(
|
||||
|
||||
// @public
|
||||
export function useHotMemoize<T>(_module: NodeModule, valueFactory: () => T): T;
|
||||
|
||||
// Warnings were encountered during analysis:
|
||||
//
|
||||
// src/database/types.d.ts:23:12 - (tsdoc-undefined-tag) The TSDoc tag "@default" is not defined in this configuration
|
||||
```
|
||||
|
||||
@@ -36,25 +36,45 @@ describe('DatabaseManager', () => {
|
||||
afterEach(() => jest.resetAllMocks());
|
||||
|
||||
describe('DatabaseManager.fromConfig', () => {
|
||||
it('accesses the backend.database key', () => {
|
||||
const config = new ConfigReader({
|
||||
backend: {
|
||||
database: {
|
||||
client: 'pg',
|
||||
connection: {
|
||||
host: 'localhost',
|
||||
user: 'foo',
|
||||
password: 'bar',
|
||||
database: 'foodb',
|
||||
},
|
||||
const backendConfig = {
|
||||
backend: {
|
||||
database: {
|
||||
client: 'pg',
|
||||
connection: {
|
||||
host: 'localhost',
|
||||
user: 'foo',
|
||||
password: 'bar',
|
||||
database: 'foodb',
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
it('accesses the backend.database key', () => {
|
||||
const config = new ConfigReader(backendConfig);
|
||||
const getConfigSpy = jest.spyOn(config, 'getConfig');
|
||||
DatabaseManager.fromConfig(config);
|
||||
|
||||
expect(getConfigSpy).toHaveBeenCalledWith('backend.database');
|
||||
});
|
||||
|
||||
it('handles default options', () => {
|
||||
const config = new ConfigReader(backendConfig);
|
||||
const database = DatabaseManager.fromConfig(config);
|
||||
const client = database.forPlugin('test');
|
||||
|
||||
expect(client.migrations?.skip).toBe(false);
|
||||
});
|
||||
|
||||
it('handles migrations options', () => {
|
||||
const config = new ConfigReader(backendConfig);
|
||||
const database = DatabaseManager.fromConfig(config, {
|
||||
migrations: { skip: true },
|
||||
});
|
||||
const client = database.forPlugin('test');
|
||||
|
||||
expect(client.migrations?.skip).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DatabaseManager.forPlugin', () => {
|
||||
|
||||
@@ -36,6 +36,15 @@ function pluginPath(pluginId: string): string {
|
||||
return `plugin.${pluginId}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration options object.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export class DatabaseManager {
|
||||
/**
|
||||
@@ -47,19 +56,25 @@ export class DatabaseManager {
|
||||
* names if config is not provided.
|
||||
*
|
||||
* @param config - The loaded application configuration.
|
||||
* @param options - An optional configuration object.
|
||||
*/
|
||||
static fromConfig(config: Config): DatabaseManager {
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options?: DatabaseManagerOptions,
|
||||
): DatabaseManager {
|
||||
const databaseConfig = config.getConfig('backend.database');
|
||||
|
||||
return new DatabaseManager(
|
||||
databaseConfig,
|
||||
databaseConfig.getOptionalString('prefix'),
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
private constructor(
|
||||
private readonly config: Config,
|
||||
private readonly prefix: string = 'backstage_plugin_',
|
||||
private readonly options?: DatabaseManagerOptions,
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -76,6 +91,10 @@ export class DatabaseManager {
|
||||
getClient(): Promise<Knex> {
|
||||
return _this.getDatabase(pluginId);
|
||||
},
|
||||
migrations: {
|
||||
skip: false,
|
||||
..._this.options?.migrations,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,18 @@ export interface PluginDatabaseManager {
|
||||
* stores so that plugins are discouraged from database integration.
|
||||
*/
|
||||
getClient(): Promise<Knex>;
|
||||
|
||||
/**
|
||||
* This property is used to control the behavior of database migrations.
|
||||
*/
|
||||
migrations?: {
|
||||
/**
|
||||
* skip database migrations. Useful if connecting to a read-only database.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
skip?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,7 +46,8 @@ export class UrlReaders {
|
||||
/**
|
||||
* Creates a UrlReader without any known types.
|
||||
*/
|
||||
static create({ logger, config, factories }: UrlReadersOptions): UrlReader {
|
||||
static create(options: UrlReadersOptions): UrlReader {
|
||||
const { logger, config, factories } = options;
|
||||
const mux = new UrlReaderPredicateMux(logger);
|
||||
const treeResponseFactory = DefaultReadTreeResponseFactory.create({
|
||||
config,
|
||||
@@ -68,7 +69,8 @@ export class UrlReaders {
|
||||
*
|
||||
* Any additional factories passed will be loaded before the default ones.
|
||||
*/
|
||||
static default({ logger, config, factories = [] }: UrlReadersOptions) {
|
||||
static default(options: UrlReadersOptions) {
|
||||
const { logger, config, factories = [] } = options;
|
||||
return UrlReaders.create({
|
||||
logger,
|
||||
config,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import git, {
|
||||
ProgressCallback,
|
||||
MergeResult,
|
||||
@@ -42,44 +43,32 @@ export class Git {
|
||||
},
|
||||
) {}
|
||||
|
||||
async add({
|
||||
dir,
|
||||
filepath,
|
||||
}: {
|
||||
dir: string;
|
||||
filepath: string;
|
||||
}): Promise<void> {
|
||||
async add(options: { dir: string; filepath: string }): Promise<void> {
|
||||
const { dir, filepath } = options;
|
||||
this.config.logger?.info(`Adding file {dir=${dir},filepath=${filepath}}`);
|
||||
|
||||
return git.add({ fs, dir, filepath });
|
||||
}
|
||||
|
||||
async addRemote({
|
||||
dir,
|
||||
url,
|
||||
remote,
|
||||
}: {
|
||||
async addRemote(options: {
|
||||
dir: string;
|
||||
remote: string;
|
||||
url: string;
|
||||
}): Promise<void> {
|
||||
const { dir, url, remote } = options;
|
||||
this.config.logger?.info(
|
||||
`Creating new remote {dir=${dir},remote=${remote},url=${url}}`,
|
||||
);
|
||||
return git.addRemote({ fs, dir, remote, url });
|
||||
}
|
||||
|
||||
async commit({
|
||||
dir,
|
||||
message,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
async commit(options: {
|
||||
dir: string;
|
||||
message: string;
|
||||
author: { name: string; email: string };
|
||||
committer: { name: string; email: string };
|
||||
}): Promise<string> {
|
||||
const { dir, message, author, committer } = options;
|
||||
this.config.logger?.info(
|
||||
`Committing file to repo {dir=${dir},message=${message}}`,
|
||||
);
|
||||
@@ -87,15 +76,12 @@ export class Git {
|
||||
return git.commit({ fs, dir, message, author, committer });
|
||||
}
|
||||
|
||||
async clone({
|
||||
url,
|
||||
dir,
|
||||
ref,
|
||||
}: {
|
||||
async clone(options: {
|
||||
url: string;
|
||||
dir: string;
|
||||
ref?: string;
|
||||
}): Promise<void> {
|
||||
const { url, dir, ref } = options;
|
||||
this.config.logger?.info(`Cloning repo {dir=${dir},url=${url}}`);
|
||||
return git.clone({
|
||||
fs,
|
||||
@@ -114,51 +100,35 @@ export class Git {
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/currentBranch
|
||||
async currentBranch({
|
||||
dir,
|
||||
fullName,
|
||||
}: {
|
||||
async currentBranch(options: {
|
||||
dir: string;
|
||||
fullName?: boolean;
|
||||
}): Promise<string | undefined> {
|
||||
const fullname = fullName ?? false;
|
||||
return git.currentBranch({ fs, dir, fullname }) as Promise<
|
||||
const { dir, fullName = false } = options;
|
||||
return git.currentBranch({ fs, dir, fullname: fullName }) as Promise<
|
||||
string | undefined
|
||||
>;
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/fetch
|
||||
async fetch({
|
||||
dir,
|
||||
remote,
|
||||
}: {
|
||||
dir: string;
|
||||
remote?: string;
|
||||
}): Promise<void> {
|
||||
const remoteValue = remote ?? 'origin';
|
||||
async fetch(options: { dir: string; remote?: string }): Promise<void> {
|
||||
const { dir, remote = 'origin' } = options;
|
||||
this.config.logger?.info(
|
||||
`Fetching remote=${remoteValue} for repository {dir=${dir}}`,
|
||||
`Fetching remote=${remote} for repository {dir=${dir}}`,
|
||||
);
|
||||
await git.fetch({
|
||||
fs,
|
||||
http,
|
||||
dir,
|
||||
remote: remoteValue,
|
||||
remote,
|
||||
onProgress: this.onProgressHandler(),
|
||||
headers: {
|
||||
'user-agent': 'git/@isomorphic-git',
|
||||
},
|
||||
headers: { 'user-agent': 'git/@isomorphic-git' },
|
||||
onAuth: this.onAuth,
|
||||
});
|
||||
}
|
||||
|
||||
async init({
|
||||
dir,
|
||||
defaultBranch = 'master',
|
||||
}: {
|
||||
dir: string;
|
||||
defaultBranch?: string;
|
||||
}): Promise<void> {
|
||||
async init(options: { dir: string; defaultBranch?: string }): Promise<void> {
|
||||
const { dir, defaultBranch = 'master' } = options;
|
||||
this.config.logger?.info(`Init git repository {dir=${dir}}`);
|
||||
|
||||
return git.init({
|
||||
@@ -169,19 +139,14 @@ export class Git {
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/merge
|
||||
async merge({
|
||||
dir,
|
||||
theirs,
|
||||
ours,
|
||||
author,
|
||||
committer,
|
||||
}: {
|
||||
async merge(options: {
|
||||
dir: string;
|
||||
theirs: string;
|
||||
ours?: string;
|
||||
author: { name: string; email: string };
|
||||
committer: { name: string; email: string };
|
||||
}): Promise<MergeResult> {
|
||||
const { dir, theirs, ours, author, committer } = options;
|
||||
this.config.logger?.info(
|
||||
`Merging branch '${theirs}' into '${ours}' for repository {dir=${dir}}`,
|
||||
);
|
||||
@@ -197,7 +162,8 @@ export class Git {
|
||||
});
|
||||
}
|
||||
|
||||
async push({ dir, remote }: { dir: string; remote: string }) {
|
||||
async push(options: { dir: string; remote: string }) {
|
||||
const { dir, remote } = options;
|
||||
this.config.logger?.info(
|
||||
`Pushing directory to remote {dir=${dir},remote=${remote}}`,
|
||||
);
|
||||
@@ -215,24 +181,17 @@ export class Git {
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/readCommit
|
||||
async readCommit({
|
||||
dir,
|
||||
sha,
|
||||
}: {
|
||||
async readCommit(options: {
|
||||
dir: string;
|
||||
sha: string;
|
||||
}): Promise<ReadCommitResult> {
|
||||
const { dir, sha } = options;
|
||||
return git.readCommit({ fs, dir, oid: sha });
|
||||
}
|
||||
|
||||
// https://isomorphic-git.org/docs/en/resolveRef
|
||||
async resolveRef({
|
||||
dir,
|
||||
ref,
|
||||
}: {
|
||||
dir: string;
|
||||
ref: string;
|
||||
}): Promise<string> {
|
||||
async resolveRef(options: { dir: string; ref: string }): Promise<string> {
|
||||
const { dir, ref } = options;
|
||||
return git.resolveRef({ fs, dir, ref });
|
||||
}
|
||||
|
||||
@@ -256,13 +215,12 @@ export class Git {
|
||||
};
|
||||
};
|
||||
|
||||
static fromAuth = ({
|
||||
username,
|
||||
password,
|
||||
logger,
|
||||
}: {
|
||||
static fromAuth = (options: {
|
||||
username?: string;
|
||||
password?: string;
|
||||
logger?: Logger;
|
||||
}) => new Git({ username, password, logger });
|
||||
}) => {
|
||||
const { username, password, logger } = options;
|
||||
return new Git({ username, password, logger });
|
||||
};
|
||||
}
|
||||
|
||||
@@ -28,20 +28,22 @@ export type UserOptions = {
|
||||
export class DockerContainerRunner implements ContainerRunner {
|
||||
private readonly dockerClient: Docker;
|
||||
|
||||
constructor({ dockerClient }: { dockerClient: Docker }) {
|
||||
this.dockerClient = dockerClient;
|
||||
constructor(options: { dockerClient: Docker }) {
|
||||
this.dockerClient = options.dockerClient;
|
||||
}
|
||||
|
||||
async runContainer({
|
||||
imageName,
|
||||
command,
|
||||
args,
|
||||
logStream = new PassThrough(),
|
||||
mountDirs = {},
|
||||
workingDir,
|
||||
envVars = {},
|
||||
pullImage = true,
|
||||
}: RunContainerOptions) {
|
||||
async runContainer(options: RunContainerOptions) {
|
||||
const {
|
||||
imageName,
|
||||
command,
|
||||
args,
|
||||
logStream = new PassThrough(),
|
||||
mountDirs = {},
|
||||
workingDir,
|
||||
envVars = {},
|
||||
pullImage = true,
|
||||
} = options;
|
||||
|
||||
// Show a better error message when Docker is unavailable.
|
||||
try {
|
||||
await this.dockerClient.ping();
|
||||
|
||||
@@ -89,7 +89,6 @@
|
||||
"ora": "^5.3.0",
|
||||
"postcss": "^8.1.0",
|
||||
"process": "^0.11.10",
|
||||
"react": "^16.0.0",
|
||||
"react-dev-utils": "^12.0.0-next.47",
|
||||
"react-hot-loader": "^4.12.21",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
|
||||
@@ -75,7 +75,9 @@ class PackageJsonHandler {
|
||||
await this.syncScripts();
|
||||
await this.syncPublishConfig();
|
||||
await this.syncDependencies('dependencies');
|
||||
await this.syncDependencies('peerDependencies', true);
|
||||
await this.syncDependencies('devDependencies');
|
||||
await this.syncReactDeps();
|
||||
}
|
||||
|
||||
// Make sure a field inside package.json is in sync. This mutates the targetObj and writes package.json on change.
|
||||
@@ -207,12 +209,12 @@ class PackageJsonHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncDependencies(fieldName: string) {
|
||||
private async syncDependencies(fieldName: string, required: boolean = false) {
|
||||
const pkgDeps = this.pkg[fieldName];
|
||||
const targetDeps = (this.targetPkg[fieldName] =
|
||||
this.targetPkg[fieldName] || {});
|
||||
|
||||
if (!pkgDeps) {
|
||||
if (!pkgDeps && !required) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,10 +233,26 @@ class PackageJsonHandler {
|
||||
continue;
|
||||
}
|
||||
|
||||
await this.syncField(key, pkgDeps, targetDeps, fieldName, true, true);
|
||||
await this.syncField(
|
||||
key,
|
||||
pkgDeps,
|
||||
targetDeps,
|
||||
fieldName,
|
||||
true,
|
||||
!required,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async syncReactDeps() {
|
||||
const targetDeps = (this.targetPkg.dependencies =
|
||||
this.targetPkg.dependencies || {});
|
||||
|
||||
// Remove these from from deps since they're now in peerDeps
|
||||
await this.syncField('react', {}, targetDeps, 'dependencies');
|
||||
await this.syncField('react-dom', {}, targetDeps, 'dependencies');
|
||||
}
|
||||
|
||||
private async write() {
|
||||
await this.writeFunc(`${JSON.stringify(this.targetPkg, null, 2)}\n`);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ export const version = findVersion();
|
||||
export const isDev = fs.pathExistsSync(paths.resolveOwn('src'));
|
||||
|
||||
export function createPackageVersionProvider(lockfile?: Lockfile) {
|
||||
return (name: string, versionHint?: string) => {
|
||||
return (name: string, versionHint?: string): string => {
|
||||
const packageVersion = packageVersions[name];
|
||||
const targetVersion = versionHint || packageVersion;
|
||||
if (!targetVersion) {
|
||||
@@ -94,6 +94,6 @@ export function createPackageVersionProvider(lockfile?: Lockfile) {
|
||||
if (semver.parse(versionHint)?.prerelease.length) {
|
||||
return versionHint!;
|
||||
}
|
||||
return `^${versionHint}`;
|
||||
return versionHint?.match(/^[\d\.]+$/) ? `^${versionHint}` : versionHint!;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -32,10 +32,11 @@
|
||||
"@material-ui/core": "{{versionQuery '@material-ui/core' '4.12.2'}}",
|
||||
"@material-ui/icons": "{{versionQuery '@material-ui/icons' '4.9.1'}}",
|
||||
"@material-ui/lab": "{{versionQuery '@material-ui/lab' '4.0.0-alpha.57'}}",
|
||||
"react": "{{versionQuery 'react' '16.13.1'}}",
|
||||
"react-dom": "{{versionQuery 'react-dom' '16.13.1'}}",
|
||||
"react-use": "{{versionQuery 'react-use' '17.2.4'}}"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "{{versionQuery 'react' '^16.13.1 || ^17.0.0'}}"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "{{versionQuery '@backstage/cli'}}",
|
||||
"@backstage/core-app-api": "{{versionQuery '@backstage/core-app-api'}}",
|
||||
|
||||
@@ -250,24 +250,13 @@ export class AppThemeSelector implements AppThemeApi {
|
||||
// @public
|
||||
export class AtlassianAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
}: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class Auth0Auth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof auth0AuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof auth0AuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -303,13 +292,7 @@ export type BackstagePluginWithAnyOutput = Omit<
|
||||
// @public
|
||||
export class BitbucketAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -402,13 +385,7 @@ export class GithubAuth implements OAuthApi, SessionApi {
|
||||
// @deprecated
|
||||
constructor(sessionManager: SessionManager<GithubSession>);
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): GithubAuth;
|
||||
static create(options: OAuthApiCreateOptions): GithubAuth;
|
||||
// (undocumented)
|
||||
getAccessToken(scope?: string, options?: AuthRequestOptions): Promise<string>;
|
||||
// (undocumented)
|
||||
@@ -441,25 +418,13 @@ export type GithubSession = {
|
||||
// @public
|
||||
export class GitlabAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class GoogleAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment,
|
||||
provider,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof googleAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof googleAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -477,13 +442,7 @@ export class LocalStorageFeatureFlags implements FeatureFlagsApi {
|
||||
// @public
|
||||
export class MicrosoftAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
discoveryApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -507,14 +466,7 @@ export class OAuth2
|
||||
scopeTransform: (scopes: string[]) => string[];
|
||||
});
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
scopeTransform,
|
||||
}: OAuth2CreateOptions): OAuth2;
|
||||
static create(options: OAuth2CreateOptions): OAuth2;
|
||||
// (undocumented)
|
||||
getAccessToken(
|
||||
scope?: string | string[],
|
||||
@@ -570,24 +522,15 @@ export class OAuthRequestManager implements OAuthRequestApi {
|
||||
// @public
|
||||
export class OktaAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
defaultScopes,
|
||||
}: OAuthApiCreateOptions): typeof oktaAuthApiRef.T;
|
||||
static create(options: OAuthApiCreateOptions): typeof oktaAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
export class OneLoginAuth {
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
oauthRequestApi,
|
||||
}: OneLoginAuthCreateOptions): typeof oneloginAuthApiRef.T;
|
||||
static create(
|
||||
options: OneLoginAuthCreateOptions,
|
||||
): typeof oneloginAuthApiRef.T;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -607,11 +550,7 @@ export class SamlAuth
|
||||
// @deprecated
|
||||
constructor(sessionManager: SessionManager<SamlSession>);
|
||||
// (undocumented)
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment,
|
||||
provider,
|
||||
}: AuthApiCreateOptions): SamlAuth;
|
||||
static create(options: AuthApiCreateOptions): SamlAuth;
|
||||
// (undocumented)
|
||||
getBackstageIdentity(
|
||||
options?: AuthRequestOptions,
|
||||
|
||||
@@ -38,14 +38,16 @@
|
||||
"@backstage/version-bridge": "^0.1.0",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@types/react": "*",
|
||||
"@types/prop-types": "^15.7.3",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/test-utils": "^0.1.23",
|
||||
|
||||
@@ -30,12 +30,14 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class AtlassianAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
}: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof atlassianAuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -30,13 +30,15 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class Auth0Auth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['openid', `email`, `profile`],
|
||||
}: OAuthApiCreateOptions): typeof auth0AuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof auth0AuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['openid', `email`, `profile`],
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -45,13 +45,15 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class BitbucketAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['team'],
|
||||
}: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof bitbucketAuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['team'],
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -56,13 +56,15 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class GithubAuth implements OAuthApi, SessionApi {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['read:user'],
|
||||
}: OAuthApiCreateOptions) {
|
||||
static create(options: OAuthApiCreateOptions) {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['read:user'],
|
||||
} = options;
|
||||
|
||||
const connector = new DefaultAuthConnector({
|
||||
discoveryApi,
|
||||
environment,
|
||||
|
||||
@@ -30,13 +30,15 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class GitlabAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['read_user'],
|
||||
}: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof gitlabAuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['read_user'],
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -32,17 +32,19 @@ const SCOPE_PREFIX = 'https://www.googleapis.com/auth/';
|
||||
* @public
|
||||
*/
|
||||
export default class GoogleAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
defaultScopes = [
|
||||
'openid',
|
||||
`${SCOPE_PREFIX}userinfo.email`,
|
||||
`${SCOPE_PREFIX}userinfo.profile`,
|
||||
],
|
||||
}: OAuthApiCreateOptions): typeof googleAuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof googleAuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
defaultScopes = [
|
||||
'openid',
|
||||
`${SCOPE_PREFIX}userinfo.email`,
|
||||
`${SCOPE_PREFIX}userinfo.profile`,
|
||||
],
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -30,19 +30,21 @@ const DEFAULT_PROVIDER = {
|
||||
* @public
|
||||
*/
|
||||
export default class MicrosoftAuth {
|
||||
static create({
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
discoveryApi,
|
||||
defaultScopes = [
|
||||
'openid',
|
||||
'offline_access',
|
||||
'profile',
|
||||
'email',
|
||||
'User.Read',
|
||||
],
|
||||
}: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof microsoftAuthApiRef.T {
|
||||
const {
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
discoveryApi,
|
||||
defaultScopes = [
|
||||
'openid',
|
||||
'offline_access',
|
||||
'profile',
|
||||
'email',
|
||||
'User.Read',
|
||||
],
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -70,14 +70,16 @@ export default class OAuth2
|
||||
BackstageIdentityApi,
|
||||
SessionApi
|
||||
{
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = [],
|
||||
scopeTransform = x => x,
|
||||
}: OAuth2CreateOptions) {
|
||||
static create(options: OAuth2CreateOptions) {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = [],
|
||||
scopeTransform = x => x,
|
||||
} = options;
|
||||
|
||||
const connector = new DefaultAuthConnector({
|
||||
discoveryApi,
|
||||
environment,
|
||||
|
||||
@@ -42,13 +42,15 @@ const OKTA_SCOPE_PREFIX: string = 'okta.';
|
||||
* @public
|
||||
*/
|
||||
export default class OktaAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['openid', 'email', 'profile', 'offline_access'],
|
||||
}: OAuthApiCreateOptions): typeof oktaAuthApiRef.T {
|
||||
static create(options: OAuthApiCreateOptions): typeof oktaAuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
defaultScopes = ['openid', 'email', 'profile', 'offline_access'],
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -57,12 +57,16 @@ const SCOPE_PREFIX: string = 'onelogin.';
|
||||
* @public
|
||||
*/
|
||||
export default class OneLoginAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
}: OneLoginAuthCreateOptions): typeof oneloginAuthApiRef.T {
|
||||
static create(
|
||||
options: OneLoginAuthCreateOptions,
|
||||
): typeof oneloginAuthApiRef.T {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
} = options;
|
||||
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
|
||||
@@ -52,11 +52,13 @@ const DEFAULT_PROVIDER = {
|
||||
export default class SamlAuth
|
||||
implements ProfileInfoApi, BackstageIdentityApi, SessionApi
|
||||
{
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
}: AuthApiCreateOptions) {
|
||||
static create(options: AuthApiCreateOptions) {
|
||||
const {
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
} = options;
|
||||
|
||||
const connector = new DirectAuthConnector<SamlSession>({
|
||||
discoveryApi,
|
||||
environment,
|
||||
|
||||
@@ -1982,10 +1982,7 @@ export const SidebarSpacer: React_2.ComponentType<
|
||||
>;
|
||||
|
||||
// @public
|
||||
export const SidebarSubmenu: ({
|
||||
title,
|
||||
children,
|
||||
}: PropsWithChildren<SidebarSubmenuProps>) => JSX.Element;
|
||||
export const SidebarSubmenu: (props: SidebarSubmenuProps) => JSX.Element;
|
||||
|
||||
// @public
|
||||
export const SidebarSubmenuItem: (
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@types/react": "*",
|
||||
"@types/react-sparklines": "^1.7.0",
|
||||
"@types/react-text-truncate": "^0.14.0",
|
||||
"classnames": "^2.2.6",
|
||||
@@ -53,8 +52,6 @@
|
||||
"prop-types": "^15.7.2",
|
||||
"qs": "^6.9.4",
|
||||
"rc-progress": "^3.0.0",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-hook-form": "^7.12.2",
|
||||
"react-markdown": "^7.0.1",
|
||||
@@ -67,6 +64,11 @@
|
||||
"remark-gfm": "^2.0.0",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0",
|
||||
"react-dom": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
"@backstage/cli": "^0.10.0",
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { act, fireEvent } from '@testing-library/react';
|
||||
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
|
||||
import { CopyTextButton } from './CopyTextButton';
|
||||
import { errorApiRef } from '@backstage/core-plugin-api';
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import React from 'react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { act } from '@testing-library/react';
|
||||
|
||||
import { Progress } from './Progress';
|
||||
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { act, fireEvent } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Route, Routes } from 'react-router';
|
||||
import { RoutedTabs } from './RoutedTabs';
|
||||
|
||||
|
||||
@@ -14,9 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { renderInTestApp, withLogCollector } from '@backstage/test-utils';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { act, fireEvent } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Route, Routes } from 'react-router';
|
||||
import { TabbedLayout } from './TabbedLayout';
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ const SidebarItemWithSubmenu = ({
|
||||
{itemIcon}
|
||||
</div>
|
||||
{text && (
|
||||
<Typography variant="subtitle2" className={classes.text}>
|
||||
<Typography variant="subtitle2" className={classes.label}>
|
||||
{text}
|
||||
</Typography>
|
||||
)}
|
||||
@@ -403,7 +403,7 @@ export const SidebarItem = forwardRef<any, SidebarItemProps>((props, ref) => {
|
||||
{itemIcon}
|
||||
</div>
|
||||
{text && (
|
||||
<Typography variant="subtitle2" className={classes.text}>
|
||||
<Typography variant="subtitle2" className={classes.label}>
|
||||
{text}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import clsx from 'clsx';
|
||||
import React, { PropsWithChildren, ReactNode, useContext } from 'react';
|
||||
import React, { ReactNode, useContext } from 'react';
|
||||
import {
|
||||
SidebarItemWithSubmenuContext,
|
||||
sidebarConfig,
|
||||
@@ -83,16 +83,12 @@ export type SidebarSubmenuProps = {
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const SidebarSubmenu = ({
|
||||
title,
|
||||
children,
|
||||
}: PropsWithChildren<SidebarSubmenuProps>) => {
|
||||
export const SidebarSubmenu = (props: SidebarSubmenuProps) => {
|
||||
const { isOpen } = useContext(SidebarContext);
|
||||
const left = isOpen
|
||||
? sidebarConfig.drawerWidthOpen
|
||||
: sidebarConfig.drawerWidthClosed;
|
||||
const props = { left: left };
|
||||
const classes = useStyles(props)();
|
||||
const classes = useStyles({ left: left })();
|
||||
|
||||
const { isHoveredOn } = useContext(SidebarItemWithSubmenuContext);
|
||||
return (
|
||||
@@ -102,9 +98,9 @@ export const SidebarSubmenu = ({
|
||||
})}
|
||||
>
|
||||
<Typography variant="h5" className={classes.title}>
|
||||
{title}
|
||||
{props.title}
|
||||
</Typography>
|
||||
{children}
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -43,10 +43,7 @@ export type AnalyticsApi = {
|
||||
export const analyticsApiRef: ApiRef<AnalyticsApi>;
|
||||
|
||||
// @public
|
||||
export const AnalyticsContext: ({
|
||||
attributes,
|
||||
children,
|
||||
}: {
|
||||
export const AnalyticsContext: (options: {
|
||||
attributes: Partial<AnalyticsContextValue>;
|
||||
children: ReactNode;
|
||||
}) => JSX.Element;
|
||||
|
||||
@@ -34,14 +34,16 @@
|
||||
"@backstage/types": "^0.1.1",
|
||||
"@backstage/version-bridge": "^0.1.0",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@types/react": "*",
|
||||
"history": "^5.0.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.12.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -62,13 +62,12 @@ export const useAnalyticsContext = (): AnalyticsContextValue => {
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const AnalyticsContext = ({
|
||||
attributes,
|
||||
children,
|
||||
}: {
|
||||
export const AnalyticsContext = (options: {
|
||||
attributes: Partial<AnalyticsContextValue>;
|
||||
children: ReactNode;
|
||||
}) => {
|
||||
const { attributes, children } = options;
|
||||
|
||||
const parentValues = useAnalyticsContext();
|
||||
const combinedValue = {
|
||||
...parentValues,
|
||||
|
||||
@@ -22,4 +22,4 @@ yarn backstage-create-app
|
||||
## Documentation
|
||||
|
||||
- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md)
|
||||
- [Backstage Documentation](https://github.com/backstage/backstage/blob/master/docs/README.md)
|
||||
- [Backstage Documentation](https://backstage.io/docs/)
|
||||
|
||||
@@ -65,7 +65,7 @@ export default async (cmd: Command, version: string): Promise<void> => {
|
||||
const templateDir = paths.resolveOwn('templates/default-app');
|
||||
const tempDir = resolvePath(os.tmpdir(), answers.name);
|
||||
|
||||
// Use `--path` argument as applicaiton directory when specified, otherwise
|
||||
// Use `--path` argument as application directory when specified, otherwise
|
||||
// create a directory using `answers.name`
|
||||
const appDir = cmd.path
|
||||
? resolvePath(paths.targetDir, cmd.path)
|
||||
|
||||
@@ -77,9 +77,7 @@ auth:
|
||||
providers: {}
|
||||
|
||||
scaffolder:
|
||||
github:
|
||||
token: ${GITHUB_TOKEN}
|
||||
visibility: public # or 'internal' or 'private'
|
||||
# see https://backstage.io/docs/features/software-templates/configuration for software template options
|
||||
|
||||
catalog:
|
||||
rules:
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^{{version '@backstage/cli'}}",
|
||||
"@spotify/prettier-config": "^11.0.0",
|
||||
"@spotify/prettier-config": "^12.0.0",
|
||||
"concurrently": "^6.0.0",
|
||||
"lerna": "^4.0.0",
|
||||
"prettier": "^2.3.2"
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
"@backstage/plugin-tech-radar": "^{{version '@backstage/plugin-tech-radar'}}",
|
||||
"@backstage/plugin-techdocs": "^{{version '@backstage/plugin-techdocs'}}",
|
||||
"@backstage/plugin-user-settings": "^{{version '@backstage/plugin-user-settings'}}",
|
||||
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
|
||||
"@backstage/theme": "^{{version '@backstage/theme'}}",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
@@ -34,6 +33,7 @@
|
||||
"react-use": "^15.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/test-utils": "^{{version '@backstage/test-utils'}}",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^10.4.1",
|
||||
"@testing-library/user-event": "^12.0.7",
|
||||
@@ -48,11 +48,11 @@
|
||||
"scripts": {
|
||||
"start": "backstage-cli app:serve",
|
||||
"build": "backstage-cli app:build",
|
||||
"test": "backstage-cli test",
|
||||
"lint": "backstage-cli lint",
|
||||
"clean": "backstage-cli clean",
|
||||
"test": "backstage-cli test",
|
||||
"test:e2e": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:dev",
|
||||
"test:e2e:ci": "cross-env PORT=3001 start-server-and-test start http://localhost:3001 cy:run",
|
||||
"lint": "backstage-cli lint",
|
||||
"cy:dev": "cypress open",
|
||||
"cy:run": "cypress run"
|
||||
},
|
||||
|
||||
@@ -44,11 +44,9 @@ export type DevAppPageOptions = {
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
export const EntityGridItem: ({
|
||||
entity,
|
||||
classes,
|
||||
...rest
|
||||
}: Omit<GridProps<'div', {}>, 'container' | 'item'> & {
|
||||
entity: Entity;
|
||||
}) => JSX.Element;
|
||||
export const EntityGridItem: (
|
||||
props: Omit<GridProps, 'item' | 'container'> & {
|
||||
entity: Entity;
|
||||
},
|
||||
) => JSX.Element;
|
||||
```
|
||||
|
||||
@@ -43,15 +43,17 @@
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/react": "*",
|
||||
"react": "^16.12.0",
|
||||
"react-use": "^17.2.4",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-hot-loader": "^4.12.21",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0",
|
||||
"react-dom": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@types/jest": "^26.0.7",
|
||||
|
||||
@@ -35,11 +35,10 @@ const useStyles = makeStyles<BackstageTheme, { entity: Entity }>(theme => ({
|
||||
}));
|
||||
|
||||
/** @public */
|
||||
export const EntityGridItem = ({
|
||||
entity,
|
||||
classes,
|
||||
...rest
|
||||
}: Omit<GridProps, 'item' | 'container'> & { entity: Entity }): JSX.Element => {
|
||||
export const EntityGridItem = (
|
||||
props: Omit<GridProps, 'item' | 'container'> & { entity: Entity },
|
||||
): JSX.Element => {
|
||||
const { entity, classes, ...rest } = props;
|
||||
const itemClasses = useStyles({ entity });
|
||||
|
||||
return (
|
||||
|
||||
@@ -29,10 +29,11 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/dev-utils": "^0.2.13",
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/theme": "^0.2.0",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0"
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@storybook/addon-a11y": "^6.3.4",
|
||||
|
||||
@@ -49,22 +49,6 @@ export type GeneratorBuilder = {
|
||||
get(entity: Entity): GeneratorBase;
|
||||
};
|
||||
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-with-invalid-optional-name) The @param should not include a JSDoc-style optional name; it must not be enclosed in '[ ]' brackets.
|
||||
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (tsdoc-param-tag-with-invalid-optional-name) The @param should not include a JSDoc-style optional name; it must not be enclosed in '[ ]' brackets.
|
||||
// Warning: (tsdoc-param-tag-with-invalid-type) The @param block should not include a JSDoc-style '{type}'
|
||||
// Warning: (ae-missing-release-tag) "GeneratorRunOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public
|
||||
export type GeneratorRunOptions = {
|
||||
inputDir: string;
|
||||
@@ -82,10 +66,7 @@ export class Generators implements GeneratorBuilder {
|
||||
// (undocumented)
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
{
|
||||
logger,
|
||||
containerRunner,
|
||||
}: {
|
||||
options: {
|
||||
logger: Logger_2;
|
||||
containerRunner: ContainerRunner;
|
||||
},
|
||||
@@ -185,13 +166,10 @@ export class Publisher {
|
||||
): Promise<PublisherBase>;
|
||||
}
|
||||
|
||||
// Warning: (ae-missing-release-tag) "PublisherBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public
|
||||
export interface PublisherBase {
|
||||
docsRouter(): express.Handler;
|
||||
fetchTechDocsMetadata(entityName: EntityName): Promise<TechDocsMetadata>;
|
||||
// Warning: (ae-forgotten-export) The symbol "ReadinessResponse" needs to be exported by the entry point index.d.ts
|
||||
getReadiness(): Promise<ReadinessResponse>;
|
||||
hasDocsBeenGenerated(entityName: Entity): Promise<boolean>;
|
||||
// Warning: (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
|
||||
@@ -202,7 +180,6 @@ export interface PublisherBase {
|
||||
// Warning: (tsdoc-malformed-inline-tag) Expecting a TSDoc tag starting with "{@"
|
||||
// Warning: (ae-forgotten-export) The symbol "MigrateRequest" needs to be exported by the entry point index.d.ts
|
||||
migrateDocsCase?(migrateRequest: MigrateRequest): Promise<void>;
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (ae-forgotten-export) The symbol "PublishRequest" needs to be exported by the entry point index.d.ts
|
||||
// Warning: (ae-forgotten-export) The symbol "PublishResponse" needs to be exported by the entry point index.d.ts
|
||||
publish(request: PublishRequest): Promise<PublishResponse>;
|
||||
@@ -218,6 +195,11 @@ export type PublisherType =
|
||||
| 'azureBlobStorage'
|
||||
| 'openStackSwift';
|
||||
|
||||
// @public
|
||||
export type ReadinessResponse = {
|
||||
isAvailable: boolean;
|
||||
};
|
||||
|
||||
// Warning: (ae-missing-release-tag) "RemoteProtocol" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
@@ -245,12 +227,7 @@ export interface TechDocsDocument extends IndexableDocument {
|
||||
//
|
||||
// @public (undocumented)
|
||||
export class TechdocsGenerator implements GeneratorBase {
|
||||
constructor({
|
||||
logger,
|
||||
containerRunner,
|
||||
config,
|
||||
scmIntegrations,
|
||||
}: {
|
||||
constructor(options: {
|
||||
logger: Logger_2;
|
||||
containerRunner: ContainerRunner;
|
||||
config: Config;
|
||||
@@ -260,26 +237,15 @@ export class TechdocsGenerator implements GeneratorBase {
|
||||
// (undocumented)
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
{
|
||||
containerRunner,
|
||||
logger,
|
||||
}: {
|
||||
options: {
|
||||
containerRunner: ContainerRunner;
|
||||
logger: Logger_2;
|
||||
},
|
||||
): TechdocsGenerator;
|
||||
// (undocumented)
|
||||
run({
|
||||
inputDir,
|
||||
outputDir,
|
||||
parsedLocationAnnotation,
|
||||
etag,
|
||||
logger: childLogger,
|
||||
logStream,
|
||||
}: GeneratorRunOptions): Promise<void>;
|
||||
run(options: GeneratorRunOptions): Promise<void>;
|
||||
}
|
||||
|
||||
// Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// Warning: (ae-missing-release-tag) "TechDocsMetadata" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public
|
||||
@@ -319,7 +285,7 @@ export class UrlPreparer implements PreparerBase {
|
||||
|
||||
// Warnings were encountered during analysis:
|
||||
//
|
||||
// src/stages/generate/types.d.ts:44:5 - (ae-forgotten-export) The symbol "SupportedGeneratorKey" needs to be exported by the entry point index.d.ts
|
||||
// src/stages/generate/types.d.ts:45:5 - (ae-forgotten-export) The symbol "SupportedGeneratorKey" needs to be exported by the entry point index.d.ts
|
||||
// src/stages/prepare/types.d.ts:18:8 - (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen
|
||||
// src/stages/prepare/types.d.ts:19:8 - (tsdoc-param-tag-with-invalid-name) The @param block should be followed by a valid parameter name: The identifier cannot non-word characters
|
||||
// src/stages/prepare/types.d.ts:21:33 - (tsdoc-escape-right-brace) The "}" character should be escaped using a backslash to avoid confusion with a TSDoc inline tag
|
||||
|
||||
@@ -31,17 +31,11 @@ export class Generators implements GeneratorBuilder {
|
||||
|
||||
static async fromConfig(
|
||||
config: Config,
|
||||
{
|
||||
logger,
|
||||
containerRunner,
|
||||
}: { logger: Logger; containerRunner: ContainerRunner },
|
||||
options: { logger: Logger; containerRunner: ContainerRunner },
|
||||
): Promise<GeneratorBuilder> {
|
||||
const generators = new Generators();
|
||||
|
||||
const techdocsGenerator = TechdocsGenerator.fromConfig(config, {
|
||||
logger,
|
||||
containerRunner,
|
||||
});
|
||||
const techdocsGenerator = TechdocsGenerator.fromConfig(config, options);
|
||||
generators.register('techdocs', techdocsGenerator);
|
||||
|
||||
return generators;
|
||||
|
||||
@@ -384,7 +384,7 @@ export const createOrUpdateMetadata = async (
|
||||
// a form appropriate for invalidating the associated object from cache.
|
||||
try {
|
||||
json.files = (await getFileTreeRecursively(techdocsMetadataDir)).map(file =>
|
||||
file.replace(`${techdocsMetadataDir}/`, ''),
|
||||
file.replace(`${techdocsMetadataDir}${path.sep}`, ''),
|
||||
);
|
||||
} catch (err) {
|
||||
assertError(err);
|
||||
|
||||
@@ -52,11 +52,9 @@ export class TechdocsGenerator implements GeneratorBase {
|
||||
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
{
|
||||
containerRunner,
|
||||
logger,
|
||||
}: { containerRunner: ContainerRunner; logger: Logger },
|
||||
options: { containerRunner: ContainerRunner; logger: Logger },
|
||||
) {
|
||||
const { containerRunner, logger } = options;
|
||||
const scmIntegrations = ScmIntegrations.fromConfig(config);
|
||||
return new TechdocsGenerator({
|
||||
logger,
|
||||
@@ -66,31 +64,28 @@ export class TechdocsGenerator implements GeneratorBase {
|
||||
});
|
||||
}
|
||||
|
||||
constructor({
|
||||
logger,
|
||||
containerRunner,
|
||||
config,
|
||||
scmIntegrations,
|
||||
}: {
|
||||
constructor(options: {
|
||||
logger: Logger;
|
||||
containerRunner: ContainerRunner;
|
||||
config: Config;
|
||||
scmIntegrations: ScmIntegrationRegistry;
|
||||
}) {
|
||||
this.logger = logger;
|
||||
this.options = readGeneratorConfig(config, logger);
|
||||
this.containerRunner = containerRunner;
|
||||
this.scmIntegrations = scmIntegrations;
|
||||
this.logger = options.logger;
|
||||
this.options = readGeneratorConfig(options.config, options.logger);
|
||||
this.containerRunner = options.containerRunner;
|
||||
this.scmIntegrations = options.scmIntegrations;
|
||||
}
|
||||
|
||||
public async run({
|
||||
inputDir,
|
||||
outputDir,
|
||||
parsedLocationAnnotation,
|
||||
etag,
|
||||
logger: childLogger,
|
||||
logStream,
|
||||
}: GeneratorRunOptions): Promise<void> {
|
||||
public async run(options: GeneratorRunOptions): Promise<void> {
|
||||
const {
|
||||
inputDir,
|
||||
outputDir,
|
||||
parsedLocationAnnotation,
|
||||
etag,
|
||||
logger: childLogger,
|
||||
logStream,
|
||||
} = options;
|
||||
|
||||
// Do some updates to mkdocs.yml before generating docs e.g. adding repo_url
|
||||
const { path: mkdocsYmlPath, content } = await getMkdocsYml(inputDir);
|
||||
|
||||
|
||||
@@ -34,12 +34,13 @@ export type GeneratorConfig = {
|
||||
/**
|
||||
* The values that the generator will receive.
|
||||
*
|
||||
* @param {string} inputDir The directory of the uncompiled documentation, with the values from the frontend
|
||||
* @param {string} outputDir Directory to store generated docs in. Usually - a newly created temporary directory.
|
||||
* @param {ParsedLocationAnnotation} parsedLocationAnnotation backstage.io/techdocs-ref annotation of an entity
|
||||
* @param {string} etag A unique identifier for the prepared tree e.g. commit SHA. If provided it will be stored in techdocs_metadata.json.
|
||||
* @param {Logger} [logger] A logger that forwards the messages to the caller to be displayed outside of the backend.
|
||||
* @param {Writable} [logStream] A log stream that can send raw log messages to the caller to be displayed outside of the backend..
|
||||
* @public
|
||||
* @param inputDir - The directory of the uncompiled documentation, with the values from the frontend
|
||||
* @param outputDir - Directory to store generated docs in. Usually - a newly created temporary directory.
|
||||
* @param parsedLocationAnnotation - backstage.io/techdocs-ref annotation of an entity
|
||||
* @param etag - A unique identifier for the prepared tree e.g. commit SHA. If provided it will be stored in techdocs_metadata.json.
|
||||
* @param logger - A logger that forwards the messages to the caller to be displayed outside of the backend.
|
||||
* @param logStream - A log stream that can send raw log messages to the caller to be displayed outside of the backend.
|
||||
*/
|
||||
export type GeneratorRunOptions = {
|
||||
inputDir: string;
|
||||
|
||||
@@ -14,4 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { Publisher } from './publish';
|
||||
export type { PublisherBase, PublisherType, TechDocsMetadata } from './types';
|
||||
export type {
|
||||
PublisherBase,
|
||||
PublisherType,
|
||||
TechDocsMetadata,
|
||||
ReadinessResponse,
|
||||
} from './types';
|
||||
|
||||
@@ -51,6 +51,8 @@ export type PublishResponse = {
|
||||
|
||||
/**
|
||||
* Result for the validation check.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ReadinessResponse = {
|
||||
/** If true, the publisher is able to interact with the backing storage. */
|
||||
@@ -59,7 +61,7 @@ export type ReadinessResponse = {
|
||||
|
||||
/**
|
||||
* Type to hold metadata found in techdocs_metadata.json and associated with each site
|
||||
* @param etag ETag of the resource used to generate the site. Usually the latest commit sha of the source repository.
|
||||
* @param etag - ETag of the resource used to generate the site. Usually the latest commit sha of the source repository.
|
||||
*/
|
||||
export type TechDocsMetadata = {
|
||||
site_name: string;
|
||||
@@ -86,6 +88,8 @@ export type MigrateRequest = {
|
||||
* Base class for a TechDocs publisher (e.g. Local, Google GCS Bucket, AWS S3, etc.)
|
||||
* The publisher handles publishing of the generated static files after the prepare and generate steps of TechDocs.
|
||||
* It also provides APIs to communicate with the storage service.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface PublisherBase {
|
||||
/**
|
||||
@@ -99,8 +103,8 @@ export interface PublisherBase {
|
||||
/**
|
||||
* Store the generated static files onto a storage service (either local filesystem or external service).
|
||||
*
|
||||
* @param request Object containing the entity from the service
|
||||
* catalog, and the directory that contains the generated static files from TechDocs.
|
||||
* @param request - Object containing the entity from the service
|
||||
* catalog, and the directory that contains the generated static files from TechDocs.
|
||||
*/
|
||||
publish(request: PublishRequest): Promise<PublishResponse>;
|
||||
|
||||
|
||||
@@ -89,23 +89,13 @@ export type LogFuncs = 'log' | 'warn' | 'error';
|
||||
// @public
|
||||
export class MockAnalyticsApi implements AnalyticsApi {
|
||||
// (undocumented)
|
||||
captureEvent({
|
||||
action,
|
||||
subject,
|
||||
value,
|
||||
attributes,
|
||||
context,
|
||||
}: AnalyticsEvent): void;
|
||||
captureEvent(event: AnalyticsEvent): void;
|
||||
// (undocumented)
|
||||
getEvents(): AnalyticsEvent[];
|
||||
}
|
||||
|
||||
// @public
|
||||
export function mockBreakpoint({
|
||||
matches,
|
||||
}: {
|
||||
matches?: boolean | undefined;
|
||||
}): void;
|
||||
export function mockBreakpoint(options: { matches: boolean }): void;
|
||||
|
||||
// @public
|
||||
export class MockErrorApi implements ErrorApi {
|
||||
@@ -178,10 +168,9 @@ export function setupRequestMockHandlers(worker: {
|
||||
export type SyncLogCollector = () => void;
|
||||
|
||||
// @public
|
||||
export const TestApiProvider: <T extends any[]>({
|
||||
apis,
|
||||
children,
|
||||
}: TestApiProviderProps<T>) => JSX.Element;
|
||||
export const TestApiProvider: <T extends any[]>(
|
||||
props: TestApiProviderProps<T>,
|
||||
) => JSX.Element;
|
||||
|
||||
// @public
|
||||
export type TestApiProviderProps<TApiPairs extends any[]> = {
|
||||
|
||||
@@ -38,13 +38,14 @@
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^13.1.8",
|
||||
"@types/react": "*",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@types/jest": "^26.0.7",
|
||||
|
||||
@@ -120,11 +120,13 @@ export class TestApiRegistry implements ApiHolder {
|
||||
*
|
||||
* @public
|
||||
**/
|
||||
export const TestApiProvider = <T extends any[]>({
|
||||
apis,
|
||||
children,
|
||||
}: TestApiProviderProps<T>) => {
|
||||
export const TestApiProvider = <T extends any[]>(
|
||||
props: TestApiProviderProps<T>,
|
||||
) => {
|
||||
return (
|
||||
<ApiProvider apis={TestApiRegistry.from(...apis)} children={children} />
|
||||
<ApiProvider
|
||||
apis={TestApiRegistry.from(...props.apis)}
|
||||
children={props.children}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,18 +19,15 @@ import { AnalyticsApi, AnalyticsEvent } from '@backstage/core-plugin-api';
|
||||
/**
|
||||
* Mock implementation of {@link core-plugin-api#AnalyticsApi} with helpers to ensure that events are sent correctly.
|
||||
* Use getEvents in tests to verify captured events.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class MockAnalyticsApi implements AnalyticsApi {
|
||||
private events: AnalyticsEvent[] = [];
|
||||
|
||||
captureEvent({
|
||||
action,
|
||||
subject,
|
||||
value,
|
||||
attributes,
|
||||
context,
|
||||
}: AnalyticsEvent) {
|
||||
captureEvent(event: AnalyticsEvent) {
|
||||
const { action, subject, value, attributes, context } = event;
|
||||
|
||||
this.events.push({
|
||||
action,
|
||||
subject,
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is a mocking method suggested in the Jest Doc's, as it is not implemented in JSDOM yet.
|
||||
* It can be used to mock values when the MUI `useMediaQuery` hook if it is used in a tested component.
|
||||
* This is a mocking method suggested in the Jest docs, as it is not implemented in JSDOM yet.
|
||||
* It can be used to mock values for the MUI `useMediaQuery` hook if it is used in a tested component.
|
||||
*
|
||||
* For issues checkout the documentation:
|
||||
* https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
||||
@@ -26,11 +26,11 @@
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export default function mockBreakpoint({ matches = false }) {
|
||||
export default function mockBreakpoint(options: { matches: boolean }) {
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: jest.fn().mockImplementation(query => ({
|
||||
matches: matches,
|
||||
matches: options.matches ?? false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: jest.fn(), // deprecated
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
|
||||
import { ReactElement } from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { render, RenderResult } from '@testing-library/react';
|
||||
import { act, render, RenderResult } from '@testing-library/react';
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
||||
@@ -28,9 +28,9 @@
|
||||
"postpack": "backstage-cli postpack",
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.12.0"
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
|
||||
@@ -30,11 +30,12 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -17,13 +17,7 @@ export const analyticsModuleGA: BackstagePlugin<{}, {}>;
|
||||
//
|
||||
// @public
|
||||
export class GoogleAnalytics implements AnalyticsApi {
|
||||
captureEvent({
|
||||
context,
|
||||
action,
|
||||
subject,
|
||||
value,
|
||||
attributes,
|
||||
}: AnalyticsEvent): void;
|
||||
captureEvent(event: AnalyticsEvent): void;
|
||||
static fromConfig(config: Config): GoogleAnalytics;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,11 +28,12 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-ga": "^3.3.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
+5
-14
@@ -39,19 +39,15 @@ export class GoogleAnalytics implements AnalyticsApi {
|
||||
/**
|
||||
* Instantiate the implementation and initialize ReactGA.
|
||||
*/
|
||||
private constructor({
|
||||
cdmConfig,
|
||||
trackingId,
|
||||
scriptSrc,
|
||||
testMode,
|
||||
debug,
|
||||
}: {
|
||||
private constructor(options: {
|
||||
cdmConfig: CustomDimensionOrMetricConfig[];
|
||||
trackingId: string;
|
||||
scriptSrc?: string;
|
||||
testMode: boolean;
|
||||
debug: boolean;
|
||||
}) {
|
||||
const { cdmConfig, trackingId, scriptSrc, testMode, debug } = options;
|
||||
|
||||
this.cdmConfig = cdmConfig;
|
||||
|
||||
// Initialize Google Analytics.
|
||||
@@ -102,13 +98,8 @@ export class GoogleAnalytics implements AnalyticsApi {
|
||||
* pageview and the rest as custom events. All custom dimensions/metrics are
|
||||
* applied as they should be (set on pageview, merged object on events).
|
||||
*/
|
||||
captureEvent({
|
||||
context,
|
||||
action,
|
||||
subject,
|
||||
value,
|
||||
attributes,
|
||||
}: AnalyticsEvent) {
|
||||
captureEvent(event: AnalyticsEvent) {
|
||||
const { context, action, subject, value, attributes } = event;
|
||||
const customMetadata = this.getCustomDimensionMetrics(context, attributes);
|
||||
|
||||
if (action === 'navigate' && context.extension === 'App') {
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @backstage/plugin-api-docs
|
||||
|
||||
## 0.6.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- dde1681f33: chore(dependencies): bump `graphiql` package to latest
|
||||
- ef64a444ca: Update AsyncAPI component to 1.0.0-x releases
|
||||
|
||||
## 0.6.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@backstage/plugin-api-docs",
|
||||
"description": "A Backstage plugin that helps represent API entities in the frontend",
|
||||
"version": "0.6.16",
|
||||
"version": "0.6.17",
|
||||
"main": "src/index.ts",
|
||||
"types": "src/index.ts",
|
||||
"license": "Apache-2.0",
|
||||
@@ -30,7 +30,7 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@asyncapi/react-component": "^0.23.0",
|
||||
"@asyncapi/react-component": "^1.0.0-next.25",
|
||||
"@backstage/catalog-model": "^0.9.7",
|
||||
"@backstage/core-components": "^0.7.6",
|
||||
"@backstage/core-plugin-api": "^0.2.2",
|
||||
@@ -40,18 +40,19 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@types/react": "*",
|
||||
"graphiql": "^1.0.0-alpha.10",
|
||||
"graphql": "^15.3.0",
|
||||
"graphiql": "^1.5.12",
|
||||
"graphql": "^16.0.0",
|
||||
"isomorphic-form-data": "^2.0.0",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4",
|
||||
"swagger-client": "3.16.1",
|
||||
"swagger-ui-react": "^4.0.0-rc.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
+11
-10
@@ -18,6 +18,15 @@ import { renderInTestApp } from '@backstage/test-utils';
|
||||
import React from 'react';
|
||||
import { AsyncApiDefinition } from './AsyncApiDefinition';
|
||||
|
||||
jest.mock('use-resize-observer', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn().mockImplementation(() => ({
|
||||
observe: jest.fn(),
|
||||
unobserve: jest.fn(),
|
||||
disconnect: jest.fn(),
|
||||
})),
|
||||
}));
|
||||
|
||||
describe('<AsyncApiDefinition />', () => {
|
||||
it('renders asyncapi spec', async () => {
|
||||
const definition = `
|
||||
@@ -45,15 +54,7 @@ components:
|
||||
|
||||
expect(getByText(/Account Service/i)).toBeInTheDocument();
|
||||
expect(getByText(/user\/signedup/i)).toBeInTheDocument();
|
||||
expect(getByText(/UserSignedUp/i)).toBeInTheDocument();
|
||||
expect(getAllByText(/displayName/i)).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('renders error if definition is missing', async () => {
|
||||
const { getByText } = await renderInTestApp(
|
||||
<AsyncApiDefinition definition="" />,
|
||||
);
|
||||
expect(getByText(/Error/i)).toBeInTheDocument();
|
||||
expect(getByText(/Document can't be null or falsey/i)).toBeInTheDocument();
|
||||
expect(getAllByText(/UserSignedUp/i)).toHaveLength(2);
|
||||
expect(getAllByText(/displayName/i)).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,23 +15,72 @@
|
||||
*/
|
||||
|
||||
import AsyncApi from '@asyncapi/react-component';
|
||||
import '@asyncapi/react-component/lib/styles/fiori.css';
|
||||
import { alpha, makeStyles } from '@material-ui/core/styles';
|
||||
import '@asyncapi/react-component/styles/default.css';
|
||||
import { makeStyles, alpha, darken } from '@material-ui/core/styles';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import React from 'react';
|
||||
import { useTheme } from '@material-ui/core';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
const useStyles = makeStyles((theme: BackstageTheme) => ({
|
||||
root: {
|
||||
'& .asyncapi': {
|
||||
'font-family': 'inherit',
|
||||
fontFamily: 'inherit',
|
||||
'& .bg-white': {
|
||||
background: 'none',
|
||||
},
|
||||
'& h2': {
|
||||
...theme.typography.h6,
|
||||
'& .text-4xl': {
|
||||
...theme.typography.h3,
|
||||
},
|
||||
'& .text-teal': {
|
||||
color: theme.palette.primary.main,
|
||||
' & h2': {
|
||||
...theme.typography.h4,
|
||||
},
|
||||
'& .border': {
|
||||
borderColor: alpha(theme.palette.border, 0.1),
|
||||
},
|
||||
'& .min-w-min': {
|
||||
minWidth: 'fit-content',
|
||||
},
|
||||
'& .examples': {
|
||||
padding: '1rem',
|
||||
},
|
||||
'& .bg-teal-500': {
|
||||
backgroundColor: theme.palette.status.ok,
|
||||
},
|
||||
'& .bg-blue-500': {
|
||||
backgroundColor: theme.palette.info.main,
|
||||
},
|
||||
'& .bg-blue-400': {
|
||||
backgroundColor: theme.palette.info.light,
|
||||
},
|
||||
'& .bg-indigo-400': {
|
||||
backgroundColor: theme.palette.warning.main,
|
||||
},
|
||||
'& .text-teal-50': {
|
||||
color: theme.palette.status.ok,
|
||||
},
|
||||
'& .text-red-600': {
|
||||
color: theme.palette.error.main,
|
||||
},
|
||||
'& .text-orange-600': {
|
||||
color: theme.palette.warning.main,
|
||||
},
|
||||
'& .text-teal-500': {
|
||||
color: theme.palette.status.ok,
|
||||
},
|
||||
'& .text-blue-500': {
|
||||
color: theme.palette.info.main,
|
||||
},
|
||||
'& .-rotate-90': {
|
||||
'--tw-rotate': '0deg',
|
||||
},
|
||||
'& button': {
|
||||
...theme.typography.button,
|
||||
borderRadius: theme.shape.borderRadius,
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
'& a': {
|
||||
color: theme.palette.link,
|
||||
},
|
||||
'& a.no-underline': {
|
||||
...theme.typography.button,
|
||||
background: 'none',
|
||||
boxSizing: 'border-box',
|
||||
@@ -48,84 +97,47 @@ const useStyles = makeStyles(theme => ({
|
||||
border: `1px solid ${alpha(theme.palette.primary.main, 0.5)}`,
|
||||
'&:hover': {
|
||||
textDecoration: 'none',
|
||||
'&.Mui-disabled': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
border: `1px solid ${theme.palette.primary.main}`,
|
||||
backgroundColor: alpha(
|
||||
theme.palette.primary.main,
|
||||
theme.palette.action.hoverOpacity,
|
||||
),
|
||||
// Reset on touch devices, it doesn't add specificity
|
||||
'@media (hover: none)': {
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
},
|
||||
'&.Mui-disabled': {
|
||||
color: theme.palette.action.disabled,
|
||||
},
|
||||
},
|
||||
'& .asyncapi__collapse-button:hover': {
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
'& button.asyncapi__toggle-button': {
|
||||
'min-width': 'inherit',
|
||||
},
|
||||
'& .asyncapi__info-list li': {
|
||||
'border-color': theme.palette.primary.main,
|
||||
'&:hover': {
|
||||
color: theme.palette.text.primary,
|
||||
'border-color': theme.palette.primary.main,
|
||||
'background-color': theme.palette.primary.main,
|
||||
},
|
||||
},
|
||||
'& .asyncapi__info-list li a': {
|
||||
color: theme.palette.primary.main,
|
||||
'&:hover': {
|
||||
'& li.no-underline': {
|
||||
'& a': {
|
||||
textDecoration: 'none',
|
||||
color: theme.palette.getContrastText(theme.palette.primary.main),
|
||||
},
|
||||
},
|
||||
'& .asyncapi__enum': {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
dark: {
|
||||
'& svg': {
|
||||
fill: theme.palette.text.primary,
|
||||
},
|
||||
'& .asyncapi__info, .asyncapi__channel, .asyncapi__channels > div, .asyncapi__schema, .asyncapi__channel-operations-list .asyncapi__messages-list-item .asyncapi__message, .asyncapi__message, .asyncapi__server, .asyncapi__servers > div, .asyncapi__messages > div, .asyncapi__schemas > div':
|
||||
{
|
||||
'background-color': 'inherit',
|
||||
},
|
||||
'& .asyncapi__channel-parameters-header, .asyncapi__channel-operations-header, .asyncapi__channel-operation-oneOf-subscribe-header, .asyncapi__channel-operation-oneOf-publish-header, .asyncapi__channel-operation-message-header, .asyncapi__message-header, .asyncapi__message-header-title, .asyncapi__message-header-title > h3, .asyncapi__bindings, .asyncapi__bindings-header, .asyncapi__bindings-header > h4':
|
||||
{
|
||||
'background-color': 'inherit',
|
||||
'& .prose': {
|
||||
color: theme.palette.text.secondary,
|
||||
'& h3': {
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
'& .asyncapi__additional-properties-notice': {
|
||||
color: theme.palette.text.hint,
|
||||
},
|
||||
'& .asyncapi__code, .asyncapi__code-pre': {
|
||||
background: theme.palette.background.default,
|
||||
'& .bg-gray-100, .bg-gray-200': {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
},
|
||||
'& .asyncapi__schema-example-header-title': {
|
||||
color: theme.palette.text.secondary,
|
||||
'& .text-gray-600': {
|
||||
color: theme.palette.grey['50'],
|
||||
},
|
||||
'& .asyncapi__message-headers-header, .asyncapi__message-payload-header, .asyncapi__server-variables-header, .asyncapi__server-security-header':
|
||||
{
|
||||
'background-color': 'inherit',
|
||||
color: theme.palette.text.secondary,
|
||||
'& .text-gray-700': {
|
||||
color: theme.palette.grey['100'],
|
||||
},
|
||||
'& .panel--right': {
|
||||
background: darken(theme.palette.navigation.background, 0.1),
|
||||
},
|
||||
'& .examples': {
|
||||
backgroundColor: darken(theme.palette.navigation.background, 0.1),
|
||||
'& pre': {
|
||||
backgroundColor: darken(theme.palette.background.default, 0.2),
|
||||
},
|
||||
'& .asyncapi__table-header': {
|
||||
background: theme.palette.background.default,
|
||||
},
|
||||
'& .asyncapi__table-body': {
|
||||
color: theme.palette.text.primary,
|
||||
},
|
||||
'& .asyncapi__server-security-flow': {
|
||||
background: theme.palette.background.default,
|
||||
border: 'none',
|
||||
},
|
||||
'& .asyncapi__server-security-flows-list a': {
|
||||
color: theme.palette.primary.main,
|
||||
},
|
||||
'& .asyncapi__table-row--nested': {
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
},
|
||||
}));
|
||||
@@ -134,11 +146,15 @@ type Props = {
|
||||
definition: string;
|
||||
};
|
||||
|
||||
export const AsyncApiDefinition = ({ definition }: Props) => {
|
||||
export const AsyncApiDefinition = ({ definition }: Props): JSX.Element => {
|
||||
const classes = useStyles();
|
||||
const theme = useTheme();
|
||||
const classNames = `${classes.root} ${
|
||||
theme.palette.type === 'dark' ? classes.dark : ''
|
||||
}`;
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<div className={classNames}>
|
||||
<AsyncApi schema={definition} />
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -185,10 +185,7 @@ export class CatalogIdentityClient {
|
||||
// Warning: (ae-forgotten-export) The symbol "UserQuery" needs to be exported by the entry point index.d.ts
|
||||
findUser(query: UserQuery): Promise<UserEntity>;
|
||||
// Warning: (ae-forgotten-export) The symbol "MemberClaimQuery" needs to be exported by the entry point index.d.ts
|
||||
resolveCatalogMembership({
|
||||
entityRefs,
|
||||
logger,
|
||||
}: MemberClaimQuery): Promise<string[]>;
|
||||
resolveCatalogMembership(query: MemberClaimQuery): Promise<string[]>;
|
||||
}
|
||||
|
||||
// Warning: (ae-missing-release-tag) "createAtlassianProvider" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
@@ -270,13 +267,7 @@ export function createOriginFilter(config: Config): (origin: string) => boolean;
|
||||
// Warning: (ae-missing-release-tag) "createRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export function createRouter({
|
||||
logger,
|
||||
config,
|
||||
discovery,
|
||||
database,
|
||||
providerFactories,
|
||||
}: RouterOptions): Promise<express.Router>;
|
||||
export function createRouter(options: RouterOptions): Promise<express.Router>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const createSamlProvider: (
|
||||
|
||||
@@ -84,10 +84,8 @@ export class CatalogIdentityClient {
|
||||
*
|
||||
* Returns a superset of the entity names that can be passed directly to `issueToken` as `ent`.
|
||||
*/
|
||||
async resolveCatalogMembership({
|
||||
entityRefs,
|
||||
logger,
|
||||
}: MemberClaimQuery): Promise<string[]> {
|
||||
async resolveCatalogMembership(query: MemberClaimQuery): Promise<string[]> {
|
||||
const { entityRefs, logger } = query;
|
||||
const resolvedEntityRefs = entityRefs
|
||||
.map((ref: string) => {
|
||||
try {
|
||||
|
||||
@@ -59,6 +59,7 @@ export type OAuth2AuthProviderOptions = OAuthProviderOptions & {
|
||||
tokenUrl: string;
|
||||
scope?: string;
|
||||
logger: Logger;
|
||||
includeBasicAuth?: boolean;
|
||||
};
|
||||
|
||||
export class OAuth2AuthProvider implements OAuthHandlers {
|
||||
@@ -85,12 +86,14 @@ export class OAuth2AuthProvider implements OAuthHandlers {
|
||||
tokenURL: options.tokenUrl,
|
||||
passReqToCallback: false as true,
|
||||
scope: options.scope,
|
||||
customHeaders: {
|
||||
Authorization: `Basic ${this.encodeClientCredentials(
|
||||
options.clientId,
|
||||
options.clientSecret,
|
||||
)}`,
|
||||
},
|
||||
customHeaders: options.includeBasicAuth
|
||||
? {
|
||||
Authorization: `Basic ${this.encodeClientCredentials(
|
||||
options.clientId,
|
||||
options.clientSecret,
|
||||
)}`,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
(
|
||||
accessToken: any,
|
||||
@@ -244,6 +247,7 @@ export const createOAuth2Provider = (
|
||||
const authorizationUrl = envConfig.getString('authorizationUrl');
|
||||
const tokenUrl = envConfig.getString('tokenUrl');
|
||||
const scope = envConfig.getOptionalString('scope');
|
||||
const includeBasicAuth = envConfig.getOptionalBoolean('includeBasicAuth');
|
||||
const disableRefresh =
|
||||
envConfig.getOptionalBoolean('disableRefresh') ?? false;
|
||||
|
||||
@@ -280,6 +284,7 @@ export const createOAuth2Provider = (
|
||||
tokenUrl,
|
||||
scope,
|
||||
logger,
|
||||
includeBasicAuth,
|
||||
});
|
||||
|
||||
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
||||
|
||||
@@ -44,13 +44,10 @@ export interface RouterOptions {
|
||||
providerFactories?: ProviderFactories;
|
||||
}
|
||||
|
||||
export async function createRouter({
|
||||
logger,
|
||||
config,
|
||||
discovery,
|
||||
database,
|
||||
providerFactories,
|
||||
}: RouterOptions): Promise<express.Router> {
|
||||
export async function createRouter(
|
||||
options: RouterOptions,
|
||||
): Promise<express.Router> {
|
||||
const { logger, config, discovery, database, providerFactories } = options;
|
||||
const router = Router();
|
||||
|
||||
const appUrl = config.getString('app.baseUrl');
|
||||
|
||||
@@ -39,11 +39,12 @@
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"humanize-duration": "^3.27.0",
|
||||
"luxon": "^2.0.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -36,11 +36,12 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -34,12 +34,13 @@
|
||||
"@material-ui/pickers": "^3.3.10",
|
||||
"@testing-library/jest-dom": "^5.10.1",
|
||||
"luxon": "^2.0.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-hook-form": "^7.13.0",
|
||||
"react-router-dom": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/dev-utils": "^0.2.13",
|
||||
|
||||
@@ -33,11 +33,12 @@
|
||||
"lodash": "^4.17.21",
|
||||
"luxon": "^2.0.2",
|
||||
"qs": "^6.9.6",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-use": "^17.2.4",
|
||||
"recharts": "^1.8.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -752,13 +752,7 @@ export type DbPageInfo =
|
||||
//
|
||||
// @public (undocumented)
|
||||
export class DefaultCatalogCollator implements DocumentCollator {
|
||||
constructor({
|
||||
discovery,
|
||||
locationTemplate,
|
||||
filter,
|
||||
catalogClient,
|
||||
tokenManager,
|
||||
}: {
|
||||
constructor(options: {
|
||||
discovery: PluginEndpointDiscovery;
|
||||
tokenManager: TokenManager;
|
||||
locationTemplate?: string;
|
||||
|
||||
@@ -56,19 +56,16 @@ export class DefaultCatalogCollator implements DocumentCollator {
|
||||
});
|
||||
}
|
||||
|
||||
constructor({
|
||||
discovery,
|
||||
locationTemplate,
|
||||
filter,
|
||||
catalogClient,
|
||||
tokenManager,
|
||||
}: {
|
||||
constructor(options: {
|
||||
discovery: PluginEndpointDiscovery;
|
||||
tokenManager: TokenManager;
|
||||
locationTemplate?: string;
|
||||
filter?: CatalogEntitiesRequest['filter'];
|
||||
catalogClient?: CatalogApi;
|
||||
}) {
|
||||
const { discovery, locationTemplate, filter, catalogClient, tokenManager } =
|
||||
options;
|
||||
|
||||
this.discovery = discovery;
|
||||
this.locationTemplate =
|
||||
locationTemplate || '/catalog/:namespace/:kind/:name';
|
||||
|
||||
@@ -336,7 +336,10 @@ export class NextCatalogBuilder {
|
||||
const parser = this.parser || defaultEntityDataParser;
|
||||
|
||||
const dbClient = await database.getClient();
|
||||
await applyDatabaseMigrations(dbClient);
|
||||
if (!database.migrations?.skip) {
|
||||
logger.info('Performing database migration');
|
||||
await applyDatabaseMigrations(dbClient);
|
||||
}
|
||||
|
||||
const db = new CommonDatabase(dbClient, logger);
|
||||
|
||||
|
||||
@@ -30,16 +30,17 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@types/react": "*",
|
||||
"classnames": "^2.3.1",
|
||||
"lodash": "^4.17.15",
|
||||
"p-limit": "^3.1.0",
|
||||
"qs": "^6.9.4",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -43,17 +43,18 @@
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@types/react": "*",
|
||||
"git-url-parse": "^11.6.0",
|
||||
"js-base64": "^3.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-hook-form": "^7.12.2",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4",
|
||||
"yaml": "^1.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/backstage/backstage",
|
||||
"directory": "plugins/plugin-catalog-common-react"
|
||||
"directory": "plugins/catalog-react"
|
||||
},
|
||||
"keywords": [
|
||||
"backstage"
|
||||
@@ -41,15 +41,17 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@types/react": "*",
|
||||
"jwt-decode": "^3.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"qs": "^6.9.4",
|
||||
"react": "^16.13.1",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4",
|
||||
"zen-observable": "^0.8.15"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/test-utils": "^0.1.22",
|
||||
|
||||
@@ -42,15 +42,16 @@
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@material-ui/icons": "^4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@types/react": "*",
|
||||
"history": "^5.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-router": "6.0.0-beta.0",
|
||||
"react-use": "^17.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.13.1 || ^17.0.0",
|
||||
"react": "^16.13.1 || ^17.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@backstage/cli": "^0.10.0",
|
||||
"@backstage/core-app-api": "^0.1.24",
|
||||
|
||||
@@ -31,9 +31,8 @@ import {
|
||||
renderInTestApp,
|
||||
TestApiRegistry,
|
||||
} from '@backstage/test-utils';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { act, fireEvent } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Route, Routes } from 'react-router';
|
||||
import { EntityLayout } from './EntityLayout';
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
import React from 'react';
|
||||
import { Tabbed } from './Tabbed';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { act, fireEvent } from '@testing-library/react';
|
||||
import { Routes, Route } from 'react-router';
|
||||
|
||||
describe('Tabbed layout', () => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user