Remove circular dependencies
In reference to issue #5563 this does the initial work to remove all the circular dependencies that we have encountered while building backstage using bazel. The next step will be to implement a method to catch these circular dependencies before they get merged in Signed-off-by: jrusso1020 <jrusso@brex.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
---
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/core': patch
|
||||
'@backstage/core-api': patch
|
||||
'@backstage/integration': patch
|
||||
'@backstage/techdocs-common': patch
|
||||
'@backstage/plugin-api-docs': patch
|
||||
'@backstage/plugin-auth-backend': patch
|
||||
'@backstage/plugin-cloudbuild': patch
|
||||
'@backstage/plugin-github-actions': patch
|
||||
'@backstage/plugin-scaffolder-backend': patch
|
||||
'@backstage/plugin-techdocs': patch
|
||||
---
|
||||
|
||||
Remove circular dependencies
|
||||
@@ -32,7 +32,7 @@ import { Writable } from 'stream';
|
||||
// @public (undocumented)
|
||||
export class AzureUrlReader implements UrlReader {
|
||||
constructor(integration: AzureIntegration, deps: {
|
||||
treeResponseFactory: ReadTreeResponseFactory;
|
||||
treeResponseFactory: IReadTreeResponseFactory;
|
||||
});
|
||||
// (undocumented)
|
||||
static factory: ReaderFactory;
|
||||
@@ -49,7 +49,7 @@ export class AzureUrlReader implements UrlReader {
|
||||
// @public
|
||||
export class BitbucketUrlReader implements UrlReader {
|
||||
constructor(integration: BitbucketIntegration, deps: {
|
||||
treeResponseFactory: ReadTreeResponseFactory;
|
||||
treeResponseFactory: IReadTreeResponseFactory;
|
||||
});
|
||||
// (undocumented)
|
||||
static factory: ReaderFactory;
|
||||
@@ -214,7 +214,7 @@ export class Git {
|
||||
// @public
|
||||
export class GithubUrlReader implements UrlReader {
|
||||
constructor(integration: GitHubIntegration, deps: {
|
||||
treeResponseFactory: ReadTreeResponseFactory;
|
||||
treeResponseFactory: IReadTreeResponseFactory;
|
||||
credentialsProvider: GithubCredentialsProvider;
|
||||
});
|
||||
// (undocumented)
|
||||
@@ -232,7 +232,7 @@ export class GithubUrlReader implements UrlReader {
|
||||
// @public (undocumented)
|
||||
export class GitlabUrlReader implements UrlReader {
|
||||
constructor(integration: GitLabIntegration, deps: {
|
||||
treeResponseFactory: ReadTreeResponseFactory;
|
||||
treeResponseFactory: IReadTreeResponseFactory;
|
||||
});
|
||||
// (undocumented)
|
||||
static factory: ReaderFactory;
|
||||
|
||||
@@ -27,9 +27,9 @@ import parseGitUrl from 'git-url-parse';
|
||||
import { Minimatch } from 'minimatch';
|
||||
import { Readable } from 'stream';
|
||||
import { NotFoundError, NotModifiedError } from '@backstage/errors';
|
||||
import { ReadTreeResponseFactory } from './tree';
|
||||
import { stripFirstDirectoryFromPath } from './tree/util';
|
||||
import {
|
||||
IReadTreeResponseFactory,
|
||||
ReaderFactory,
|
||||
ReadTreeOptions,
|
||||
ReadTreeResponse,
|
||||
@@ -50,7 +50,7 @@ export class AzureUrlReader implements UrlReader {
|
||||
|
||||
constructor(
|
||||
private readonly integration: AzureIntegration,
|
||||
private readonly deps: { treeResponseFactory: ReadTreeResponseFactory },
|
||||
private readonly deps: { treeResponseFactory: IReadTreeResponseFactory },
|
||||
) {}
|
||||
|
||||
async read(url: string): Promise<Buffer> {
|
||||
|
||||
@@ -27,9 +27,9 @@ import parseGitUrl from 'git-url-parse';
|
||||
import { Minimatch } from 'minimatch';
|
||||
import { Readable } from 'stream';
|
||||
import { NotFoundError, NotModifiedError } from '@backstage/errors';
|
||||
import { ReadTreeResponseFactory } from './tree';
|
||||
import { stripFirstDirectoryFromPath } from './tree/util';
|
||||
import {
|
||||
IReadTreeResponseFactory,
|
||||
ReaderFactory,
|
||||
ReadTreeOptions,
|
||||
ReadTreeResponse,
|
||||
@@ -56,7 +56,7 @@ export class BitbucketUrlReader implements UrlReader {
|
||||
|
||||
constructor(
|
||||
private readonly integration: BitbucketIntegration,
|
||||
private readonly deps: { treeResponseFactory: ReadTreeResponseFactory },
|
||||
private readonly deps: { treeResponseFactory: IReadTreeResponseFactory },
|
||||
) {
|
||||
const {
|
||||
host,
|
||||
|
||||
@@ -26,8 +26,8 @@ import parseGitUrl from 'git-url-parse';
|
||||
import { Minimatch } from 'minimatch';
|
||||
import { Readable } from 'stream';
|
||||
import { NotFoundError, NotModifiedError } from '@backstage/errors';
|
||||
import { ReadTreeResponseFactory } from './tree';
|
||||
import {
|
||||
IReadTreeResponseFactory,
|
||||
ReaderFactory,
|
||||
ReadTreeOptions,
|
||||
ReadTreeResponse,
|
||||
@@ -65,7 +65,7 @@ export class GithubUrlReader implements UrlReader {
|
||||
constructor(
|
||||
private readonly integration: GitHubIntegration,
|
||||
private readonly deps: {
|
||||
treeResponseFactory: ReadTreeResponseFactory;
|
||||
treeResponseFactory: IReadTreeResponseFactory;
|
||||
credentialsProvider: GithubCredentialsProvider;
|
||||
},
|
||||
) {
|
||||
|
||||
@@ -25,9 +25,9 @@ import parseGitUrl from 'git-url-parse';
|
||||
import { Minimatch } from 'minimatch';
|
||||
import { Readable } from 'stream';
|
||||
import { NotFoundError, NotModifiedError } from '@backstage/errors';
|
||||
import { ReadTreeResponseFactory } from './tree';
|
||||
import { stripFirstDirectoryFromPath } from './tree/util';
|
||||
import {
|
||||
IReadTreeResponseFactory,
|
||||
ReaderFactory,
|
||||
ReadTreeOptions,
|
||||
ReadTreeResponse,
|
||||
@@ -50,7 +50,7 @@ export class GitlabUrlReader implements UrlReader {
|
||||
|
||||
constructor(
|
||||
private readonly integration: GitLabIntegration,
|
||||
private readonly deps: { treeResponseFactory: ReadTreeResponseFactory },
|
||||
private readonly deps: { treeResponseFactory: IReadTreeResponseFactory },
|
||||
) {}
|
||||
|
||||
async read(url: string): Promise<Buffer> {
|
||||
|
||||
@@ -15,25 +15,16 @@
|
||||
*/
|
||||
|
||||
import os from 'os';
|
||||
import { Readable } from 'stream';
|
||||
import { Config } from '@backstage/config';
|
||||
import { ReadTreeResponse } from '../types';
|
||||
import {
|
||||
ReadTreeResponse,
|
||||
FromArchiveOptions,
|
||||
IReadTreeResponseFactory,
|
||||
} from '../types';
|
||||
import { TarArchiveResponse } from './TarArchiveResponse';
|
||||
import { ZipArchiveResponse } from './ZipArchiveResponse';
|
||||
|
||||
type FromArchiveOptions = {
|
||||
// A binary stream of a tar archive.
|
||||
stream: Readable;
|
||||
// If unset, the files at the root of the tree will be read.
|
||||
// subpath must not contain the name of the top level directory.
|
||||
subpath?: string;
|
||||
// etag of the blob
|
||||
etag: string;
|
||||
// Filter passed on from the ReadTreeOptions
|
||||
filter?: (path: string) => boolean;
|
||||
};
|
||||
|
||||
export class ReadTreeResponseFactory {
|
||||
export class ReadTreeResponseFactory implements IReadTreeResponseFactory {
|
||||
static create(options: { config: Config }): ReadTreeResponseFactory {
|
||||
return new ReadTreeResponseFactory(
|
||||
options.config.getOptionalString('backend.workingDirectory') ??
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Readable } from 'stream';
|
||||
import { Logger } from 'winston';
|
||||
import { Config } from '@backstage/config';
|
||||
import { ReadTreeResponseFactory } from './tree';
|
||||
|
||||
/**
|
||||
* A generic interface for fetching plain data from URLs.
|
||||
@@ -39,7 +39,7 @@ export type UrlReaderPredicateTuple = {
|
||||
export type ReaderFactory = (options: {
|
||||
config: Config;
|
||||
logger: Logger;
|
||||
treeResponseFactory: ReadTreeResponseFactory;
|
||||
treeResponseFactory: IReadTreeResponseFactory;
|
||||
}) => UrlReaderPredicateTuple[];
|
||||
|
||||
/**
|
||||
@@ -105,6 +105,23 @@ export type ReadTreeResponseFile = {
|
||||
content(): Promise<Buffer>;
|
||||
};
|
||||
|
||||
export type FromArchiveOptions = {
|
||||
// A binary stream of a tar archive.
|
||||
stream: Readable;
|
||||
// If unset, the files at the root of the tree will be read.
|
||||
// subpath must not contain the name of the top level directory.
|
||||
subpath?: string;
|
||||
// etag of the blob
|
||||
etag: string;
|
||||
// Filter passed on from the ReadTreeOptions
|
||||
filter?: (path: string) => boolean;
|
||||
};
|
||||
|
||||
export interface IReadTreeResponseFactory {
|
||||
fromTarArchive(options: FromArchiveOptions): Promise<ReadTreeResponse>;
|
||||
fromZipArchive(options: FromArchiveOptions): Promise<ReadTreeResponse>;
|
||||
}
|
||||
|
||||
/**
|
||||
* An options object for search operations.
|
||||
*/
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { IconComponent } from '../../icons';
|
||||
import { IconComponent } from '../../icons/types';
|
||||
import { Observable } from '../../types';
|
||||
import { ApiRef, createApiRef } from '../system';
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { PublishSubject } from '../../../lib';
|
||||
import { PublishSubject } from '../../../lib/subjects';
|
||||
import { Observable } from '../../../types';
|
||||
import { AlertApi, AlertMessage } from '../../definitions';
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { AppThemeApi, AppTheme } from '../../definitions';
|
||||
import { BehaviorSubject } from '../../../lib';
|
||||
import { BehaviorSubject } from '../../../lib/subjects';
|
||||
import { Observable } from '../../../types';
|
||||
|
||||
const STORAGE_KEY = 'theme';
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { PublishSubject } from '../../../lib';
|
||||
import { PublishSubject } from '../../../lib/subjects';
|
||||
import { Observable } from '../../../types';
|
||||
import { ErrorApi, ErrorContext } from '../../definitions';
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BehaviorSubject } from '../../../lib';
|
||||
import { BehaviorSubject } from '../../../lib/subjects';
|
||||
import { Observable } from '../../../types';
|
||||
|
||||
type RequestQueueEntry<ResultType> = {
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
AuthRequesterOptions,
|
||||
} from '../../definitions';
|
||||
import { OAuthPendingRequests, PendingRequest } from './OAuthPendingRequests';
|
||||
import { BehaviorSubject } from '../../../lib';
|
||||
import { BehaviorSubject } from '../../../lib/subjects';
|
||||
import { Observable } from '../../../types';
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
*/
|
||||
|
||||
import { ComponentType } from 'react';
|
||||
import { IconComponent, IconComponentMap, IconKey } from '../icons';
|
||||
import { IconComponent, IconComponentMap, IconKey } from '../icons/types';
|
||||
import { AnyExternalRoutes, BackstagePlugin } from '../plugin/types';
|
||||
import { ExternalRouteRef, RouteRef } from '../routing';
|
||||
import { AnyApiFactory } from '../apis';
|
||||
import { ExternalRouteRef, RouteRef, SubRouteRef } from '../routing/types';
|
||||
import { AnyApiFactory } from '../apis/system';
|
||||
import { AppTheme, ProfileInfo } from '../apis/definitions';
|
||||
import { AppConfig } from '@backstage/config';
|
||||
import { SubRouteRef } from '../routing/types';
|
||||
|
||||
export type BootErrorPageProps = {
|
||||
step: 'load-config' | 'load-chunk';
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { AuthRequester } from '../../apis';
|
||||
import {
|
||||
AuthRequester,
|
||||
OAuthRequestApi,
|
||||
AuthProvider,
|
||||
DiscoveryApi,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SessionState } from '../../apis';
|
||||
import { SessionState } from '../../apis/definitions';
|
||||
import { Observable } from '../../types';
|
||||
import { BehaviorSubject } from '../subjects';
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import { Observable } from '../../types';
|
||||
import { SessionState } from '../../apis';
|
||||
import { SessionState } from '../../apis/definitions';
|
||||
|
||||
export type GetSessionOptions = {
|
||||
optional?: boolean;
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
ParamKeys,
|
||||
OptionalParams,
|
||||
} from './types';
|
||||
import { IconComponent } from '../icons';
|
||||
import { IconComponent } from '../icons/types';
|
||||
|
||||
// TODO(Rugvip): Remove this in the next breaking release, it's exported but unused
|
||||
export type RouteRefConfig<Params extends AnyParams> = {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { IconComponent } from '../icons';
|
||||
import { IconComponent } from '../icons/types';
|
||||
import { getOrCreateGlobalSingleton } from '../lib/globalObject';
|
||||
|
||||
export type AnyParams = { [param in string]: string } | undefined;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
import React, { useContext, ReactNode, PropsWithChildren } from 'react';
|
||||
import { Button, makeStyles } from '@material-ui/core';
|
||||
import { StepActions } from './SimpleStepperStep';
|
||||
import { StepActions } from './types';
|
||||
import { VerticalStepperContext } from './SimpleStepper';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import { SimpleStepperFooter } from './SimpleStepperFooter';
|
||||
import { StepProps } from './types';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
end: {
|
||||
@@ -29,30 +30,6 @@ const useStyles = makeStyles(theme => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export type StepActions = {
|
||||
showNext?: boolean;
|
||||
canNext?: () => boolean;
|
||||
onNext?: () => void;
|
||||
nextStep?: (current: number, last: number) => number;
|
||||
nextText?: string;
|
||||
|
||||
showBack?: boolean;
|
||||
backText?: string;
|
||||
onBack?: () => void;
|
||||
|
||||
showRestart?: boolean;
|
||||
canRestart?: () => boolean;
|
||||
onRestart?: () => void;
|
||||
restartText?: string;
|
||||
};
|
||||
|
||||
export type StepProps = {
|
||||
title: string;
|
||||
children: React.ReactElement;
|
||||
end?: boolean;
|
||||
actions?: StepActions;
|
||||
};
|
||||
|
||||
export const SimpleStepperStep = ({
|
||||
title,
|
||||
children,
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export type StepActions = {
|
||||
showNext?: boolean;
|
||||
canNext?: () => boolean;
|
||||
onNext?: () => void;
|
||||
nextStep?: (current: number, last: number) => number;
|
||||
nextText?: string;
|
||||
|
||||
showBack?: boolean;
|
||||
backText?: string;
|
||||
onBack?: () => void;
|
||||
|
||||
showRestart?: boolean;
|
||||
canRestart?: () => boolean;
|
||||
onRestart?: () => void;
|
||||
restartText?: string;
|
||||
};
|
||||
|
||||
export type StepProps = {
|
||||
title: string;
|
||||
children: React.ReactElement;
|
||||
end?: boolean;
|
||||
actions?: StepActions;
|
||||
};
|
||||
@@ -16,7 +16,8 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { matchRoutes, useNavigate, useParams, useRoutes } from 'react-router';
|
||||
import { Content, HeaderTabs } from '../../layout';
|
||||
import { Content } from '../../layout/Content';
|
||||
import { HeaderTabs } from '../../layout/HeaderTabs';
|
||||
import { SubRoute } from './types';
|
||||
|
||||
export function useSelectedSubRoute(
|
||||
|
||||
@@ -20,11 +20,8 @@ import { BitbucketIntegration } from './bitbucket/BitbucketIntegration';
|
||||
import { GitHubIntegration } from './github/GitHubIntegration';
|
||||
import { GitLabIntegration } from './gitlab/GitLabIntegration';
|
||||
import { defaultScmResolveUrl } from './helpers';
|
||||
import {
|
||||
ScmIntegration,
|
||||
ScmIntegrationRegistry,
|
||||
ScmIntegrationsGroup,
|
||||
} from './types';
|
||||
import { ScmIntegration, ScmIntegrationsGroup } from './types';
|
||||
import { ScmIntegrationRegistry } from './registry';
|
||||
|
||||
type IntegrationsByType = {
|
||||
azure: ScmIntegrationsGroup<AzureIntegration>;
|
||||
|
||||
@@ -21,8 +21,5 @@ export * from './gitlab';
|
||||
export * from './googleGcs';
|
||||
export { defaultScmResolveUrl } from './helpers';
|
||||
export { ScmIntegrations } from './ScmIntegrations';
|
||||
export type {
|
||||
ScmIntegration,
|
||||
ScmIntegrationRegistry,
|
||||
ScmIntegrationsGroup,
|
||||
} from './types';
|
||||
export type { ScmIntegration, ScmIntegrationsGroup } from './types';
|
||||
export type { ScmIntegrationRegistry } from './registry';
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ScmIntegration, ScmIntegrationsGroup } from './types';
|
||||
import { AzureIntegration } from './azure/AzureIntegration';
|
||||
import { BitbucketIntegration } from './bitbucket/BitbucketIntegration';
|
||||
import { GitHubIntegration } from './github/GitHubIntegration';
|
||||
import { GitLabIntegration } from './gitlab/GitLabIntegration';
|
||||
|
||||
/**
|
||||
* Holds all registered SCM integrations, of all types.
|
||||
*/
|
||||
export interface ScmIntegrationRegistry
|
||||
extends ScmIntegrationsGroup<ScmIntegration> {
|
||||
azure: ScmIntegrationsGroup<AzureIntegration>;
|
||||
bitbucket: ScmIntegrationsGroup<BitbucketIntegration>;
|
||||
github: ScmIntegrationsGroup<GitHubIntegration>;
|
||||
gitlab: ScmIntegrationsGroup<GitLabIntegration>;
|
||||
|
||||
/**
|
||||
* Resolves an absolute or relative URL in relation to a base URL.
|
||||
*
|
||||
* This method is adapted for use within SCM systems, so relative URLs are
|
||||
* within the context of the root of the hierarchy pointed to by the base
|
||||
* URL.
|
||||
*
|
||||
* For example, if the base URL is `<repo root url>/folder/a.yaml`, i.e.
|
||||
* within the file tree of a certain repo, an absolute path of `/b.yaml` does
|
||||
* not resolve to `https://hostname/b.yaml` but rather to
|
||||
* `<repo root url>/b.yaml` inside the file tree of that same repo.
|
||||
*
|
||||
* @param options.url The (absolute or relative) URL or path to resolve
|
||||
* @param options.base The base URL onto which this resolution happens
|
||||
* @param options.lineNumber The line number in the target file to link to, starting with 1. Only applicable when linking to files.
|
||||
*/
|
||||
resolveUrl(options: {
|
||||
url: string;
|
||||
base: string;
|
||||
lineNumber?: number;
|
||||
}): string;
|
||||
|
||||
/**
|
||||
* Resolves the edit URL for a file within the SCM system.
|
||||
*
|
||||
* Most SCM systems have a web interface that allows viewing and editing files
|
||||
* in the repository. The returned URL directly jumps into the edit mode for
|
||||
* the file.
|
||||
* If this is not possible, the integration can fall back to a URL to view
|
||||
* the file in the web interface.
|
||||
*
|
||||
* @param url The absolute URL to the file that should be edited.
|
||||
*/
|
||||
resolveEditUrl(url: string): string;
|
||||
}
|
||||
@@ -15,10 +15,6 @@
|
||||
*/
|
||||
|
||||
import { Config } from '@backstage/config';
|
||||
import { AzureIntegration } from './azure/AzureIntegration';
|
||||
import { BitbucketIntegration } from './bitbucket/BitbucketIntegration';
|
||||
import { GitHubIntegration } from './github/GitHubIntegration';
|
||||
import { GitLabIntegration } from './gitlab/GitLabIntegration';
|
||||
|
||||
/**
|
||||
* Encapsulates a single SCM integration.
|
||||
@@ -95,52 +91,6 @@ export interface ScmIntegrationsGroup<T extends ScmIntegration> {
|
||||
byHost(host: string): T | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds all registered SCM integrations, of all types.
|
||||
*/
|
||||
export interface ScmIntegrationRegistry
|
||||
extends ScmIntegrationsGroup<ScmIntegration> {
|
||||
azure: ScmIntegrationsGroup<AzureIntegration>;
|
||||
bitbucket: ScmIntegrationsGroup<BitbucketIntegration>;
|
||||
github: ScmIntegrationsGroup<GitHubIntegration>;
|
||||
gitlab: ScmIntegrationsGroup<GitLabIntegration>;
|
||||
|
||||
/**
|
||||
* Resolves an absolute or relative URL in relation to a base URL.
|
||||
*
|
||||
* This method is adapted for use within SCM systems, so relative URLs are
|
||||
* within the context of the root of the hierarchy pointed to by the base
|
||||
* URL.
|
||||
*
|
||||
* For example, if the base URL is `<repo root url>/folder/a.yaml`, i.e.
|
||||
* within the file tree of a certain repo, an absolute path of `/b.yaml` does
|
||||
* not resolve to `https://hostname/b.yaml` but rather to
|
||||
* `<repo root url>/b.yaml` inside the file tree of that same repo.
|
||||
*
|
||||
* @param options.url The (absolute or relative) URL or path to resolve
|
||||
* @param options.base The base URL onto which this resolution happens
|
||||
* @param options.lineNumber The line number in the target file to link to, starting with 1. Only applicable when linking to files.
|
||||
*/
|
||||
resolveUrl(options: {
|
||||
url: string;
|
||||
base: string;
|
||||
lineNumber?: number;
|
||||
}): string;
|
||||
|
||||
/**
|
||||
* Resolves the edit URL for a file within the SCM system.
|
||||
*
|
||||
* Most SCM systems have a web interface that allows viewing and editing files
|
||||
* in the repository. The returned URL directly jumps into the edit mode for
|
||||
* the file.
|
||||
* If this is not possible, the integration can fall back to a URL to view
|
||||
* the file in the web interface.
|
||||
*
|
||||
* @param url The absolute URL to the file that should be edited.
|
||||
*/
|
||||
resolveEditUrl(url: string): string;
|
||||
}
|
||||
|
||||
export type ScmIntegrationsFactory<T extends ScmIntegration> = (options: {
|
||||
config: Config;
|
||||
}) => ScmIntegrationsGroup<T>;
|
||||
|
||||
@@ -18,7 +18,9 @@ import { Entity } from '@backstage/catalog-model';
|
||||
import { Config } from '@backstage/config';
|
||||
import { Logger } from 'winston';
|
||||
import { parseReferenceAnnotation } from '../../helpers';
|
||||
import { CommonGitPreparer, DirectoryPreparer, UrlPreparer } from '../prepare';
|
||||
import { DirectoryPreparer } from './dir';
|
||||
import { CommonGitPreparer } from './commonGit';
|
||||
import { UrlPreparer } from './url';
|
||||
import { PreparerBase, PreparerBuilder, RemoteProtocol } from './types';
|
||||
|
||||
type factoryOptions = {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { ApiEntity } from '@backstage/catalog-model';
|
||||
import { createApiRef } from '@backstage/core';
|
||||
import { ApiDefinitionWidget } from './components';
|
||||
import { ApiDefinitionWidget } from './components/ApiDefinitionCard/ApiDefinitionWidget';
|
||||
|
||||
export const apiDocsConfigRef = createApiRef<ApiDocsConfig>({
|
||||
id: 'plugin.api-docs.config',
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
AuthProviderConfig,
|
||||
} from '../../providers/types';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import { TokenIssuer } from '../../identity/types';
|
||||
import { verifyNonce } from './helpers';
|
||||
import { postMessageResponse, ensuresXRequestedWith } from '../flow';
|
||||
import { OAuthHandlers, OAuthStartRequest, OAuthRefreshRequest } from './types';
|
||||
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
PassportDoneCallback,
|
||||
} from '../../lib/passport';
|
||||
import { AuthProviderFactory, RedirectInfo } from '../types';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import { TokenIssuer } from '../../identity/types';
|
||||
|
||||
type PrivateInfo = {
|
||||
refreshToken: string;
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
} from '../../lib/passport';
|
||||
import { AuthProviderRouteHandlers, AuthProviderFactory } from '../types';
|
||||
import { postMessageResponse } from '../../lib/flow';
|
||||
import { TokenIssuer } from '../../identity';
|
||||
import { TokenIssuer } from '../../identity/types';
|
||||
|
||||
type SamlInfo = {
|
||||
fullProfile: any;
|
||||
|
||||
@@ -19,7 +19,7 @@ import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import express from 'express';
|
||||
import { Logger } from 'winston';
|
||||
import { TokenIssuer } from '../identity';
|
||||
import { TokenIssuer } from '../identity/types';
|
||||
|
||||
export type AuthProviderConfig = {
|
||||
/**
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, { useEffect } from 'react';
|
||||
import { useWorkflowRuns } from '../useWorkflowRuns';
|
||||
import { WorkflowRun, WorkflowRunsTable } from '../WorkflowRunsTable';
|
||||
import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns';
|
||||
import { WorkflowRunsTable } from '../WorkflowRunsTable';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { WorkflowRunStatus } from '../WorkflowRunStatus';
|
||||
|
||||
@@ -17,7 +17,7 @@ import React from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { Routes, Route } from 'react-router';
|
||||
import { rootRouteRef, buildRouteRef } from '../plugin';
|
||||
import { rootRouteRef, buildRouteRef } from '../routes';
|
||||
import { WorkflowRunDetails } from './WorkflowRunDetails';
|
||||
import { WorkflowRunsTable } from './WorkflowRunsTable';
|
||||
import { CLOUDBUILD_ANNOTATION } from './useProjectName';
|
||||
|
||||
@@ -19,26 +19,14 @@ import RetryIcon from '@material-ui/icons/Replay';
|
||||
import GoogleIcon from '@material-ui/icons/CloudCircle';
|
||||
import { Link as RouterLink, generatePath } from 'react-router-dom';
|
||||
import { Table, TableColumn } from '@backstage/core';
|
||||
import { useWorkflowRuns } from '../useWorkflowRuns';
|
||||
import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns';
|
||||
import { WorkflowRunStatus } from '../WorkflowRunStatus';
|
||||
import SyncIcon from '@material-ui/icons/Sync';
|
||||
import { useProjectName } from '../useProjectName';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { Substitutions } from '../../api/types';
|
||||
import { buildRouteRef } from '../../plugin';
|
||||
import { buildRouteRef } from '../../routes';
|
||||
import moment from 'moment';
|
||||
|
||||
export type WorkflowRun = {
|
||||
id: string;
|
||||
message: string;
|
||||
url?: string;
|
||||
googleUrl?: string;
|
||||
status: string;
|
||||
substitutions: Substitutions;
|
||||
createTime: string;
|
||||
rerun: () => void;
|
||||
};
|
||||
|
||||
const generatedColumns: TableColumn[] = [
|
||||
{
|
||||
title: 'Status',
|
||||
|
||||
@@ -14,4 +14,3 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { WorkflowRunsTable, WorkflowRunsTableView } from './WorkflowRunsTable';
|
||||
export type { WorkflowRun } from './WorkflowRunsTable';
|
||||
|
||||
@@ -15,10 +15,23 @@
|
||||
*/
|
||||
import { useState } from 'react';
|
||||
import { useAsyncRetry } from 'react-use';
|
||||
import { WorkflowRun } from './WorkflowRunsTable/WorkflowRunsTable';
|
||||
import { cloudbuildApiRef } from '../api/CloudbuildApi';
|
||||
import { useApi, errorApiRef } from '@backstage/core';
|
||||
import { ActionsListWorkflowRunsForRepoResponseData } from '../api/types';
|
||||
import {
|
||||
ActionsListWorkflowRunsForRepoResponseData,
|
||||
Substitutions,
|
||||
} from '../api/types';
|
||||
|
||||
export type WorkflowRun = {
|
||||
id: string;
|
||||
message: string;
|
||||
url?: string;
|
||||
googleUrl?: string;
|
||||
status: string;
|
||||
substitutions: Substitutions;
|
||||
createTime: string;
|
||||
rerun: () => void;
|
||||
};
|
||||
|
||||
export function useWorkflowRuns({ projectId }: { projectId: string }) {
|
||||
const api = useApi(cloudbuildApiRef);
|
||||
|
||||
@@ -15,23 +15,13 @@
|
||||
*/
|
||||
import {
|
||||
createPlugin,
|
||||
createRouteRef,
|
||||
createApiFactory,
|
||||
googleAuthApiRef,
|
||||
createRoutableExtension,
|
||||
createComponentExtension,
|
||||
} from '@backstage/core';
|
||||
import { cloudbuildApiRef, CloudbuildClient } from './api';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '',
|
||||
title: 'Google Cloudbuild',
|
||||
});
|
||||
|
||||
export const buildRouteRef = createRouteRef({
|
||||
path: ':id',
|
||||
title: 'Cloudbuild Run',
|
||||
});
|
||||
import { rootRouteRef } from './routes';
|
||||
|
||||
export const cloudbuildPlugin = createPlugin({
|
||||
id: 'cloudbuild',
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { createRouteRef } from '@backstage/core';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '',
|
||||
title: 'Google Cloudbuild',
|
||||
});
|
||||
|
||||
export const buildRouteRef = createRouteRef({
|
||||
path: ':id',
|
||||
title: 'Cloudbuild Run',
|
||||
});
|
||||
@@ -34,8 +34,8 @@ import {
|
||||
import ExternalLinkIcon from '@material-ui/icons/Launch';
|
||||
import React, { useEffect } from 'react';
|
||||
import { GITHUB_ACTIONS_ANNOTATION } from '../useProjectName';
|
||||
import { useWorkflowRuns } from '../useWorkflowRuns';
|
||||
import { WorkflowRun, WorkflowRunsTable } from '../WorkflowRunsTable';
|
||||
import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns';
|
||||
import { WorkflowRunsTable } from '../WorkflowRunsTable';
|
||||
import { WorkflowRunStatus } from '../WorkflowRunStatus';
|
||||
|
||||
const useStyles = makeStyles<Theme>({
|
||||
|
||||
@@ -17,7 +17,7 @@ import React from 'react';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { useEntity } from '@backstage/plugin-catalog-react';
|
||||
import { Routes, Route } from 'react-router';
|
||||
import { rootRouteRef, buildRouteRef } from '../plugin';
|
||||
import { rootRouteRef, buildRouteRef } from '../routes';
|
||||
import { WorkflowRunDetails } from './WorkflowRunDetails';
|
||||
import { WorkflowRunsTable } from './WorkflowRunsTable';
|
||||
import { GITHUB_ACTIONS_ANNOTATION } from './useProjectName';
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
import { useApi, useRouteRefParams } from '@backstage/core';
|
||||
import { useAsync } from 'react-use';
|
||||
import { githubActionsApiRef } from '../../api';
|
||||
import { buildRouteRef } from '../../plugin';
|
||||
import { buildRouteRef } from '../../routes';
|
||||
|
||||
export const useWorkflowRunsDetails = ({
|
||||
hostname,
|
||||
|
||||
@@ -32,32 +32,14 @@ import {
|
||||
configApiRef,
|
||||
useApi,
|
||||
} from '@backstage/core';
|
||||
import { useWorkflowRuns } from '../useWorkflowRuns';
|
||||
import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns';
|
||||
import { WorkflowRunStatus } from '../WorkflowRunStatus';
|
||||
import SyncIcon from '@material-ui/icons/Sync';
|
||||
import { buildRouteRef } from '../../plugin';
|
||||
import { buildRouteRef } from '../../routes';
|
||||
import { useProjectName } from '../useProjectName';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { readGitHubIntegrationConfigs } from '@backstage/integration';
|
||||
|
||||
export type WorkflowRun = {
|
||||
workflowName: string;
|
||||
id: string;
|
||||
message: string;
|
||||
url?: string;
|
||||
githubUrl?: string;
|
||||
source: {
|
||||
branchName: string;
|
||||
commit: {
|
||||
hash: string;
|
||||
url?: string;
|
||||
};
|
||||
};
|
||||
status: string;
|
||||
conclusion: string;
|
||||
onReRunClick: () => void;
|
||||
};
|
||||
|
||||
const generatedColumns: TableColumn[] = [
|
||||
{
|
||||
title: 'ID',
|
||||
|
||||
@@ -14,4 +14,3 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { WorkflowRunsTable, WorkflowRunsTableView } from './WorkflowRunsTable';
|
||||
export type { WorkflowRun } from './WorkflowRunsTable';
|
||||
|
||||
@@ -15,10 +15,27 @@
|
||||
*/
|
||||
import { useState } from 'react';
|
||||
import { useAsyncRetry } from 'react-use';
|
||||
import { WorkflowRun } from './WorkflowRunsTable/WorkflowRunsTable';
|
||||
import { githubActionsApiRef } from '../api/GithubActionsApi';
|
||||
import { useApi, errorApiRef } from '@backstage/core';
|
||||
|
||||
export type WorkflowRun = {
|
||||
workflowName: string;
|
||||
id: string;
|
||||
message: string;
|
||||
url?: string;
|
||||
githubUrl?: string;
|
||||
source: {
|
||||
branchName: string;
|
||||
commit: {
|
||||
hash: string;
|
||||
url?: string;
|
||||
};
|
||||
};
|
||||
status: string;
|
||||
conclusion: string;
|
||||
onReRunClick: () => void;
|
||||
};
|
||||
|
||||
export function useWorkflowRuns({
|
||||
hostname,
|
||||
owner,
|
||||
|
||||
@@ -17,25 +17,13 @@
|
||||
import {
|
||||
configApiRef,
|
||||
createPlugin,
|
||||
createRouteRef,
|
||||
createApiFactory,
|
||||
githubAuthApiRef,
|
||||
createRoutableExtension,
|
||||
createComponentExtension,
|
||||
} from '@backstage/core';
|
||||
import { githubActionsApiRef, GithubActionsClient } from './api';
|
||||
|
||||
// TODO(freben): This is just a demo route for now
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '',
|
||||
title: 'GitHub Actions',
|
||||
});
|
||||
|
||||
export const buildRouteRef = createRouteRef({
|
||||
path: ':id',
|
||||
params: ['id'],
|
||||
title: 'GitHub Actions Workflow Run',
|
||||
});
|
||||
import { rootRouteRef } from './routes';
|
||||
|
||||
export const githubActionsPlugin = createPlugin({
|
||||
id: 'github-actions',
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createRouteRef } from '@backstage/core';
|
||||
|
||||
// TODO(freben): This is just a demo route for now
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '',
|
||||
title: 'GitHub Actions',
|
||||
});
|
||||
|
||||
export const buildRouteRef = createRouteRef({
|
||||
path: ':id',
|
||||
params: ['id'],
|
||||
title: 'GitHub Actions Workflow Run',
|
||||
});
|
||||
@@ -17,5 +17,3 @@ export * from './prepare';
|
||||
export * from './publish';
|
||||
export * from './templater';
|
||||
export * from './helpers';
|
||||
|
||||
export { createLegacyActions } from './legacy';
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
rootRouteRef,
|
||||
rootDocsRouteRef,
|
||||
rootCatalogDocsRouteRef,
|
||||
} from './plugin';
|
||||
} from './routes';
|
||||
import { TechDocsHome } from './home/components/TechDocsHome';
|
||||
import { TechDocsPage } from './reader/components/TechDocsPage';
|
||||
import { EntityPageDocs } from './EntityPageDocs';
|
||||
|
||||
@@ -21,7 +21,7 @@ import { Entity } from '@backstage/catalog-model';
|
||||
import { Button, ItemCardGrid, ItemCardHeader } from '@backstage/core';
|
||||
import { Card, CardActions, CardContent, CardMedia } from '@material-ui/core';
|
||||
|
||||
import { rootDocsRouteRef } from '../../plugin';
|
||||
import { rootDocsRouteRef } from '../../routes';
|
||||
|
||||
export const DocsCardGrid = ({
|
||||
entities,
|
||||
|
||||
@@ -22,7 +22,7 @@ import { IconButton, Tooltip } from '@material-ui/core';
|
||||
import ShareIcon from '@material-ui/icons/Share';
|
||||
import { Table, EmptyState, Button, SubvalueCell, Link } from '@backstage/core';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { rootDocsRouteRef } from '../../plugin';
|
||||
import { rootDocsRouteRef } from '../../routes';
|
||||
|
||||
export const DocsTable = ({
|
||||
entities,
|
||||
|
||||
@@ -20,27 +20,16 @@ import {
|
||||
createComponentExtension,
|
||||
createPlugin,
|
||||
createRoutableExtension,
|
||||
createRouteRef,
|
||||
discoveryApiRef,
|
||||
identityApiRef,
|
||||
} from '@backstage/core';
|
||||
import { techdocsApiRef, techdocsStorageApiRef } from './api';
|
||||
import { TechDocsClient, TechDocsStorageClient } from './client';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '',
|
||||
title: 'TechDocs Landing Page',
|
||||
});
|
||||
|
||||
export const rootDocsRouteRef = createRouteRef({
|
||||
path: ':namespace/:kind/:name/*',
|
||||
title: 'Docs',
|
||||
});
|
||||
|
||||
export const rootCatalogDocsRouteRef = createRouteRef({
|
||||
path: '*',
|
||||
title: 'Docs',
|
||||
});
|
||||
import {
|
||||
rootDocsRouteRef,
|
||||
rootRouteRef,
|
||||
rootCatalogDocsRouteRef,
|
||||
} from './routes';
|
||||
|
||||
export const techdocsPlugin = createPlugin({
|
||||
id: 'techdocs',
|
||||
|
||||
@@ -23,7 +23,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useAsync } from 'react-use';
|
||||
import { techdocsStorageApiRef } from '../../api';
|
||||
import transformer, {
|
||||
import {
|
||||
addBaseUrl,
|
||||
addGitFeedbackLink,
|
||||
addLinkClickListener,
|
||||
@@ -33,6 +33,7 @@ import transformer, {
|
||||
rewriteDocLinks,
|
||||
sanitizeDOM,
|
||||
simplifyMkdocsFooter,
|
||||
transform as transformer,
|
||||
} from '../transformers';
|
||||
import { TechDocsNotFound } from './TechDocsNotFound';
|
||||
import TechDocsProgressBar from './TechDocsProgressBar';
|
||||
|
||||
@@ -18,7 +18,7 @@ import { TechDocsPageHeader } from './TechDocsPageHeader';
|
||||
import { act } from '@testing-library/react';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import { entityRouteRef } from '@backstage/plugin-catalog-react';
|
||||
import { rootRouteRef } from '../../plugin';
|
||||
import { rootRouteRef } from '../../routes';
|
||||
|
||||
describe('<TechDocsPageHeader />', () => {
|
||||
it('should render a techdocs page header', async () => {
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
import CodeIcon from '@material-ui/icons/Code';
|
||||
import React from 'react';
|
||||
import { AsyncState } from 'react-use/lib/useAsync';
|
||||
import { rootRouteRef } from '../../plugin';
|
||||
import { rootRouteRef } from '../../routes';
|
||||
import { TechDocsMetadata } from '../../types';
|
||||
|
||||
type TechDocsPageHeaderProps = {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { EntityName } from '@backstage/catalog-model';
|
||||
import type { Transformer } from './index';
|
||||
import type { Transformer } from './transformer';
|
||||
import { TechDocsStorageApi } from '../../api';
|
||||
|
||||
type AddBaseUrlOptions = {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Transformer } from './index';
|
||||
import type { Transformer } from './transformer';
|
||||
|
||||
type AddLinkClickListenerOptions = {
|
||||
baseUrl: string;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import transform, { Transformer } from './index';
|
||||
import { Transformer, transform } from './transformer';
|
||||
|
||||
describe('transform', () => {
|
||||
it('calls the transformers', () => {
|
||||
|
||||
@@ -23,30 +23,4 @@ export * from './simplifyMkdocsFooter';
|
||||
export * from './onCssReady';
|
||||
export * from './sanitizeDOM';
|
||||
export * from './injectCss';
|
||||
|
||||
// TODO(freben): move all of this out of index
|
||||
|
||||
export type Transformer = (dom: Element) => Element;
|
||||
|
||||
function transform(
|
||||
html: string | Element,
|
||||
transformers: Transformer[],
|
||||
): Element {
|
||||
let dom: Element;
|
||||
|
||||
if (typeof html === 'string') {
|
||||
dom = new DOMParser().parseFromString(html, 'text/html').documentElement;
|
||||
} else if (html instanceof Element) {
|
||||
dom = html;
|
||||
} else {
|
||||
throw new Error('dom is not a recognized type');
|
||||
}
|
||||
|
||||
transformers.forEach(transformer => {
|
||||
dom = transformer(dom);
|
||||
});
|
||||
|
||||
return dom;
|
||||
}
|
||||
|
||||
export default transform;
|
||||
export * from './transformer';
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Transformer } from './index';
|
||||
import type { Transformer } from './transformer';
|
||||
|
||||
type InjectCssOptions = {
|
||||
css: string;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Transformer } from './index';
|
||||
import type { Transformer } from './transformer';
|
||||
|
||||
type OnCssReadyOptions = {
|
||||
docStorageUrl: Promise<string>;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Transformer } from './index';
|
||||
import type { Transformer } from './transformer';
|
||||
|
||||
export const removeMkdocsHeader = (): Transformer => {
|
||||
return dom => {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Transformer } from './index';
|
||||
import type { Transformer } from './transformer';
|
||||
|
||||
export const rewriteDocLinks = (): Transformer => {
|
||||
return dom => {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// @ts-ignore
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
import type { Transformer } from '../index';
|
||||
import type { Transformer } from '../transformer';
|
||||
import { TECHDOCS_ALLOWED_TAGS } from './tags';
|
||||
import { TECHDOCS_ALLOWED_ATTRIBUTES } from './attributes';
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Transformer } from './index';
|
||||
import type { Transformer } from './transformer';
|
||||
|
||||
export const simplifyMkdocsFooter = (): Transformer => {
|
||||
return dom => {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export type Transformer = (dom: Element) => Element;
|
||||
|
||||
export const transform = (
|
||||
html: string | Element,
|
||||
transformers: Transformer[],
|
||||
): Element => {
|
||||
let dom: Element;
|
||||
|
||||
if (typeof html === 'string') {
|
||||
dom = new DOMParser().parseFromString(html, 'text/html').documentElement;
|
||||
} else if (html instanceof Element) {
|
||||
dom = html;
|
||||
} else {
|
||||
throw new Error('dom is not a recognized type');
|
||||
}
|
||||
|
||||
transformers.forEach(transformer => {
|
||||
dom = transformer(dom);
|
||||
});
|
||||
|
||||
return dom;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createRouteRef } from '@backstage/core';
|
||||
|
||||
export const rootRouteRef = createRouteRef({
|
||||
path: '',
|
||||
title: 'TechDocs Landing Page',
|
||||
});
|
||||
|
||||
export const rootDocsRouteRef = createRouteRef({
|
||||
path: ':namespace/:kind/:name/*',
|
||||
title: 'Docs',
|
||||
});
|
||||
|
||||
export const rootCatalogDocsRouteRef = createRouteRef({
|
||||
path: '*',
|
||||
title: 'Docs',
|
||||
});
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import transformer from '../reader/transformers';
|
||||
import type { Transformer } from '../reader/transformers';
|
||||
import { transform as transformer } from '../reader/transformers';
|
||||
|
||||
export type CreateTestShadowDomOptions = {
|
||||
preTransformers: Transformer[];
|
||||
|
||||
Reference in New Issue
Block a user