moved over the urlreader to backend-defaults

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2024-05-23 16:40:18 +02:00
parent 5c50d66192
commit b2ee7f3a65
78 changed files with 1338 additions and 738 deletions
+15
View File
@@ -0,0 +1,15 @@
---
'@backstage/backend-plugin-api': patch
---
Deprecated all of the `UrlReader` related type names and replaced them with prefixed versions. Please update your imports.
- `ReadTreeOptions` was renamed to `UrlReaderReadTreeOptions`
- `ReadTreeResponse` was renamed to `UrlReaderReadTreeResponse`
- `ReadTreeResponseDirOptions` was renamed to `UrlReaderReadTreeResponseDirOptions`
- `ReadTreeResponseFile` was renamed to `UrlReaderReadTreeResponseFile`
- `ReadUrlResponse` was renamed to `UrlReaderReadUrlResponse`
- `ReadUrlOptions` was renamed to `UrlReaderReadUrlOptions`
- `SearchOptions` was renamed to `UrlReaderSearchOptions`
- `SearchResponse` was renamed to `UrlReaderSearchResponse`
- `SearchResponseFile` was renamed to `UrlReaderSearchResponseFile`
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/backend-defaults': patch
'@backstage/backend-common': patch
---
Moved over all URL reader functionality from `@backstage/backend-common` to `@backstage/backend-defaults/urlReader`. Please update your imports.
+3 -4
View File
@@ -19,7 +19,7 @@ files before generating a documentation site.
Since, the requirement for reading files is so essential for Backstage plugins,
the
[`@backstage/backend-common`](https://github.com/backstage/backstage/tree/master/packages/backend-common)
[`coreServices.urlReader`](../reference/backend-plugin-api.coreservices.urlreader/)
package provides a dedicated API for reading from such URL based remote
locations like GitHub, GitLab, Bitbucket, Google Cloud Storage, etc. This is
commonly referred to as "URL Reader". It takes care of making authenticated
@@ -49,9 +49,8 @@ function makeCreateEnv(config: Config) {
}
```
This instance contains all
[the default URL Reader providers](https://github.com/backstage/backstage/blob/master/packages/backend-common/src/reading/UrlReaders.ts)
in the backend-common package including GitHub, GitLab, Bitbucket, Azure, Google
This instance contains all the default URL Reader providers
in the backend-defaults package including GitHub, GitLab, Bitbucket, Azure, Google
GCS. As the need arises, more URL Readers are being written to support different
providers.
+1 -1
View File
@@ -17,7 +17,7 @@
"build:all": "backstage-cli repo build --all",
"build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'",
"build:api-reports": "yarn build:api-reports:only --tsc",
"build:api-reports:only": "NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags",
"build:api-reports:only": "NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --allow-warnings 'packages/backend-common,packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags",
"build:backend": "yarn workspace example-backend build",
"build:knip-reports": "backstage-repo-tools knip-reports",
"build:plugins-report": "node ./scripts/build-plugins-report",
+5 -2
View File
@@ -42,7 +42,7 @@ import { ServiceFactory } from '@backstage/backend-plugin-api';
import { ServiceFactoryOrFunction } from '@backstage/backend-plugin-api';
import { TokenManagerService } from '@backstage/backend-plugin-api';
import { transport } from 'winston';
import { UrlReader } from '@backstage/backend-common';
import { UrlReaderService } from '@backstage/backend-plugin-api';
import { UserInfoService } from '@backstage/backend-plugin-api';
// @public (undocumented)
@@ -339,7 +339,10 @@ export const tokenManagerServiceFactory: () => ServiceFactory<
>;
// @public @deprecated (undocumented)
export const urlReaderServiceFactory: () => ServiceFactory<UrlReader, 'plugin'>;
export const urlReaderServiceFactory: () => ServiceFactory<
UrlReaderService,
'plugin'
>;
// @public (undocumented)
export const userInfoServiceFactory: () => ServiceFactory<
+118 -323
View File
@@ -49,26 +49,32 @@ import { PluginMetadataService } from '@backstage/backend-plugin-api';
import { PushResult } from 'isomorphic-git';
import { Readable } from 'stream';
import { ReadCommitResult } from 'isomorphic-git';
import { ReadTreeOptions } from '@backstage/backend-plugin-api';
import { ReadTreeResponse } from '@backstage/backend-plugin-api';
import { ReadTreeResponseDirOptions } from '@backstage/backend-plugin-api';
import { ReadTreeResponseFile } from '@backstage/backend-plugin-api';
import { ReadUrlOptions } from '@backstage/backend-plugin-api';
import { ReadUrlResponse } from '@backstage/backend-plugin-api';
import type { ReadTreeOptions as ReadTreeOptions_2 } from '@backstage/backend-plugin-api';
import type { ReadTreeResponse as ReadTreeResponse_2 } from '@backstage/backend-plugin-api';
import type { ReadTreeResponseDirOptions as ReadTreeResponseDirOptions_2 } from '@backstage/backend-plugin-api';
import type { ReadTreeResponseFile as ReadTreeResponseFile_2 } from '@backstage/backend-plugin-api';
import type { ReadUrlOptions as ReadUrlOptions_2 } from '@backstage/backend-plugin-api';
import type { ReadUrlResponse as ReadUrlResponse_2 } from '@backstage/backend-plugin-api';
import { RequestHandler } from 'express';
import { resolvePackagePath as resolvePackagePath_2 } from '@backstage/backend-plugin-api';
import { resolveSafeChildPath as resolveSafeChildPath_2 } from '@backstage/backend-plugin-api';
import { RootConfigService } from '@backstage/backend-plugin-api';
import { Router } from 'express';
import { SchedulerService } from '@backstage/backend-plugin-api';
import { SearchOptions } from '@backstage/backend-plugin-api';
import { SearchResponse } from '@backstage/backend-plugin-api';
import { SearchResponseFile } from '@backstage/backend-plugin-api';
import type { SearchOptions as SearchOptions_2 } from '@backstage/backend-plugin-api';
import type { SearchResponse as SearchResponse_2 } from '@backstage/backend-plugin-api';
import type { SearchResponseFile as SearchResponseFile_2 } from '@backstage/backend-plugin-api';
import { Server } from 'http';
import { ServiceRef } from '@backstage/backend-plugin-api';
import { TokenManagerService as TokenManager } from '@backstage/backend-plugin-api';
import { TransportStreamOptions } from 'winston-transport';
import { UrlReaderService as UrlReader } from '@backstage/backend-plugin-api';
import { UrlReaderReadTreeOptions } from '@backstage/backend-plugin-api';
import { UrlReaderReadTreeResponse } from '@backstage/backend-plugin-api';
import { UrlReaderReadUrlOptions } from '@backstage/backend-plugin-api';
import { UrlReaderReadUrlResponse } from '@backstage/backend-plugin-api';
import { UrlReaderSearchOptions } from '@backstage/backend-plugin-api';
import { UrlReaderSearchResponse } from '@backstage/backend-plugin-api';
import { UrlReaderService } from '@backstage/backend-plugin-api';
import { UserInfoService } from '@backstage/backend-plugin-api';
import { V1PodTemplateSpec } from '@kubernetes/client-node';
import * as winston from 'winston';
@@ -80,118 +86,30 @@ export type AuthCallbackOptions = {
logger?: LoggerService;
};
// @public
export class AwsS3UrlReader implements UrlReader {
constructor(
credsManager: AwsCredentialsManager,
integration: AwsS3Integration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "AwsS3UrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const AwsS3UrlReader: typeof AwsS3UrlReader_2;
// @public
export class AzureUrlReader implements UrlReader {
constructor(
integration: AzureIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
credentialsProvider: AzureDevOpsCredentialsProvider;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "AzureUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const AzureUrlReader: typeof AzureUrlReader_2;
// @public
export class BitbucketCloudUrlReader implements UrlReader {
constructor(
integration: BitbucketCloudIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "BitbucketCloudUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const BitbucketCloudUrlReader: typeof BitbucketCloudUrlReader_2;
// @public
export class BitbucketServerUrlReader implements UrlReader {
constructor(
integration: BitbucketServerIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "BitbucketServerUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const BitbucketServerUrlReader: typeof BitbucketServerUrlReader_2;
// @public @deprecated
export class BitbucketUrlReader implements UrlReader {
constructor(
integration: BitbucketIntegration,
logger: LoggerService,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "BitbucketUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const BitbucketUrlReader: typeof BitbucketUrlReader_2;
// @public @deprecated (undocumented)
export type CacheClient = CacheService;
@@ -330,50 +248,20 @@ export type ErrorHandlerOptions = {
logClientErrors?: boolean;
};
// @public
export class FetchUrlReader implements UrlReader {
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "FetchUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const FetchUrlReader: typeof FetchUrlReader_2;
// @public
export type FromReadableArrayOptions = Array<{
data: Readable;
path: string;
lastModifiedAt?: Date;
}>;
// Warning: (ae-forgotten-export) The symbol "FromReadableArrayOptions_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export type FromReadableArrayOptions = FromReadableArrayOptions_2;
// @public
export class GerritUrlReader implements UrlReader {
constructor(
integration: GerritIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
workDir: string,
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "GerritUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const GerritUrlReader: typeof GerritUrlReader_2;
// @public @deprecated
export function getRootLogger(): winston.Logger;
@@ -457,94 +345,25 @@ export class Git {
resolveRef(options: { dir: string; ref: string }): Promise<string>;
}
// @public
export class GiteaUrlReader implements UrlReader {
constructor(
integration: GiteaIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "GiteaUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const GiteaUrlReader: typeof GiteaUrlReader_2;
// @public
export class GithubUrlReader implements UrlReader {
constructor(
integration: GithubIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
credentialsProvider: GithubCredentialsProvider;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "GithubUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const GithubUrlReader: typeof GithubUrlReader_2;
// @public
export class GitlabUrlReader implements UrlReader {
constructor(
integration: GitLabIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "GitlabUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const GitlabUrlReader: typeof GitlabUrlReader_2;
// @public
export class HarnessUrlReader implements UrlReader {
constructor(
integration: HarnessIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
// (undocumented)
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
// (undocumented)
search(): Promise<SearchResponse>;
// (undocumented)
toString(): string;
}
// Warning: (ae-forgotten-export) The symbol "HarnessUrlReader_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const HarnessUrlReader: typeof HarnessUrlReader_2;
// @public @deprecated
export const HostDiscovery: typeof HostDiscovery_2;
@@ -596,7 +415,7 @@ export const legacyPlugin: (
permissions: PermissionsService;
scheduler: SchedulerService;
tokenManager: TokenManager;
reader: UrlReader;
reader: UrlReaderService;
identity: IdentityService;
},
{
@@ -677,73 +496,49 @@ export interface PullOptions {
};
}
// @public
export type ReaderFactory = (options: {
config: Config;
logger: LoggerService;
treeResponseFactory: ReadTreeResponseFactory;
}) => UrlReaderPredicateTuple[];
// Warning: (ae-forgotten-export) The symbol "ReaderFactory_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export type ReaderFactory = ReaderFactory_2;
export { ReadTreeOptions };
// @public @deprecated (undocumented)
export type ReadTreeOptions = ReadTreeOptions_2;
export { ReadTreeResponse };
// @public @deprecated (undocumented)
export type ReadTreeResponse = ReadTreeResponse_2;
export { ReadTreeResponseDirOptions };
// @public @deprecated (undocumented)
export type ReadTreeResponseDirOptions = ReadTreeResponseDirOptions_2;
// @public
export interface ReadTreeResponseFactory {
// (undocumented)
fromReadableArray(
options: FromReadableArrayOptions,
): Promise<ReadTreeResponse>;
// (undocumented)
fromTarArchive(
options: ReadTreeResponseFactoryOptions & {
stripFirstDirectory?: boolean;
},
): Promise<ReadTreeResponse>;
// (undocumented)
fromZipArchive(
options: ReadTreeResponseFactoryOptions,
): Promise<ReadTreeResponse>;
}
// Warning: (ae-forgotten-export) The symbol "ReadTreeResponseFactory_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export type ReadTreeResponseFactory = ReadTreeResponseFactory_2;
// @public
export type ReadTreeResponseFactoryOptions = {
stream: Readable;
subpath?: string;
etag: string;
filter?: (
path: string,
info?: {
size: number;
},
) => boolean;
};
// Warning: (ae-forgotten-export) The symbol "ReadTreeResponseFactoryOptions_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export type ReadTreeResponseFactoryOptions = ReadTreeResponseFactoryOptions_2;
export { ReadTreeResponseFile };
// @public @deprecated (undocumented)
export type ReadTreeResponseFile = ReadTreeResponseFile_2;
export { ReadUrlOptions };
// @public @deprecated (undocumented)
export type ReadUrlOptions = ReadUrlOptions_2;
export { ReadUrlResponse };
// @public @deprecated (undocumented)
export type ReadUrlResponse = ReadUrlResponse_2;
// @public
export class ReadUrlResponseFactory {
static fromNodeJSReadable(
oldStyleStream: NodeJS.ReadableStream,
options?: ReadUrlResponseFactoryFromStreamOptions,
): Promise<ReadUrlResponse>;
static fromReadable(
stream: Readable,
options?: ReadUrlResponseFactoryFromStreamOptions,
): Promise<ReadUrlResponse>;
}
// Warning: (ae-forgotten-export) The symbol "ReadUrlResponseFactory_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const ReadUrlResponseFactory: typeof ReadUrlResponseFactory_2;
// @public
export type ReadUrlResponseFactoryFromStreamOptions = {
etag?: string;
lastModifiedAt?: Date;
};
// Warning: (ae-forgotten-export) The symbol "ReadUrlResponseFactoryFromStreamOptions_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export type ReadUrlResponseFactoryFromStreamOptions =
ReadUrlResponseFactoryFromStreamOptions_2;
// @public
export function redactWinstonLogLine(
@@ -778,11 +573,14 @@ export type RunContainerOptions = {
pullOptions?: PullOptions;
};
export { SearchOptions };
// @public @deprecated (undocumented)
export type SearchOptions = SearchOptions_2;
export { SearchResponse };
// @public @deprecated (undocumented)
export type SearchResponse = SearchResponse_2;
export { SearchResponseFile };
// @public @deprecated (undocumented)
export type SearchResponseFile = SearchResponseFile_2;
// @public
export class ServerTokenManager implements TokenManager {
@@ -861,26 +659,23 @@ export interface StatusCheckHandlerOptions {
export { TokenManager };
export { UrlReader };
// @public @deprecated (undocumented)
export type UrlReader = UrlReaderService;
// @public
export type UrlReaderPredicateTuple = {
predicate: (url: URL) => boolean;
reader: UrlReader;
};
// Warning: (ae-forgotten-export) The symbol "UrlReaderPredicateTuple_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export type UrlReaderPredicateTuple = UrlReaderPredicateTuple_2;
// @public
export class UrlReaders {
static create(options: UrlReadersOptions): UrlReader;
static default(options: UrlReadersOptions): UrlReader;
}
// Warning: (ae-forgotten-export) The symbol "UrlReaders_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export const UrlReaders: typeof UrlReaders_2;
// @public
export type UrlReadersOptions = {
config: Config;
logger: LoggerService;
factories?: ReaderFactory[];
};
// Warning: (ae-forgotten-export) The symbol "UrlReadersOptions_2" needs to be exported by the entry point index.d.ts
//
// @public @deprecated (undocumented)
export type UrlReadersOptions = UrlReadersOptions_2;
// @public @deprecated
export function useHotCleanup(
+204 -32
View File
@@ -14,35 +14,207 @@
* limitations under the License.
*/
export { AzureUrlReader } from './AzureUrlReader';
export { BitbucketCloudUrlReader } from './BitbucketCloudUrlReader';
export { BitbucketUrlReader } from './BitbucketUrlReader';
export { BitbucketServerUrlReader } from './BitbucketServerUrlReader';
export { GerritUrlReader } from './GerritUrlReader';
export { GithubUrlReader } from './GithubUrlReader';
export { GitlabUrlReader } from './GitlabUrlReader';
export { GiteaUrlReader } from './GiteaUrlReader';
export { HarnessUrlReader } from './HarnessUrlReader';
export { AwsS3UrlReader } from './AwsS3UrlReader';
export { FetchUrlReader } from './FetchUrlReader';
export { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
export type {
FromReadableArrayOptions,
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadTreeResponseFile,
ReadTreeResponseDirOptions,
ReadTreeResponseFactoryOptions,
ReadUrlOptions,
ReadUrlResponse,
ReadUrlResponseFactoryFromStreamOptions,
SearchOptions,
SearchResponse,
SearchResponseFile,
UrlReader,
UrlReaderPredicateTuple,
} from './types';
export { UrlReaders } from './UrlReaders';
export type { UrlReadersOptions } from './UrlReaders';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { AzureUrlReader as _AzureUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/AzureUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { BitbucketCloudUrlReader as _BitbucketCloudUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketCloudUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { BitbucketUrlReader as _BitbucketUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { BitbucketServerUrlReader as _BitbucketServerUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/BitbucketServerUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { GerritUrlReader as _GerritUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GerritUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { GithubUrlReader as _GithubUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GithubUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { GitlabUrlReader as _GitlabUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GitlabUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { GiteaUrlReader as _GiteaUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/GiteaUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { HarnessUrlReader as _HarnessUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/HarnessUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { AwsS3UrlReader as _AwsS3UrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/AwsS3UrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { FetchUrlReader as _FetchUrlReader } from '../../../backend-defaults/src/entrypoints/urlReader/lib/FetchUrlReader';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { UrlReaders as _UrlReaders } from '../../../backend-defaults/src/entrypoints/urlReader/lib/UrlReaders';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import { ReadUrlResponseFactory as _ReadUrlResponseFactory } from '../../../backend-defaults/src/entrypoints/urlReader/lib/ReadUrlResponseFactory';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import type { UrlReadersOptions as _UrlReadersOptions } from '../../../backend-defaults/src/entrypoints/urlReader/lib/UrlReaders';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import type { FromReadableArrayOptions as _FromReadableArrayOptions } from '../../../backend-defaults/src/entrypoints/urlReader/lib/types';
// eslint-disable-next-line @backstage/no-relative-monorepo-imports
import type {
ReaderFactory as _ReaderFactory,
ReadTreeResponseFactory as _ReadTreeResponseFactory,
ReadTreeResponseFactoryOptions as _ReadTreeResponseFactoryOptions,
ReadUrlResponseFactoryFromStreamOptions as _ReadUrlResponseFactoryFromStreamOptions,
UrlReaderPredicateTuple as _UrlReaderPredicateTuple,
} from '../../../backend-defaults/src/entrypoints/urlReader/lib/types';
import type {
ReadTreeOptions as _ReadTreeOptions,
ReadTreeResponse as _ReadTreeResponse,
ReadTreeResponseFile as _ReadTreeResponseFile,
ReadTreeResponseDirOptions as _ReadTreeResponseDirOptions,
ReadUrlOptions as _ReadUrlOptions,
ReadUrlResponse as _ReadUrlResponse,
SearchOptions as _SearchOptions,
SearchResponse as _SearchResponse,
SearchResponseFile as _SearchResponseFile,
UrlReaderService as _UrlReaderService,
} from '@backstage/backend-plugin-api';
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const AzureUrlReader = _AzureUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const BitbucketCloudUrlReader = _BitbucketCloudUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const BitbucketUrlReader = _BitbucketUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const BitbucketServerUrlReader = _BitbucketServerUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const GerritUrlReader = _GerritUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const GithubUrlReader = _GithubUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const GitlabUrlReader = _GitlabUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const GiteaUrlReader = _GiteaUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const HarnessUrlReader = _HarnessUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const AwsS3UrlReader = _AwsS3UrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const FetchUrlReader = _FetchUrlReader;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const UrlReaders = _UrlReaders;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export const ReadUrlResponseFactory = _ReadUrlResponseFactory;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export type UrlReadersOptions = _UrlReadersOptions;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export type FromReadableArrayOptions = _FromReadableArrayOptions;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export type ReaderFactory = _ReaderFactory;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export type ReadTreeResponseFactory = _ReadTreeResponseFactory;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export type ReadTreeResponseFactoryOptions = _ReadTreeResponseFactoryOptions;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export type ReadUrlResponseFactoryFromStreamOptions =
_ReadUrlResponseFactoryFromStreamOptions;
/**
* @public
* @deprecated Import from `@backstage/backend-defaults/urlReader` instead
*/
export type UrlReaderPredicateTuple = _UrlReaderPredicateTuple;
/**
* @public
* @deprecated Use `ÙrlReaderReadTreeOptions` from `@backstage/backend-plugin-api` instead
*/
export type ReadTreeOptions = _ReadTreeOptions;
/**
* @public
* @deprecated Use `ÙrlReaderReadTreeResponse` from `@backstage/backend-plugin-api` instead
*/
export type ReadTreeResponse = _ReadTreeResponse;
/**
* @public
* @deprecated Use `ÙrlReaderReadTreeResponseFile` from `@backstage/backend-plugin-api` instead
*/
export type ReadTreeResponseFile = _ReadTreeResponseFile;
/**
* @public
* @deprecated Use `ÙrlReaderReadTreeResponseDirOptions` from `@backstage/backend-plugin-api` instead
*/
export type ReadTreeResponseDirOptions = _ReadTreeResponseDirOptions;
/**
* @public
* @deprecated Use `ÙrlReaderReadUrlOptions` from `@backstage/backend-plugin-api` instead
*/
export type ReadUrlOptions = _ReadUrlOptions;
/**
* @public
* @deprecated Use `ÙrlReaderReadUrlResponse` from `@backstage/backend-plugin-api` instead
*/
export type ReadUrlResponse = _ReadUrlResponse;
/**
* @public
* @deprecated Use `ÙrlReaderSearchOptions` from `@backstage/backend-plugin-api` instead
*/
export type SearchOptions = _SearchOptions;
/**
* @public
* @deprecated Use `ÙrlReaderSearchResponse` from `@backstage/backend-plugin-api` instead
*/
export type SearchResponse = _SearchResponse;
/**
* @public
* @deprecated Use `ÙrlReaderSearchResponseFile` from `@backstage/backend-plugin-api` instead
*/
export type SearchResponseFile = _SearchResponseFile;
/**
* @public
* @deprecated Use `ÙrlReaderService` from `@backstage/backend-plugin-api` instead
*/
export type UrlReader = _UrlReaderService;
@@ -3,11 +3,441 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
/// <reference types="node" />
import { AwsCredentialsManager } from '@backstage/integration-aws-node';
import { AwsS3Integration } from '@backstage/integration';
import { AzureDevOpsCredentialsProvider } from '@backstage/integration';
import { AzureIntegration } from '@backstage/integration';
import { BitbucketCloudIntegration } from '@backstage/integration';
import { BitbucketIntegration } from '@backstage/integration';
import { BitbucketServerIntegration } from '@backstage/integration';
import { Config } from '@backstage/config';
import { GerritIntegration } from '@backstage/integration';
import { GiteaIntegration } from '@backstage/integration';
import { GithubCredentialsProvider } from '@backstage/integration';
import { GithubIntegration } from '@backstage/integration';
import { GitLabIntegration } from '@backstage/integration';
import { HarnessIntegration } from '@backstage/integration';
import { LoggerService } from '@backstage/backend-plugin-api';
import { Readable } from 'stream';
import { ServiceFactory } from '@backstage/backend-plugin-api';
import { UrlReader } from '@backstage/backend-common';
import { UrlReaderReadTreeOptions } from '@backstage/backend-plugin-api';
import { UrlReaderReadTreeResponse } from '@backstage/backend-plugin-api';
import { UrlReaderReadUrlOptions } from '@backstage/backend-plugin-api';
import { UrlReaderReadUrlResponse } from '@backstage/backend-plugin-api';
import { UrlReaderSearchOptions } from '@backstage/backend-plugin-api';
import { UrlReaderSearchResponse } from '@backstage/backend-plugin-api';
import { UrlReaderService } from '@backstage/backend-plugin-api';
// @public
export class AwsS3UrlReader implements UrlReaderService {
constructor(
credsManager: AwsCredentialsManager,
integration: AwsS3Integration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class AzureUrlReader implements UrlReaderService {
constructor(
integration: AzureIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
credentialsProvider: AzureDevOpsCredentialsProvider;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class BitbucketCloudUrlReader implements UrlReaderService {
constructor(
integration: BitbucketCloudIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class BitbucketServerUrlReader implements UrlReaderService {
constructor(
integration: BitbucketServerIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public @deprecated
export class BitbucketUrlReader implements UrlReaderService {
constructor(
integration: BitbucketIntegration,
logger: LoggerService,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class FetchUrlReader implements UrlReaderService {
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export type FromReadableArrayOptions = Array<{
data: Readable;
path: string;
lastModifiedAt?: Date;
}>;
// @public
export class GerritUrlReader implements UrlReaderService {
constructor(
integration: GerritIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
workDir: string,
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class GiteaUrlReader implements UrlReaderService {
constructor(
integration: GiteaIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class GithubUrlReader implements UrlReaderService {
constructor(
integration: GithubIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
credentialsProvider: GithubCredentialsProvider;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class GitlabUrlReader implements UrlReaderService {
constructor(
integration: GitLabIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export class HarnessUrlReader implements UrlReaderService {
constructor(
integration: HarnessIntegration,
deps: {
treeResponseFactory: ReadTreeResponseFactory;
},
);
// (undocumented)
static factory: ReaderFactory;
// (undocumented)
read(url: string): Promise<Buffer>;
// (undocumented)
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
// (undocumented)
search(): Promise<UrlReaderSearchResponse>;
// (undocumented)
toString(): string;
}
// @public
export type ReaderFactory = (options: {
config: Config;
logger: LoggerService;
treeResponseFactory: ReadTreeResponseFactory;
}) => UrlReaderPredicateTuple[];
// @public
export interface ReadTreeResponseFactory {
// (undocumented)
fromReadableArray(
options: FromReadableArrayOptions,
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
fromTarArchive(
options: ReadTreeResponseFactoryOptions & {
stripFirstDirectory?: boolean;
},
): Promise<UrlReaderReadTreeResponse>;
// (undocumented)
fromZipArchive(
options: ReadTreeResponseFactoryOptions,
): Promise<UrlReaderReadTreeResponse>;
}
// @public
export type ReadTreeResponseFactoryOptions = {
stream: Readable;
subpath?: string;
etag: string;
filter?: (
path: string,
info?: {
size: number;
},
) => boolean;
};
// @public
export class ReadUrlResponseFactory {
static fromNodeJSReadable(
oldStyleStream: NodeJS.ReadableStream,
options?: ReadUrlResponseFactoryFromStreamOptions,
): Promise<UrlReaderReadUrlResponse>;
static fromReadable(
stream: Readable,
options?: ReadUrlResponseFactoryFromStreamOptions,
): Promise<UrlReaderReadUrlResponse>;
}
// @public
export type ReadUrlResponseFactoryFromStreamOptions = {
etag?: string;
lastModifiedAt?: Date;
};
// @public
export type UrlReaderPredicateTuple = {
predicate: (url: URL) => boolean;
reader: UrlReaderService;
};
// @public
export class UrlReaders {
static create(options: UrlReadersOptions): UrlReaderService;
static default(options: UrlReadersOptions): UrlReaderService;
}
// @public (undocumented)
export const urlReaderServiceFactory: () => ServiceFactory<UrlReader, 'plugin'>;
export const urlReaderServiceFactory: () => ServiceFactory<
UrlReaderService,
'plugin'
>;
// @public
export type UrlReadersOptions = {
config: Config;
logger: LoggerService;
factories?: ReaderFactory[];
};
// (No @packageDocumentation comment for this package)
```
+22
View File
@@ -82,6 +82,11 @@
"test": "backstage-cli package test"
},
"dependencies": {
"@aws-sdk/abort-controller": "^3.347.0",
"@aws-sdk/client-codecommit": "^3.350.0",
"@aws-sdk/client-s3": "^3.350.0",
"@aws-sdk/credential-providers": "^3.350.0",
"@aws-sdk/types": "^3.347.0",
"@backstage/backend-app-api": "workspace:^",
"@backstage/backend-common": "workspace:^",
"@backstage/backend-dev-utils": "workspace:^",
@@ -89,31 +94,48 @@
"@backstage/config": "workspace:^",
"@backstage/config-loader": "workspace:^",
"@backstage/errors": "workspace:^",
"@backstage/integration": "workspace:^",
"@backstage/integration-aws-node": "workspace:^",
"@backstage/plugin-events-node": "workspace:^",
"@backstage/plugin-permission-node": "workspace:^",
"@backstage/types": "workspace:^",
"@google-cloud/storage": "^7.0.0",
"@keyv/memcache": "^1.3.5",
"@keyv/redis": "^2.5.3",
"@octokit/rest": "^19.0.3",
"@opentelemetry/api": "^1.3.0",
"archiver": "^6.0.0",
"base64-stream": "^1.0.0",
"better-sqlite3": "^9.0.0",
"concat-stream": "^2.0.0",
"cron": "^3.0.0",
"fs-extra": "^11.2.0",
"git-url-parse": "^14.0.0",
"isomorphic-git": "^1.23.0",
"keyv": "^4.5.2",
"knex": "^3.0.0",
"lodash": "^4.17.21",
"luxon": "^3.0.0",
"minimatch": "^9.0.0",
"mysql2": "^3.0.0",
"node-fetch": "^2.6.7",
"p-limit": "^3.1.0",
"pg": "^8.11.3",
"pg-connection-string": "^2.3.0",
"raw-body": "^2.4.1",
"tar": "^6.1.12",
"uuid": "^9.0.0",
"yauzl": "^3.0.0",
"yn": "^4.0.0",
"zod": "^3.22.4"
},
"devDependencies": {
"@aws-sdk/util-stream-node": "^3.350.0",
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"aws-sdk-client-mock": "^4.0.0",
"msw": "^1.0.0",
"wait-for-expect": "^3.0.2"
},
"configSchema": "config.d.ts"
@@ -14,4 +14,5 @@
* limitations under the License.
*/
export * from './lib';
export { urlReaderServiceFactory } from './urlReaderServiceFactory';
@@ -14,16 +14,15 @@
* limitations under the License.
*/
import { ReaderFactory, ReadTreeResponseFactory } from './types';
import {
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
SearchResponse,
UrlReader,
} from './types';
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import {
AwsCredentialsManager,
DefaultAwsCredentialsManager,
@@ -118,7 +117,7 @@ export function parseUrl(
*
* @public
*/
export class AwsCodeCommitUrlReader implements UrlReader {
export class AwsCodeCommitUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
const credsManager = DefaultAwsCredentialsManager.fromConfig(config);
@@ -222,8 +221,8 @@ export class AwsCodeCommitUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
// etag and lastModifiedAfter are not supported by the CodeCommit API
try {
const { path, repositoryName, region, commitSpecifier } = parseUrl(
@@ -326,8 +325,8 @@ export class AwsCodeCommitUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
// url: https://eu-west-1.console.aws.amazon.com/codesuite/codecommit/repositories/test-stijn-delete-techdocs/browse?region=eu-west-1
try {
const { path, repositoryName, region, commitSpecifier } = parseUrl(url);
@@ -380,7 +379,7 @@ export class AwsCodeCommitUrlReader implements UrlReader {
}
}
async search(): Promise<SearchResponse> {
async search(): Promise<UrlReaderSearchResponse> {
throw new Error('AwsCodeCommitReader does not implement search');
}
@@ -15,15 +15,14 @@
*/
import {
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
SearchResponse,
UrlReader,
} from './types';
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import { ReaderFactory, ReadTreeResponseFactory } from './types';
import {
AwsCredentialsManager,
DefaultAwsCredentialsManager,
@@ -132,7 +131,7 @@ export function parseUrl(
*
* @public
*/
export class AwsS3UrlReader implements UrlReader {
export class AwsS3UrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
const credsManager = DefaultAwsCredentialsManager.fromConfig(config);
@@ -253,8 +252,8 @@ export class AwsS3UrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const { etag, lastModifiedAfter } = options ?? {};
try {
@@ -300,8 +299,8 @@ export class AwsS3UrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
try {
const { path, bucket, region } = parseUrl(url, this.integration.config);
const s3Client = await this.buildS3Client(
@@ -357,7 +356,7 @@ export class AwsS3UrlReader implements UrlReader {
}
}
async search(): Promise<SearchResponse> {
async search(): Promise<UrlReaderSearchResponse> {
throw new Error('AwsS3Reader does not implement search');
}
@@ -14,6 +14,15 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import {
getAzureCommitsUrl,
getAzureDownloadUrl,
@@ -27,17 +36,7 @@ import fetch, { Response } from 'node-fetch';
import { Minimatch } from 'minimatch';
import { Readable } from 'stream';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
ReadTreeResponseFactory,
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
SearchOptions,
SearchResponse,
UrlReader,
ReadUrlOptions,
ReadUrlResponse,
} from './types';
import { ReadTreeResponseFactory, ReaderFactory } from './types';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
/**
@@ -45,7 +44,7 @@ import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
*
* @public
*/
export class AzureUrlReader implements UrlReader {
export class AzureUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
const credentialProvider =
@@ -75,8 +74,8 @@ export class AzureUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
// TODO: etag is not implemented yet.
const { signal } = options ?? {};
@@ -114,8 +113,8 @@ export class AzureUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const { etag, filter, signal } = options ?? {};
// TODO: Support filepath based reading tree feature like other providers
@@ -180,7 +179,10 @@ export class AzureUrlReader implements UrlReader {
});
}
async search(url: string, options?: SearchOptions): Promise<SearchResponse> {
async search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse> {
const treeUrl = new URL(url);
const path = treeUrl.searchParams.get('path');
@@ -14,6 +14,15 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
BitbucketCloudIntegration,
@@ -28,17 +37,7 @@ import parseGitUrl from 'git-url-parse';
import { trimEnd } from 'lodash';
import { Minimatch } from 'minimatch';
import { Readable } from 'stream';
import {
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
SearchOptions,
SearchResponse,
UrlReader,
} from './types';
import { ReaderFactory, ReadTreeResponseFactory } from './types';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import { parseLastModified } from './util';
@@ -47,7 +46,7 @@ import { parseLastModified } from './util';
*
* @public
*/
export class BitbucketCloudUrlReader implements UrlReader {
export class BitbucketCloudUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
return integrations.bitbucketCloud.list().map(integration => {
@@ -79,8 +78,8 @@ export class BitbucketCloudUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const { etag, lastModifiedAfter, signal } = options ?? {};
const bitbucketUrl = getBitbucketCloudFileFetchUrl(
url,
@@ -134,8 +133,8 @@ export class BitbucketCloudUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const { filepath } = parseGitUrl(url);
const lastCommitShortHash = await this.getLastCommitShortHash(url);
@@ -167,7 +166,10 @@ export class BitbucketCloudUrlReader implements UrlReader {
});
}
async search(url: string, options?: SearchOptions): Promise<SearchResponse> {
async search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse> {
const { filepath } = parseGitUrl(url);
const matcher = new Minimatch(filepath);
@@ -14,6 +14,15 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
BitbucketServerIntegration,
@@ -27,17 +36,7 @@ import parseGitUrl from 'git-url-parse';
import { trimEnd } from 'lodash';
import { Minimatch } from 'minimatch';
import { Readable } from 'stream';
import {
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
SearchOptions,
SearchResponse,
UrlReader,
} from './types';
import { ReaderFactory, ReadTreeResponseFactory } from './types';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import { parseLastModified } from './util';
@@ -46,7 +45,7 @@ import { parseLastModified } from './util';
*
* @public
*/
export class BitbucketServerUrlReader implements UrlReader {
export class BitbucketServerUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
return integrations.bitbucketServer.list().map(integration => {
@@ -70,8 +69,8 @@ export class BitbucketServerUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const { etag, lastModifiedAfter, signal } = options ?? {};
const bitbucketUrl = getBitbucketServerFileFetchUrl(
url,
@@ -125,8 +124,8 @@ export class BitbucketServerUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const { filepath } = parseGitUrl(url);
const lastCommitShortHash = await this.getLastCommitShortHash(url);
@@ -158,7 +157,10 @@ export class BitbucketServerUrlReader implements UrlReader {
});
}
async search(url: string, options?: SearchOptions): Promise<SearchResponse> {
async search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse> {
const { filepath } = parseGitUrl(url);
const matcher = new Minimatch(filepath);
@@ -14,6 +14,15 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
BitbucketIntegration,
@@ -29,17 +38,7 @@ import { trimEnd } from 'lodash';
import { Minimatch } from 'minimatch';
import { Readable } from 'stream';
import { LoggerService } from '@backstage/backend-plugin-api';
import {
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
SearchOptions,
SearchResponse,
UrlReader,
} from './types';
import { ReaderFactory, ReadTreeResponseFactory } from './types';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import { parseLastModified } from './util';
@@ -50,7 +49,7 @@ import { parseLastModified } from './util';
* @public
* @deprecated in favor of BitbucketCloudUrlReader and BitbucketServerUrlReader
*/
export class BitbucketUrlReader implements UrlReader {
export class BitbucketUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, logger, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
return integrations.bitbucket
@@ -95,8 +94,8 @@ export class BitbucketUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const { etag, lastModifiedAfter, signal } = options ?? {};
const bitbucketUrl = getBitbucketFileFetchUrl(url, this.integration.config);
const requestOptions = getBitbucketRequestOptions(this.integration.config);
@@ -145,8 +144,8 @@ export class BitbucketUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const { filepath } = parseGitUrl(url);
const lastCommitShortHash = await this.getLastCommitShortHash(url);
@@ -178,7 +177,10 @@ export class BitbucketUrlReader implements UrlReader {
});
}
async search(url: string, options?: SearchOptions): Promise<SearchResponse> {
async search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse> {
const { filepath } = parseGitUrl(url);
const matcher = new Minimatch(filepath);
@@ -14,16 +14,16 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import fetch, { Response } from 'node-fetch';
import {
ReaderFactory,
ReadTreeResponse,
ReadUrlOptions,
ReadUrlResponse,
SearchResponse,
UrlReader,
} from './types';
import { ReaderFactory } from './types';
import path from 'path';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import { parseLastModified } from './util';
@@ -68,7 +68,7 @@ const parsePortPredicate = (port: string | undefined) => {
*
* @public
*/
export class FetchUrlReader implements UrlReader {
export class FetchUrlReader implements UrlReaderService {
/**
* The factory creates a single reader that will be used for reading any URL that's listed
* in configuration at `backend.reading.allow`. The allow list contains a list of objects describing
@@ -121,8 +121,8 @@ export class FetchUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
let response: Response;
try {
response = await fetch(url, {
@@ -165,11 +165,11 @@ export class FetchUrlReader implements UrlReader {
throw new Error(message);
}
async readTree(): Promise<ReadTreeResponse> {
async readTree(): Promise<UrlReaderReadTreeResponse> {
throw new Error('FetchUrlReader does not implement readTree');
}
async search(): Promise<SearchResponse> {
async search(): Promise<UrlReaderSearchResponse> {
throw new Error('FetchUrlReader does not implement search');
}
@@ -14,6 +14,14 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import { Base64Decode } from 'base64-stream';
import concatStream from 'concat-stream';
import fs from 'fs-extra';
@@ -35,16 +43,7 @@ import {
parseGerritJsonResponse,
} from '@backstage/integration';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
ReaderFactory,
SearchResponse,
UrlReader,
} from './types';
import { ReadTreeResponseFactory, ReaderFactory } from './types';
import { Git } from './git';
const pipeline = promisify(pipelineCb);
@@ -78,7 +77,7 @@ const createTemporaryDirectory = async (workDir: string): Promise<string> =>
*
* @public
*/
export class GerritUrlReader implements UrlReader {
export class GerritUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
if (!integrations.gerrit) {
@@ -121,8 +120,8 @@ export class GerritUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const apiUrl = getGerritFileContentsApiUrl(this.integration.config, url);
let response: Response;
try {
@@ -166,8 +165,8 @@ export class GerritUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const apiUrl = getGerritBranchApiUrl(this.integration.config, url);
let response: Response;
try {
@@ -203,7 +202,7 @@ export class GerritUrlReader implements UrlReader {
return this.readTreeFromGitClone(url, branchInfo.revision, options);
}
async search(): Promise<SearchResponse> {
async search(): Promise<UrlReaderSearchResponse> {
throw new Error('GerritReader does not implement search');
}
@@ -215,7 +214,7 @@ export class GerritUrlReader implements UrlReader {
private async readTreeFromGitClone(
url: string,
revision: string,
options?: ReadTreeOptions,
options?: UrlReaderReadTreeOptions,
) {
const { filePath } = parseGerritGitilesUrl(this.integration.config, url);
@@ -258,7 +257,7 @@ export class GerritUrlReader implements UrlReader {
private async readTreeFromGitiles(
url: string,
revision: string,
options?: ReadTreeOptions,
options?: UrlReaderReadTreeOptions,
) {
const { branch, filePath, project } = parseGerritGitilesUrl(
this.integration.config,
@@ -13,6 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import {
getGiteaFileContentsUrl,
getGiteaArchiveUrl,
@@ -22,16 +31,7 @@ import {
GiteaIntegration,
ScmIntegrations,
} from '@backstage/integration';
import {
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
SearchResponse,
UrlReader,
} from './types';
import { ReaderFactory, ReadTreeResponseFactory } from './types';
import fetch, { Response } from 'node-fetch';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import {
@@ -47,7 +47,7 @@ import { parseLastModified } from './util';
*
* @public
*/
export class GiteaUrlReader implements UrlReader {
export class GiteaUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
return ScmIntegrations.fromConfig(config)
.gitea.list()
@@ -74,8 +74,8 @@ export class GiteaUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
let response: Response;
const blobUrl = getGiteaFileContentsUrl(this.integration.config, url);
@@ -126,8 +126,8 @@ export class GiteaUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const lastCommitHash = await this.getLastCommitHash(url);
if (options?.etag && options.etag === lastCommitHash) {
throw new NotModifiedError();
@@ -156,7 +156,7 @@ export class GiteaUrlReader implements UrlReader {
});
}
search(): Promise<SearchResponse> {
search(): Promise<UrlReaderSearchResponse> {
throw new Error('GiteaUrlReader search not implemented.');
}
@@ -14,6 +14,16 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
UrlReaderSearchResponseFile,
} from '@backstage/backend-plugin-api';
import {
getGithubFileFetchUrl,
DefaultGithubCredentialsProvider,
@@ -28,18 +38,7 @@ import parseGitUrl from 'git-url-parse';
import { Minimatch } from 'minimatch';
import { Readable } from 'stream';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
ReadTreeResponseFactory,
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
SearchOptions,
SearchResponse,
SearchResponseFile,
UrlReader,
ReadUrlOptions,
ReadUrlResponse,
} from './types';
import { ReadTreeResponseFactory, ReaderFactory } from './types';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import { parseLastModified } from './util';
@@ -58,7 +57,7 @@ export type GhBlobResponse =
*
* @public
*/
export class GithubUrlReader implements UrlReader {
export class GithubUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
const credentialsProvider =
@@ -113,8 +112,8 @@ export class GithubUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const credentials = await this.getCredentials(url, options);
const ghUrl = getGithubFileFetchUrl(
@@ -149,8 +148,8 @@ export class GithubUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const repoDetails = await this.getRepoDetails(url);
const commitSha = repoDetails.commitSha;
@@ -176,7 +175,10 @@ export class GithubUrlReader implements UrlReader {
);
}
async search(url: string, options?: SearchOptions): Promise<SearchResponse> {
async search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse> {
const repoDetails = await this.getRepoDetails(url);
const commitSha = repoDetails.commitSha;
@@ -209,8 +211,8 @@ export class GithubUrlReader implements UrlReader {
sha: string,
subpath: string,
init: RequestInit,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
// archive_url looks like "https://api.github.com/repos/owner/repo/{archive_format}{/ref}"
const archive = await this.fetchResponse(
archiveUrl
@@ -236,7 +238,7 @@ export class GithubUrlReader implements UrlReader {
sha: string,
query: string,
init: RequestInit,
): Promise<SearchResponseFile[]> {
): Promise<UrlReaderSearchResponseFile[]> {
function pathToUrl(path: string): string {
// TODO(freben): Use the integration package facility for this instead
// pathname starts as /backstage/backstage/blob/master/<path>
@@ -14,6 +14,15 @@
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import {
getGitLabFileFetchUrl,
getGitLabIntegrationRelativePath,
@@ -26,17 +35,7 @@ import parseGitUrl from 'git-url-parse';
import { Minimatch } from 'minimatch';
import { Readable } from 'stream';
import { NotFoundError, NotModifiedError } from '@backstage/errors';
import {
ReadTreeResponseFactory,
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
SearchOptions,
SearchResponse,
UrlReader,
ReadUrlResponse,
ReadUrlOptions,
} from './types';
import { ReadTreeResponseFactory, ReaderFactory } from './types';
import { trimEnd, trimStart } from 'lodash';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import { parseLastModified } from './util';
@@ -46,7 +45,7 @@ import { parseLastModified } from './util';
*
* @public
*/
export class GitlabUrlReader implements UrlReader {
export class GitlabUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
const integrations = ScmIntegrations.fromConfig(config);
return integrations.gitlab.list().map(integration => {
@@ -70,8 +69,8 @@ export class GitlabUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const { etag, lastModifiedAfter, signal } = options ?? {};
const builtUrl = await this.getGitlabFetchUrl(url);
@@ -119,8 +118,8 @@ export class GitlabUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const { etag, signal } = options ?? {};
const { ref, full_name, filepath } = parseGitUrl(url);
@@ -236,7 +235,10 @@ export class GitlabUrlReader implements UrlReader {
});
}
async search(url: string, options?: SearchOptions): Promise<SearchResponse> {
async search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse> {
const { filepath } = parseGitUrl(url);
const staticPart = this.getStaticPart(filepath);
const matcher = new Minimatch(filepath);
@@ -19,7 +19,7 @@ import { JsonObject } from '@backstage/types';
import { DefaultReadTreeResponseFactory } from './tree';
import { GoogleGcsUrlReader } from './GoogleGcsUrlReader';
import { UrlReaderPredicateTuple } from './types';
import packageinfo from '../../package.json';
import packageinfo from '@backstage/backend-defaults/package.json';
import { mockServices } from '@backstage/backend-test-utils';
const bucketGetFilesMock = jest.fn();
@@ -80,7 +80,7 @@ describe('GcsUrlReader', () => {
});
it('check if userAgent has been called with this key value', async () => {
const getStorage: any = {
userAgent: `backstage/backend-common.GoogleGcsUrlReader/${packageinfo.version}`,
userAgent: `backstage/backend-defaults.GoogleGcsUrlReader/${packageinfo.version}`,
};
jest.mock('@google-cloud/storage', () => {
return {
@@ -89,7 +89,7 @@ describe('GcsUrlReader', () => {
});
const getUserAgent = getStorage.userAgent.toString();
expect(getUserAgent).toBe(
`backstage/backend-common.GoogleGcsUrlReader/${packageinfo.version}`,
`backstage/backend-defaults.GoogleGcsUrlReader/${packageinfo.version}`,
);
});
@@ -14,15 +14,15 @@
* limitations under the License.
*/
import { Storage } from '@google-cloud/storage';
import {
ReaderFactory,
ReadTreeResponse,
ReadUrlOptions,
ReadUrlResponse,
SearchResponse,
UrlReader,
} from './types';
UrlReaderService,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchResponse,
} from '@backstage/backend-plugin-api';
import { Storage } from '@google-cloud/storage';
import { ReaderFactory } from './types';
import getRawBody from 'raw-body';
import {
GoogleGcsIntegrationConfig,
@@ -30,7 +30,7 @@ import {
} from '@backstage/integration';
import { Readable } from 'stream';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import packageinfo from '../../package.json';
import packageinfo from '@backstage/backend-defaults/package.json';
const GOOGLE_GCS_HOST = 'storage.cloud.google.com';
@@ -56,7 +56,7 @@ const parseURL = (
*
* @public
*/
export class GoogleGcsUrlReader implements UrlReader {
export class GoogleGcsUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, logger }) => {
if (!config.has('integrations.googleGcs')) {
return [];
@@ -70,7 +70,7 @@ export class GoogleGcsUrlReader implements UrlReader {
'googleGcs credentials not found in config. Using default credentials provider.',
);
storage = new Storage({
userAgent: `backstage/backend-common.GoogleGcsUrlReader/${packageinfo.version}`,
userAgent: `backstage/backend-defaults.GoogleGcsUrlReader/${packageinfo.version}`,
});
} else {
storage = new Storage({
@@ -78,7 +78,7 @@ export class GoogleGcsUrlReader implements UrlReader {
client_email: gcsConfig.clientEmail || undefined,
private_key: gcsConfig.privateKey || undefined,
},
userAgent: `backstage/backend-common.GoogleGcsUrlReader/${packageinfo.version}`,
userAgent: `backstage/backend-defaults.GoogleGcsUrlReader/${packageinfo.version}`,
});
}
const reader = new GoogleGcsUrlReader(gcsConfig, storage);
@@ -106,18 +106,18 @@ export class GoogleGcsUrlReader implements UrlReader {
async readUrl(
url: string,
_options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
_options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
// TODO etag is not implemented yet.
const stream = this.readStreamFromUrl(url);
return ReadUrlResponseFactory.fromReadable(stream);
}
async readTree(): Promise<ReadTreeResponse> {
async readTree(): Promise<UrlReaderReadTreeResponse> {
throw new Error('GcsUrlReader does not implement readTree');
}
async search(url: string): Promise<SearchResponse> {
async search(url: string): Promise<UrlReaderSearchResponse> {
const { bucket, key: pattern } = parseURL(url);
if (!pattern.endsWith('*') || pattern.indexOf('*') !== pattern.length - 1) {
@@ -13,6 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
UrlReaderService,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchResponse,
UrlReaderReadTreeOptions,
} from '@backstage/backend-plugin-api';
import {
getHarnessRequestOptions,
getHarnessFileContentsUrl,
@@ -22,16 +31,7 @@ import {
getHarnessArchiveUrl,
parseHarnessUrl,
} from '@backstage/integration';
import {
ReaderFactory,
ReadTreeOptions,
ReadTreeResponse,
SearchResponse,
ReadTreeResponseFactory,
ReadUrlOptions,
ReadUrlResponse,
UrlReader,
} from './types';
import { ReadTreeResponseFactory, ReaderFactory } from './types';
import fetch, { Response } from 'node-fetch';
import { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
import {
@@ -47,7 +47,7 @@ import { Readable } from 'stream';
*
* @public
*/
export class HarnessUrlReader implements UrlReader {
export class HarnessUrlReader implements UrlReaderService {
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
return ScmIntegrations.fromConfig(config)
.harness.list()
@@ -75,8 +75,8 @@ export class HarnessUrlReader implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
let response: Response;
const blobUrl = getHarnessFileContentsUrl(this.integration.config, url);
@@ -123,8 +123,8 @@ export class HarnessUrlReader implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const lastCommitHash = await this.getLastCommitHash(url);
if (options?.etag && options.etag === lastCommitHash) {
@@ -153,7 +153,8 @@ export class HarnessUrlReader implements UrlReader {
filter: options?.filter,
});
}
search(): Promise<SearchResponse> {
search(): Promise<UrlReaderSearchResponse> {
throw new Error('HarnessUrlReader search not implemented.');
}
@@ -15,12 +15,10 @@
*/
import { ConflictError } from '@backstage/errors';
import { UrlReaderReadUrlResponse } from '@backstage/backend-plugin-api';
import getRawBody from 'raw-body';
import { Readable } from 'stream';
import {
ReadUrlResponse,
ReadUrlResponseFactoryFromStreamOptions,
} from './types';
import { ReadUrlResponseFactoryFromStreamOptions } from './types';
/**
* Utility class for UrlReader implementations to create valid ReadUrlResponse
@@ -35,7 +33,7 @@ export class ReadUrlResponseFactory {
static async fromReadable(
stream: Readable,
options?: ReadUrlResponseFactoryFromStreamOptions,
): Promise<ReadUrlResponse> {
): Promise<UrlReaderReadUrlResponse> {
// Reference to eventual buffer enables callers to call buffer() multiple
// times without consequence.
let buffer: Promise<Buffer>;
@@ -71,7 +69,7 @@ export class ReadUrlResponseFactory {
static async fromNodeJSReadable(
oldStyleStream: NodeJS.ReadableStream,
options?: ReadUrlResponseFactoryFromStreamOptions,
): Promise<ReadUrlResponse> {
): Promise<UrlReaderReadUrlResponse> {
const readable = Readable.from(oldStyleStream);
return ReadUrlResponseFactory.fromReadable(readable, options);
}
@@ -14,17 +14,17 @@
* limitations under the License.
*/
import { NotAllowedError } from '@backstage/errors';
import {
ReadTreeOptions,
ReadTreeResponse,
ReadUrlOptions,
ReadUrlResponse,
SearchOptions,
SearchResponse,
UrlReader,
UrlReaderPredicateTuple,
} from './types';
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadUrlOptions,
UrlReaderReadUrlResponse,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
UrlReaderService,
} from '@backstage/backend-plugin-api';
import { NotAllowedError } from '@backstage/errors';
import { UrlReaderPredicateTuple } from './types';
function notAllowedMessage(url: string) {
return (
@@ -35,10 +35,10 @@ function notAllowedMessage(url: string) {
}
/**
* A UrlReader implementation that selects from a set of UrlReaders
* A UrlReaderService implementation that selects from a set of readers
* based on a predicate tied to each reader.
*/
export class UrlReaderPredicateMux implements UrlReader {
export class UrlReaderPredicateMux implements UrlReaderService {
private readonly readers: UrlReaderPredicateTuple[] = [];
register(tuple: UrlReaderPredicateTuple): void {
@@ -47,8 +47,8 @@ export class UrlReaderPredicateMux implements UrlReader {
async readUrl(
url: string,
options?: ReadUrlOptions,
): Promise<ReadUrlResponse> {
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse> {
const parsed = new URL(url);
for (const { predicate, reader } of this.readers) {
@@ -62,8 +62,8 @@ export class UrlReaderPredicateMux implements UrlReader {
async readTree(
url: string,
options?: ReadTreeOptions,
): Promise<ReadTreeResponse> {
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse> {
const parsed = new URL(url);
for (const { predicate, reader } of this.readers) {
@@ -75,7 +75,10 @@ export class UrlReaderPredicateMux implements UrlReader {
throw new NotAllowedError(notAllowedMessage(url));
}
async search(url: string, options?: SearchOptions): Promise<SearchResponse> {
async search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse> {
const parsed = new URL(url);
for (const { predicate, reader } of this.readers) {
@@ -14,9 +14,9 @@
* limitations under the License.
*/
import { LoggerService } from '@backstage/backend-plugin-api';
import { LoggerService, UrlReaderService } from '@backstage/backend-plugin-api';
import { Config } from '@backstage/config';
import { ReaderFactory, UrlReader } from './types';
import { ReaderFactory } from './types';
import { UrlReaderPredicateMux } from './UrlReaderPredicateMux';
import { AzureUrlReader } from './AzureUrlReader';
import { BitbucketCloudUrlReader } from './BitbucketCloudUrlReader';
@@ -56,7 +56,7 @@ export class UrlReaders {
/**
* Creates a custom {@link @backstage/backend-plugin-api#UrlReaderService} wrapper for your own set of factories.
*/
static create(options: UrlReadersOptions): UrlReader {
static create(options: UrlReadersOptions): UrlReaderService {
const { logger, config, factories } = options;
const mux = new UrlReaderPredicateMux();
const treeResponseFactory = DefaultReadTreeResponseFactory.create({
@@ -0,0 +1,38 @@
/*
* Copyright 2020 The Backstage Authors
*
* 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 { AzureUrlReader } from './AzureUrlReader';
export { BitbucketCloudUrlReader } from './BitbucketCloudUrlReader';
export { BitbucketUrlReader } from './BitbucketUrlReader';
export { BitbucketServerUrlReader } from './BitbucketServerUrlReader';
export { GerritUrlReader } from './GerritUrlReader';
export { GithubUrlReader } from './GithubUrlReader';
export { GitlabUrlReader } from './GitlabUrlReader';
export { GiteaUrlReader } from './GiteaUrlReader';
export { HarnessUrlReader } from './HarnessUrlReader';
export { AwsS3UrlReader } from './AwsS3UrlReader';
export { FetchUrlReader } from './FetchUrlReader';
export { ReadUrlResponseFactory } from './ReadUrlResponseFactory';
export type {
FromReadableArrayOptions,
ReaderFactory,
ReadTreeResponseFactory,
ReadTreeResponseFactoryOptions,
ReadUrlResponseFactoryFromStreamOptions,
UrlReaderPredicateTuple,
} from './types';
export { UrlReaders } from './UrlReaders';
export type { UrlReadersOptions } from './UrlReaders';
@@ -17,7 +17,6 @@
import os from 'os';
import { Config } from '@backstage/config';
import {
ReadTreeResponse,
ReadTreeResponseFactoryOptions,
ReadTreeResponseFactory,
FromReadableArrayOptions,
@@ -25,6 +24,7 @@ import {
import { TarArchiveResponse } from './TarArchiveResponse';
import { ZipArchiveResponse } from './ZipArchiveResponse';
import { ReadableArrayResponse } from './ReadableArrayResponse';
import { UrlReaderReadTreeResponse } from '@backstage/backend-plugin-api';
export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory {
static create(options: { config: Config }): DefaultReadTreeResponseFactory {
@@ -40,7 +40,7 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory {
options: ReadTreeResponseFactoryOptions & {
stripFirstDirectory?: boolean;
},
): Promise<ReadTreeResponse> {
): Promise<UrlReaderReadTreeResponse> {
return new TarArchiveResponse(
options.stream,
options.subpath ?? '',
@@ -53,7 +53,7 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory {
async fromZipArchive(
options: ReadTreeResponseFactoryOptions,
): Promise<ReadTreeResponse> {
): Promise<UrlReaderReadTreeResponse> {
return new ZipArchiveResponse(
options.stream,
options.subpath ?? '',
@@ -65,7 +65,7 @@ export class DefaultReadTreeResponseFactory implements ReadTreeResponseFactory {
async fromReadableArray(
options: FromReadableArrayOptions,
): Promise<ReadTreeResponse> {
): Promise<UrlReaderReadTreeResponse> {
return new ReadableArrayResponse(options, this.workDir, '');
}
}
@@ -14,27 +14,26 @@
* limitations under the License.
*/
import {
UrlReaderReadTreeResponse,
UrlReaderReadTreeResponseDirOptions,
UrlReaderReadTreeResponseFile,
} from '@backstage/backend-plugin-api';
import concatStream from 'concat-stream';
import platformPath, { dirname } from 'path';
import getRawBody from 'raw-body';
import fs from 'fs-extra';
import { promisify } from 'util';
import tar from 'tar';
import { pipeline as pipelineCb, Readable } from 'stream';
import {
ReadTreeResponse,
ReadTreeResponseFile,
ReadTreeResponseDirOptions,
FromReadableArrayOptions,
} from '../types';
import { FromReadableArrayOptions } from '../types';
const pipeline = promisify(pipelineCb);
/**
* Wraps a array of Readable objects into a tree response reader.
*/
export class ReadableArrayResponse implements ReadTreeResponse {
export class ReadableArrayResponse implements UrlReaderReadTreeResponse {
private read = false;
constructor(
@@ -53,10 +52,10 @@ export class ReadableArrayResponse implements ReadTreeResponse {
this.read = true;
}
async files(): Promise<ReadTreeResponseFile[]> {
async files(): Promise<UrlReaderReadTreeResponseFile[]> {
this.onlyOnce();
const files = Array<ReadTreeResponseFile>();
const files = Array<UrlReaderReadTreeResponseFile>();
for (let i = 0; i < this.stream.length; i++) {
if (!this.stream[i].path.endsWith('/')) {
@@ -87,7 +86,7 @@ export class ReadableArrayResponse implements ReadTreeResponse {
}
}
async dir(options?: ReadTreeResponseDirOptions): Promise<string> {
async dir(options?: UrlReaderReadTreeResponseDirOptions): Promise<string> {
this.onlyOnce();
const dir =
@@ -14,17 +14,17 @@
* limitations under the License.
*/
import {
UrlReaderReadTreeResponse,
UrlReaderReadTreeResponseDirOptions,
UrlReaderReadTreeResponseFile,
} from '@backstage/backend-plugin-api';
import concatStream from 'concat-stream';
import fs from 'fs-extra';
import platformPath from 'path';
import { pipeline as pipelineCb, Readable } from 'stream';
import tar, { Parse, ParseStream, ReadEntry } from 'tar';
import { promisify } from 'util';
import {
ReadTreeResponse,
ReadTreeResponseDirOptions,
ReadTreeResponseFile,
} from '../types';
import { stripFirstDirectoryFromPath } from './util';
// Tar types for `Parse` is not a proper constructor, but it should be
@@ -35,7 +35,7 @@ const pipeline = promisify(pipelineCb);
/**
* Wraps a tar archive stream into a tree response reader.
*/
export class TarArchiveResponse implements ReadTreeResponse {
export class TarArchiveResponse implements UrlReaderReadTreeResponse {
private read = false;
constructor(
@@ -68,10 +68,10 @@ export class TarArchiveResponse implements ReadTreeResponse {
this.read = true;
}
async files(): Promise<ReadTreeResponseFile[]> {
async files(): Promise<UrlReaderReadTreeResponseFile[]> {
this.onlyOnce();
const files = Array<ReadTreeResponseFile>();
const files = Array<UrlReaderReadTreeResponseFile>();
const parser = new TarParseStream();
parser.on('entry', (entry: ReadEntry & Readable) => {
@@ -142,7 +142,7 @@ export class TarArchiveResponse implements ReadTreeResponse {
}
}
async dir(options?: ReadTreeResponseDirOptions): Promise<string> {
async dir(options?: UrlReaderReadTreeResponseDirOptions): Promise<string> {
this.onlyOnce();
const dir =
@@ -14,23 +14,23 @@
* limitations under the License.
*/
import {
UrlReaderReadTreeResponse,
UrlReaderReadTreeResponseDirOptions,
UrlReaderReadTreeResponseFile,
} from '@backstage/backend-plugin-api';
import archiver from 'archiver';
import yauzl, { Entry } from 'yauzl';
import fs from 'fs-extra';
import platformPath from 'path';
import { Readable } from 'stream';
import {
ReadTreeResponse,
ReadTreeResponseDirOptions,
ReadTreeResponseFile,
} from '../types';
import { streamToBuffer } from './util';
import { resolveSafeChildPath } from '@backstage/backend-plugin-api';
/**
* Wraps a zip archive stream into a tree response reader.
*/
export class ZipArchiveResponse implements ReadTreeResponse {
export class ZipArchiveResponse implements UrlReaderReadTreeResponse {
private read = false;
constructor(
@@ -141,9 +141,9 @@ export class ZipArchiveResponse implements ReadTreeResponse {
});
}
async files(): Promise<ReadTreeResponseFile[]> {
async files(): Promise<UrlReaderReadTreeResponseFile[]> {
this.onlyOnce();
const files = Array<ReadTreeResponseFile>();
const files = Array<UrlReaderReadTreeResponseFile>();
const temporary = await this.streamToTemporaryFile(this.stream);
await this.forEveryZipEntry(temporary.fileName, async (entry, content) => {
@@ -184,7 +184,7 @@ export class ZipArchiveResponse implements ReadTreeResponse {
return archive;
}
async dir(options?: ReadTreeResponseDirOptions): Promise<string> {
async dir(options?: UrlReaderReadTreeResponseDirOptions): Promise<string> {
this.onlyOnce();
const dir =
options?.targetDir ??
@@ -18,23 +18,10 @@ import { Readable } from 'stream';
import { Config } from '@backstage/config';
import {
UrlReaderService,
ReadTreeResponse,
UrlReaderReadTreeResponse,
LoggerService,
} from '@backstage/backend-plugin-api';
export type {
UrlReaderService as UrlReader,
ReadTreeOptions,
ReadTreeResponse,
ReadTreeResponseDirOptions,
ReadTreeResponseFile,
ReadUrlResponse,
ReadUrlOptions,
SearchOptions,
SearchResponse,
SearchResponseFile,
} from '@backstage/backend-plugin-api';
/**
* A predicate that decides whether a specific {@link @backstage/backend-plugin-api#UrlReaderService} can handle a
* given URL.
@@ -123,11 +110,11 @@ export interface ReadTreeResponseFactory {
*/
stripFirstDirectory?: boolean;
},
): Promise<ReadTreeResponse>;
): Promise<UrlReaderReadTreeResponse>;
fromZipArchive(
options: ReadTreeResponseFactoryOptions,
): Promise<ReadTreeResponse>;
): Promise<UrlReaderReadTreeResponse>;
fromReadableArray(
options: FromReadableArrayOptions,
): Promise<ReadTreeResponse>;
): Promise<UrlReaderReadTreeResponse>;
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { UrlReaders } from '@backstage/backend-common';
import { UrlReaders } from './lib/UrlReaders';
import {
coreServices,
createServiceFactory,
+99 -63
View File
@@ -466,54 +466,23 @@ export function readSchedulerServiceTaskScheduleDefinitionFromConfig(
config: Config,
): SchedulerServiceTaskScheduleDefinition;
// @public
export type ReadTreeOptions = {
filter?(
path: string,
info?: {
size: number;
},
): boolean;
etag?: string;
signal?: AbortSignal;
token?: string;
};
// @public @deprecated (undocumented)
export type ReadTreeOptions = UrlReaderReadTreeOptions;
// @public
export type ReadTreeResponse = {
files(): Promise<ReadTreeResponseFile[]>;
archive(): Promise<NodeJS.ReadableStream>;
dir(options?: ReadTreeResponseDirOptions): Promise<string>;
etag: string;
};
// @public @deprecated (undocumented)
export type ReadTreeResponse = UrlReaderReadTreeResponse;
// @public
export type ReadTreeResponseDirOptions = {
targetDir?: string;
};
// @public @deprecated (undocumented)
export type ReadTreeResponseDirOptions = UrlReaderReadTreeResponseDirOptions;
// @public
export type ReadTreeResponseFile = {
path: string;
content(): Promise<Buffer>;
lastModifiedAt?: Date;
};
// @public @deprecated (undocumented)
export type ReadTreeResponseFile = UrlReaderReadTreeResponseFile;
// @public
export type ReadUrlOptions = {
etag?: string;
lastModifiedAfter?: Date;
signal?: AbortSignal;
token?: string;
};
// @public @deprecated (undocumented)
export type ReadUrlOptions = UrlReaderReadUrlOptions;
// @public
export type ReadUrlResponse = {
buffer(): Promise<Buffer>;
stream?(): Readable;
etag?: string;
lastModifiedAt?: Date;
};
// @public @deprecated (undocumented)
export type ReadUrlResponse = UrlReaderReadUrlResponse;
// @public
export function resolvePackagePath(name: string, ...paths: string[]): string;
@@ -617,25 +586,14 @@ export interface SchedulerServiceTaskScheduleDefinitionConfig {
timeout: string | HumanDuration;
}
// @public
export type SearchOptions = {
etag?: string;
signal?: AbortSignal;
token?: string;
};
// @public @deprecated (undocumented)
export type SearchOptions = UrlReaderSearchOptions;
// @public
export type SearchResponse = {
files: SearchResponseFile[];
etag: string;
};
// @public @deprecated (undocumented)
export type SearchResponse = UrlReaderSearchResponse;
// @public
export type SearchResponseFile = {
url: string;
content(): Promise<Buffer>;
lastModifiedAt?: Date;
};
// @public @deprecated (undocumented)
export type SearchResponseFile = UrlReaderSearchResponseFile;
// @public (undocumented)
export interface ServiceFactory<
@@ -680,11 +638,89 @@ export interface TokenManagerService {
}>;
}
// @public
export type UrlReaderReadTreeOptions = {
filter?(
path: string,
info?: {
size: number;
},
): boolean;
etag?: string;
signal?: AbortSignal;
token?: string;
};
// @public
export type UrlReaderReadTreeResponse = {
files(): Promise<UrlReaderReadTreeResponseFile[]>;
archive(): Promise<NodeJS.ReadableStream>;
dir(options?: UrlReaderReadTreeResponseDirOptions): Promise<string>;
etag: string;
};
// @public
export type UrlReaderReadTreeResponseDirOptions = {
targetDir?: string;
};
// @public
export type UrlReaderReadTreeResponseFile = {
path: string;
content(): Promise<Buffer>;
lastModifiedAt?: Date;
};
// @public
export type UrlReaderReadUrlOptions = {
etag?: string;
lastModifiedAfter?: Date;
signal?: AbortSignal;
token?: string;
};
// @public
export type UrlReaderReadUrlResponse = {
buffer(): Promise<Buffer>;
stream?(): Readable;
etag?: string;
lastModifiedAt?: Date;
};
// @public
export type UrlReaderSearchOptions = {
etag?: string;
signal?: AbortSignal;
token?: string;
};
// @public
export type UrlReaderSearchResponse = {
files: UrlReaderSearchResponseFile[];
etag: string;
};
// @public
export type UrlReaderSearchResponseFile = {
url: string;
content(): Promise<Buffer>;
lastModifiedAt?: Date;
};
// @public
export interface UrlReaderService {
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
}
// @public
@@ -27,17 +27,26 @@ export interface UrlReaderService {
/**
* Reads a single file and return its content.
*/
readUrl(url: string, options?: ReadUrlOptions): Promise<ReadUrlResponse>;
readUrl(
url: string,
options?: UrlReaderReadUrlOptions,
): Promise<UrlReaderReadUrlResponse>;
/**
* Reads a full or partial file tree.
*/
readTree(url: string, options?: ReadTreeOptions): Promise<ReadTreeResponse>;
readTree(
url: string,
options?: UrlReaderReadTreeOptions,
): Promise<UrlReaderReadTreeResponse>;
/**
* Searches for a file in a tree using a glob pattern.
*/
search(url: string, options?: SearchOptions): Promise<SearchResponse>;
search(
url: string,
options?: UrlReaderSearchOptions,
): Promise<UrlReaderSearchResponse>;
}
/**
@@ -45,7 +54,7 @@ export interface UrlReaderService {
*
* @public
*/
export type ReadUrlOptions = {
export type UrlReaderReadUrlOptions = {
/**
* An ETag which can be provided to check whether a
* {@link UrlReaderService.readUrl} response has changed from a previous execution.
@@ -113,7 +122,7 @@ export type ReadUrlOptions = {
*
* @public
*/
export type ReadUrlResponse = {
export type UrlReaderReadUrlResponse = {
/**
* Returns the data that was read from the remote URL.
*/
@@ -148,7 +157,7 @@ export type ReadUrlResponse = {
*
* @public
*/
export type ReadTreeOptions = {
export type UrlReaderReadTreeOptions = {
/**
* A filter that can be used to select which files should be included.
*
@@ -208,11 +217,11 @@ export type ReadTreeOptions = {
};
/**
* Options that control {@link ReadTreeResponse.dir} execution.
* Options that control {@link UrlReaderReadTreeResponse.dir} execution.
*
* @public
*/
export type ReadTreeResponseDirOptions = {
export type UrlReaderReadTreeResponseDirOptions = {
/**
* The directory to write files to.
*
@@ -228,12 +237,12 @@ export type ReadTreeResponseDirOptions = {
*
* @public
*/
export type ReadTreeResponse = {
export type UrlReaderReadTreeResponse = {
/**
* Returns an array of all the files inside the tree, and corresponding
* functions to read their content.
*/
files(): Promise<ReadTreeResponseFile[]>;
files(): Promise<UrlReaderReadTreeResponseFile[]>;
/**
* Returns the tree contents as a binary archive, using a stream.
@@ -246,7 +255,7 @@ export type ReadTreeResponse = {
*
* **NOTE**: It is the responsibility of the caller to remove the directory after use.
*/
dir(options?: ReadTreeResponseDirOptions): Promise<string>;
dir(options?: UrlReaderReadTreeResponseDirOptions): Promise<string>;
/**
* Etag returned by content provider.
@@ -263,7 +272,7 @@ export type ReadTreeResponse = {
*
* @public
*/
export type ReadTreeResponseFile = {
export type UrlReaderReadTreeResponseFile = {
/**
* The filepath of the data.
*/
@@ -285,7 +294,7 @@ export type ReadTreeResponseFile = {
*
* @public
*/
export type SearchOptions = {
export type UrlReaderSearchOptions = {
/**
* An etag can be provided to check whether the search response has changed from a previous execution.
*
@@ -326,11 +335,11 @@ export type SearchOptions = {
*
* @public
*/
export type SearchResponse = {
export type UrlReaderSearchResponse = {
/**
* The files that matched the search query.
*/
files: SearchResponseFile[];
files: UrlReaderSearchResponseFile[];
/**
* A unique identifier of the current remote tree, usually the commit SHA or etag from the target.
@@ -343,7 +352,7 @@ export type SearchResponse = {
*
* @public
*/
export type SearchResponseFile = {
export type UrlReaderSearchResponseFile = {
/**
* The full URL to the file.
*/
@@ -359,3 +368,49 @@ export type SearchResponseFile = {
*/
lastModifiedAt?: Date;
};
/**
* @public
* @deprecated Use `UrlReaderReadTreeOptions` instead
*/
export type ReadTreeOptions = UrlReaderReadTreeOptions;
/**
* @public
* @deprecated Use `UrlReaderReadTreeResponse` instead
*/
export type ReadTreeResponse = UrlReaderReadTreeResponse;
/**
* @public
* @deprecated Use `UrlReaderReadTreeResponseDirOptions` instead
*/
export type ReadTreeResponseDirOptions = UrlReaderReadTreeResponseDirOptions;
/**
* @public
* @deprecated Use `UrlReaderReadTreeResponseFile` instead
*/
export type ReadTreeResponseFile = UrlReaderReadTreeResponseFile;
/**
* @public
* @deprecated Use `UrlReaderReadUrlResponse` instead
*/
export type ReadUrlResponse = UrlReaderReadUrlResponse;
/**
* @public
* @deprecated Use `UrlReaderReadUrlOptions` instead
*/
export type ReadUrlOptions = UrlReaderReadUrlOptions;
/**
* @public
* @deprecated Use `UrlReaderSearchOptions` instead
*/
export type SearchOptions = UrlReaderSearchOptions;
/**
* @public
* @deprecated Use `UrlReaderSearchResponse` instead
*/
export type SearchResponse = UrlReaderSearchResponse;
/**
* @public
* @deprecated Use `UrlReaderSearchResponseFile` instead
*/
export type SearchResponseFile = UrlReaderSearchResponseFile;
@@ -74,6 +74,15 @@ export type {
SearchOptions,
SearchResponse,
SearchResponseFile,
UrlReaderReadTreeOptions,
UrlReaderReadTreeResponse,
UrlReaderReadTreeResponseDirOptions,
UrlReaderReadTreeResponseFile,
UrlReaderReadUrlResponse,
UrlReaderReadUrlOptions,
UrlReaderSearchOptions,
UrlReaderSearchResponse,
UrlReaderSearchResponseFile,
UrlReaderService,
} from './UrlReaderService';
export type { BackstageUserInfo, UserInfoService } from './UserInfoService';
+22
View File
@@ -3588,6 +3588,12 @@ __metadata:
version: 0.0.0-use.local
resolution: "@backstage/backend-defaults@workspace:packages/backend-defaults"
dependencies:
"@aws-sdk/abort-controller": ^3.347.0
"@aws-sdk/client-codecommit": ^3.350.0
"@aws-sdk/client-s3": ^3.350.0
"@aws-sdk/credential-providers": ^3.350.0
"@aws-sdk/types": ^3.347.0
"@aws-sdk/util-stream-node": ^3.350.0
"@backstage/backend-app-api": "workspace:^"
"@backstage/backend-common": "workspace:^"
"@backstage/backend-dev-utils": "workspace:^"
@@ -3597,25 +3603,41 @@ __metadata:
"@backstage/config": "workspace:^"
"@backstage/config-loader": "workspace:^"
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/integration-aws-node": "workspace:^"
"@backstage/plugin-events-node": "workspace:^"
"@backstage/plugin-permission-node": "workspace:^"
"@backstage/types": "workspace:^"
"@google-cloud/storage": ^7.0.0
"@keyv/memcache": ^1.3.5
"@keyv/redis": ^2.5.3
"@octokit/rest": ^19.0.3
"@opentelemetry/api": ^1.3.0
archiver: ^6.0.0
aws-sdk-client-mock: ^4.0.0
base64-stream: ^1.0.0
better-sqlite3: ^9.0.0
concat-stream: ^2.0.0
cron: ^3.0.0
fs-extra: ^11.2.0
git-url-parse: ^14.0.0
isomorphic-git: ^1.23.0
keyv: ^4.5.2
knex: ^3.0.0
lodash: ^4.17.21
luxon: ^3.0.0
minimatch: ^9.0.0
msw: ^1.0.0
mysql2: ^3.0.0
node-fetch: ^2.6.7
p-limit: ^3.1.0
pg: ^8.11.3
pg-connection-string: ^2.3.0
raw-body: ^2.4.1
tar: ^6.1.12
uuid: ^9.0.0
wait-for-expect: ^3.0.2
yauzl: ^3.0.0
yn: ^4.0.0
zod: ^3.22.4
languageName: unknown