From ced3d7cef84a5517847e276c21d048e185ace2f6 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Tue, 22 Feb 2022 08:55:50 +0100 Subject: [PATCH 1/7] refactor(techdocs-common): clean up generator api Signed-off-by: Camila Belo --- packages/techdocs-common/api-report.md | 20 +- packages/techdocs-common/config.d.ts | 195 ++++++++++++++++++ .../src/stages/generate/generators.ts | 18 ++ .../src/stages/generate/index.ts | 4 +- .../src/stages/generate/techdocs.ts | 16 +- .../src/stages/generate/types.ts | 21 +- .../techdocs-common/src/stages/prepare/dir.ts | 29 ++- 7 files changed, 284 insertions(+), 19 deletions(-) create mode 100644 packages/techdocs-common/config.d.ts diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md index f189a85c0c..53d107bd17 100644 --- a/packages/techdocs-common/api-report.md +++ b/packages/techdocs-common/api-report.md @@ -17,21 +17,19 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { UrlReader } from '@backstage/backend-common'; import { Writable } from 'stream'; -// Warning: (ae-missing-release-tag) "DirectoryPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export class DirectoryPreparer implements PreparerBase { - constructor(config: Config, _logger: Logger_2, reader: UrlReader); + // @deprecated + constructor(config: Config, _logger: Logger_2 | null, reader: UrlReader); + // Warning: (ae-forgotten-export) The symbol "DirectoryPreparerOptions" needs to be exported by the entry point index.d.ts + // + // (undocumented) + static fromConfig(options: DirectoryPreparerOptions): DirectoryPreparer; + // Warning: (ae-forgotten-export) The symbol "PreparerOptions" needs to be exported by the entry point index.d.ts // Warning: (ae-forgotten-export) The symbol "PreparerResponse" needs to be exported by the entry point index.d.ts // // (undocumented) - prepare( - entity: Entity, - options?: { - logger?: Logger_2; - etag?: string; - }, - ): Promise; + prepare(entity: Entity, options?: PreparerOptions): Promise; } // Warning: (ae-missing-release-tag) "GeneratorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/packages/techdocs-common/config.d.ts b/packages/techdocs-common/config.d.ts new file mode 100644 index 0000000000..54e76c1a1c --- /dev/null +++ b/packages/techdocs-common/config.d.ts @@ -0,0 +1,195 @@ +/* + * Copyright 2022 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 interface Config { + app: { + baseUrl: string; // defined in core, but repeated here without doc + }; + + backend: { + /** Backend configuration for when request authentication is enabled */ + auth?: { + /** Keys shared by all backends for signing and validating backend tokens. */ + keys: { + /** + * Secret for generating tokens. Should be a base64 string, recommended + * length is 24 bytes. + * + * @visibility secret + */ + secret: string; + }[]; + }; + + baseUrl: string; // defined in core, but repeated here without doc + + /** Address that the backend should listen to. */ + listen: + | string + | { + /** Address of the interface that the backend should bind to. */ + host?: string; + /** Port that the backend should listen to. */ + port?: string | number; + }; + + /** + * HTTPS configuration for the backend. If omitted the backend will serve HTTP. + * + * Setting this to `true` will cause self-signed certificates to be generated, which + * can be useful for local development or other non-production scenarios. + */ + https?: + | true + | { + /** Certificate configuration */ + certificate?: { + /** PEM encoded certificate. Use $file to load in a file */ + cert: string; + /** + * PEM encoded certificate key. Use $file to load in a file. + * @visibility secret + */ + key: string; + }; + }; + + /** Database connection configuration, select base database type using the `client` field */ + database: { + /** Default database client to use */ + client: 'sqlite3' | 'pg'; + /** + * Base database connection string or Knex object + * @secret + */ + connection: string | object; + /** Database name prefix override */ + prefix?: string; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to true if unspecified. + */ + ensureExists?: boolean; + /** + * How plugins databases are managed/divided in the provided database instance. + * + * `database` -> Plugins are each given their own database to manage their schemas/tables. + * + * `schema` -> Plugins will be given their own schema (in the specified/default database) + * to manage their tables. + * + * NOTE: Currently only supported by the `pg` client. + * + * @default database + */ + pluginDivisionMode?: 'database' | 'schema'; + /** + * Arbitrary config object to pass to knex when initializing + * (https://knexjs.org/#Installation-client). Most notable is the debug + * and asyncStackTraces booleans + */ + knexConfig?: object; + /** Plugin specific database configuration and client override */ + plugin?: { + [pluginId: string]: { + /** Database client override */ + client?: 'sqlite3' | 'pg'; + /** + * Database connection string or Knex object override + * @secret + */ + connection?: string | object; + /** + * Whether to ensure the given database exists by creating it if it does not. + * Defaults to base config if unspecified. + */ + ensureExists?: boolean; + /** + * Arbitrary config object to pass to knex when initializing + * (https://knexjs.org/#Installation-client). Most notable is the + * debug and asyncStackTraces booleans. + * + * This is merged recursively into the base knexConfig + */ + knexConfig?: object; + }; + }; + }; + + /** Cache connection configuration, select cache type using the `store` field */ + cache?: + | { + store: 'memory'; + } + | { + store: 'memcache'; + /** + * A memcache connection string in the form `user:pass@host:port`. + * @secret + */ + connection: string; + }; + + cors?: { + origin?: string | string[]; + methods?: string | string[]; + allowedHeaders?: string | string[]; + exposedHeaders?: string | string[]; + credentials?: boolean; + maxAge?: number; + preflightContinue?: boolean; + optionsSuccessStatus?: number; + }; + + /** + * Configuration related to URL reading, used for example for reading catalog info + * files, scaffolder templates, and techdocs content. + */ + reading?: { + /** + * A list of targets to allow outgoing requests to. Users will be able to make + * requests on behalf of the backend to the targets that are allowed by this list. + */ + allow?: Array<{ + /** + * A host to allow outgoing requests to, being either a full host or + * a subdomain wildcard pattern with a leading `*`. For example `example.com` + * and `*.example.com` are valid values, `prod.*.example.com` is not. + * The host may also contain a port, for example `example.com:8080`. + */ + host: string; + + /** + * An optional list of paths. In case they are present only targets matching + * any of them will are allowed. You can use trailing slashes to make sure only + * subdirectories are allowed, for example `/mydir/` will allow targets with + * paths like `/mydir/a` but will block paths like `/mydir2`. + */ + paths?: string[]; + }>; + }; + + /** + * Content Security Policy options. + * + * The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The + * values are on the format that the helmet library expects them, as an + * array of strings. There is also the special value false, which means to + * remove the default value that Backstage puts in place for that policy. + */ + csp?: { [policyId: string]: string[] | false }; + }; +} diff --git a/packages/techdocs-common/src/stages/generate/generators.ts b/packages/techdocs-common/src/stages/generate/generators.ts index de39d4e7c3..22d07a49b9 100644 --- a/packages/techdocs-common/src/stages/generate/generators.ts +++ b/packages/techdocs-common/src/stages/generate/generators.ts @@ -26,9 +26,18 @@ import { SupportedGeneratorKey, } from './types'; +/** + * Collection of docs generators + * @public + */ export class Generators implements GeneratorBuilder { private generatorMap = new Map(); + /** + * Returns a generators instance containing a generator for Tech Docs + * @param config - A Backstage configuration + * @param options - Options to configure the Tech Docs generator + */ static async fromConfig( config: Config, options: { logger: Logger; containerRunner: ContainerRunner }, @@ -41,10 +50,19 @@ export class Generators implements GeneratorBuilder { return generators; } + /** + * Register a generator in the generators collection + * @param generatorKey - Unique identifier for the generator + * @param generator - The generator instance to register + */ register(generatorKey: SupportedGeneratorKey, generator: GeneratorBase) { this.generatorMap.set(generatorKey, generator); } + /** + * Returns the generator for a given Tech Docs entity + * @param entity - A Tech Docs entity instance + */ get(entity: Entity): GeneratorBase { const generatorKey = getGeneratorKey(entity); const generator = this.generatorMap.get(generatorKey); diff --git a/packages/techdocs-common/src/stages/generate/index.ts b/packages/techdocs-common/src/stages/generate/index.ts index eb015a5c2d..5b442be1ae 100644 --- a/packages/techdocs-common/src/stages/generate/index.ts +++ b/packages/techdocs-common/src/stages/generate/index.ts @@ -16,7 +16,9 @@ export { TechdocsGenerator } from './techdocs'; export { Generators } from './generators'; export type { - GeneratorBuilder, GeneratorBase, + GeneratorBuilder, + GeneratorFactory, GeneratorRunOptions, + SupportedGeneratorKey, } from './types'; diff --git a/packages/techdocs-common/src/stages/generate/techdocs.ts b/packages/techdocs-common/src/stages/generate/techdocs.ts index 99554a6218..c6a170910d 100644 --- a/packages/techdocs-common/src/stages/generate/techdocs.ts +++ b/packages/techdocs-common/src/stages/generate/techdocs.ts @@ -38,7 +38,12 @@ import { GeneratorRunOptions, } from './types'; import { ForwardedError } from '@backstage/errors'; +import { GeneratorFactory } from './types'; +/** + * Generates documentation files + * @public + */ export class TechdocsGenerator implements GeneratorBase { /** * The default docker image (and version) used to generate content. Public @@ -50,10 +55,12 @@ export class TechdocsGenerator implements GeneratorBase { private readonly options: GeneratorConfig; private readonly scmIntegrations: ScmIntegrationRegistry; - static fromConfig( - config: Config, - options: { containerRunner: ContainerRunner; logger: Logger }, - ) { + /** + * Returns a instance of Tech Docs generator + * @param config - A Backstage configuration + * @param options - Options to configure the generator + */ + static fromConfig(config: Config, options: GeneratorFactory) { const { containerRunner, logger } = options; const scmIntegrations = ScmIntegrations.fromConfig(config); return new TechdocsGenerator({ @@ -76,6 +83,7 @@ export class TechdocsGenerator implements GeneratorBase { this.scmIntegrations = options.scmIntegrations; } + /** {@inheritDoc GeneratorBase.run} */ public async run(options: GeneratorRunOptions): Promise { const { inputDir, diff --git a/packages/techdocs-common/src/stages/generate/types.ts b/packages/techdocs-common/src/stages/generate/types.ts index 2a090d5584..4903d886f1 100644 --- a/packages/techdocs-common/src/stages/generate/types.ts +++ b/packages/techdocs-common/src/stages/generate/types.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { ContainerRunner } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { Writable } from 'stream'; import { Logger } from 'winston'; @@ -22,6 +23,15 @@ import { ParsedLocationAnnotation } from '../../helpers'; // Determines where the generator will be run export type GeneratorRunInType = 'docker' | 'local'; +/** + * Options for building generators + * @public + */ +export type GeneratorFactory = { + containerRunner: ContainerRunner; + logger: Logger; +}; + /** * The techdocs generator configurations options. */ @@ -51,18 +61,27 @@ export type GeneratorRunOptions = { logStream?: Writable; }; +/** + * Generates documentation files + * @public + */ export type GeneratorBase = { - // Runs the generator with the values + /** + * Runs the generator with the values + * @public + */ run(opts: GeneratorRunOptions): Promise; }; /** * List of supported generator options + * @public */ export type SupportedGeneratorKey = 'techdocs' | string; /** * The generator builder holds the generator ready for run time + * @public */ export type GeneratorBuilder = { register(protocol: SupportedGeneratorKey, generator: GeneratorBase): void; diff --git a/packages/techdocs-common/src/stages/prepare/dir.ts b/packages/techdocs-common/src/stages/prepare/dir.ts index ade0b00162..c8b8943266 100644 --- a/packages/techdocs-common/src/stages/prepare/dir.ts +++ b/packages/techdocs-common/src/stages/prepare/dir.ts @@ -26,18 +26,43 @@ import { Logger } from 'winston'; import { parseReferenceAnnotation, transformDirLocation } from '../../helpers'; import { PreparerBase, PreparerResponse } from './types'; +export type DirectoryPreparerOptions = { + config: Config; + reader: UrlReader; +}; + +export type PreparerOptions = { logger?: Logger; etag?: string }; + +/** + * Prepares files before building documentation + * + * @public + */ export class DirectoryPreparer implements PreparerBase { private readonly scmIntegrations: ScmIntegrationRegistry; private readonly reader: UrlReader; - constructor(config: Config, _logger: Logger, reader: UrlReader) { + /** + * @deprecated use static fromConfig method instead. + */ + constructor(config: Config, _logger: Logger | null, reader: UrlReader) { this.reader = reader; this.scmIntegrations = ScmIntegrations.fromConfig(config); } + static fromConfig(options: DirectoryPreparerOptions): DirectoryPreparer { + return new DirectoryPreparer(options.config, null, options.reader); + } + + /** + * + * @param entity - The parts of the format that's common to all versions/kinds of entity + * @param options - Optional logger and etag + * @returns + */ async prepare( entity: Entity, - options?: { logger?: Logger; etag?: string }, + options?: PreparerOptions, ): Promise { const annotation = parseReferenceAnnotation( 'backstage.io/techdocs-ref', From 2f16b943c925ce62a74bf4cc5943474184fa089a Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 23 Feb 2022 14:28:23 +0100 Subject: [PATCH 2/7] refactor(techdocs-common): clean up preparer api Signed-off-by: Camila Belo --- .../techdocs-common/src/stages/prepare/dir.ts | 40 +++++------ .../src/stages/prepare/index.ts | 12 +++- .../src/stages/prepare/preparers.ts | 36 +++++++--- .../src/stages/prepare/types.ts | 70 +++++++++++++++++-- .../techdocs-common/src/stages/prepare/url.ts | 17 ++++- 5 files changed, 137 insertions(+), 38 deletions(-) diff --git a/packages/techdocs-common/src/stages/prepare/dir.ts b/packages/techdocs-common/src/stages/prepare/dir.ts index c8b8943266..0b43a459de 100644 --- a/packages/techdocs-common/src/stages/prepare/dir.ts +++ b/packages/techdocs-common/src/stages/prepare/dir.ts @@ -24,42 +24,40 @@ import { } from '@backstage/integration'; import { Logger } from 'winston'; import { parseReferenceAnnotation, transformDirLocation } from '../../helpers'; -import { PreparerBase, PreparerResponse } from './types'; - -export type DirectoryPreparerOptions = { - config: Config; - reader: UrlReader; -}; - -export type PreparerOptions = { logger?: Logger; etag?: string }; +import { + PreparerBase, + PreparerOptions, + PreparerResponse, + DirectoryFactory, +} from './types'; /** - * Prepares files before building documentation - * + * Preparer used to retrieve documentation files from a local directory * @public */ export class DirectoryPreparer implements PreparerBase { private readonly scmIntegrations: ScmIntegrationRegistry; private readonly reader: UrlReader; - /** - * @deprecated use static fromConfig method instead. - */ + /** @deprecated use static fromConfig method instead */ constructor(config: Config, _logger: Logger | null, reader: UrlReader) { this.reader = reader; this.scmIntegrations = ScmIntegrations.fromConfig(config); } - static fromConfig(options: DirectoryPreparerOptions): DirectoryPreparer { - return new DirectoryPreparer(options.config, null, options.reader); + /** + * Returns a directory preparer instance + * @param config - A backstage config + * @param options - A directory preparer options containing the URL reader + */ + static fromConfig( + config: Config, + options: DirectoryFactory, + ): DirectoryPreparer { + return new DirectoryPreparer(config, null, options.reader); } - /** - * - * @param entity - The parts of the format that's common to all versions/kinds of entity - * @param options - Optional logger and etag - * @returns - */ + /** {@inheritDoc PreparerBase.prepare} */ async prepare( entity: Entity, options?: PreparerOptions, diff --git a/packages/techdocs-common/src/stages/prepare/index.ts b/packages/techdocs-common/src/stages/prepare/index.ts index f129bf5315..c78e1082e2 100644 --- a/packages/techdocs-common/src/stages/prepare/index.ts +++ b/packages/techdocs-common/src/stages/prepare/index.ts @@ -16,4 +16,14 @@ export { DirectoryPreparer } from './dir'; export { UrlPreparer } from './url'; export { Preparers } from './preparers'; -export type { PreparerBuilder, PreparerBase, RemoteProtocol } from './types'; +export type { + PreparerBase, + PreparerBuilder, + PreparerFactory, + PreparerOptions, + PreparerResponse, + DirectoryFactory, + UrlFactory, + RemoteProtocol, + ETag, +} from './types'; diff --git a/packages/techdocs-common/src/stages/prepare/preparers.ts b/packages/techdocs-common/src/stages/prepare/preparers.ts index 75c9a7f23b..90207c1a1a 100644 --- a/packages/techdocs-common/src/stages/prepare/preparers.ts +++ b/packages/techdocs-common/src/stages/prepare/preparers.ts @@ -13,26 +13,34 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { UrlReader } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { Config } from '@backstage/config'; -import { Logger } from 'winston'; import { parseReferenceAnnotation } from '../../helpers'; import { DirectoryPreparer } from './dir'; import { UrlPreparer } from './url'; -import { PreparerBase, PreparerBuilder, RemoteProtocol } from './types'; - -type factoryOptions = { - logger: Logger; - reader: UrlReader; -}; +import { + PreparerBase, + PreparerBuilder, + PreparerFactory, + RemoteProtocol, +} from './types'; +/** + * Collection of docs preparers + * @public + */ export class Preparers implements PreparerBuilder { private preparerMap = new Map(); + /** + * Returns a generators instance containing a generator for Tech Docs + * @public + * @param config - A Backstage configuration + * @param options - Options to configure the URL preparer + */ static async fromConfig( config: Config, - { logger, reader }: factoryOptions, + { logger, reader }: PreparerFactory, ): Promise { const preparers = new Preparers(); @@ -49,10 +57,20 @@ export class Preparers implements PreparerBuilder { return preparers; } + /** + * Register a preparer in the preparers collection + * @param protocol - url or dir to associate with preparer + * @param preparer - The preparer instance to set + */ register(protocol: RemoteProtocol, preparer: PreparerBase) { this.preparerMap.set(protocol, preparer); } + /** + * Returns the preparer for a given Tech Docs entity + * @param entity - A Tech Docs entity instance + * @returns + */ get(entity: Entity): PreparerBase { const { type } = parseReferenceAnnotation( 'backstage.io/techdocs-ref', diff --git a/packages/techdocs-common/src/stages/prepare/types.ts b/packages/techdocs-common/src/stages/prepare/types.ts index 5c219752fa..ed3d20c2dd 100644 --- a/packages/techdocs-common/src/stages/prepare/types.ts +++ b/packages/techdocs-common/src/stages/prepare/types.ts @@ -15,19 +15,72 @@ */ import type { Entity } from '@backstage/catalog-model'; +import { UrlReader } from '@backstage/backend-common'; import { Logger } from 'winston'; +/** + * Options for building preparers + * @public + */ +export type PreparerFactory = { + logger: Logger; + reader: UrlReader; +}; + +/** + * Options to configure a directory preparer. + * @public + */ +export type DirectoryFactory = { + reader: UrlReader; +}; + +/** + * Options to configure a url preparer. + * @public + */ +export type UrlFactory = PreparerFactory; + +/** + * A unique identifier of the tree blob, usually the commit SHA or etag from the target. + * @public + */ +export type ETag = string; + +/** + * Options for configuring the content preparation process. + * @public + */ +export type PreparerOptions = { + /** + * An instance of the logger + */ + logger?: Logger; + /** + * see {@link ETag} + */ + etag?: ETag; +}; + +/** + * Result of the preparation step. + * @public + */ export type PreparerResponse = { /** * The path to directory where the tree is downloaded. */ preparedDir: string; /** - * A unique identifier of the tree blob, usually the commit SHA or etag from the target. + * see {@link ETag} */ - etag: string; + etag: ETag; }; +/** + * Definition of a Tech Docs preparer + * @public + */ export type PreparerBase = { /** * Given an Entity definition from the Software Catalog, go and prepare a directory @@ -38,15 +91,20 @@ export type PreparerBase = { * updated since the last build. * @throws `NotModifiedError` when the prepared directory has not been changed since the last build. */ - prepare( - entity: Entity, - options?: { logger?: Logger; etag?: string }, - ): Promise; + prepare(entity: Entity, options?: PreparerOptions): Promise; }; +/** + * Definition for a Tech Docs preparer builder + * @public + */ export type PreparerBuilder = { register(protocol: RemoteProtocol, preparer: PreparerBase): void; get(entity: Entity): PreparerBase; }; +/** + * Location where documentation files are stored + * @public + */ export type RemoteProtocol = 'url' | 'dir'; diff --git a/packages/techdocs-common/src/stages/prepare/url.ts b/packages/techdocs-common/src/stages/prepare/url.ts index cd4a8860e4..75f10b64d5 100644 --- a/packages/techdocs-common/src/stages/prepare/url.ts +++ b/packages/techdocs-common/src/stages/prepare/url.ts @@ -19,17 +19,32 @@ import { UrlReader } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { Logger } from 'winston'; import { getDocFilesFromRepository } from '../../helpers'; -import { PreparerBase, PreparerResponse } from './types'; +import { PreparerBase, PreparerResponse, UrlFactory } from './types'; +/** + * Preparer used to retrieve documentation files from a remote repository + * @public + */ export class UrlPreparer implements PreparerBase { private readonly logger: Logger; private readonly reader: UrlReader; + /** @deprecated use static fromConfig method instead */ constructor(reader: UrlReader, logger: Logger) { this.logger = logger; this.reader = reader; } + /** + * Returns a directory preparer instance + * @param config - A backstage config + * @param options - A directory preparer options containing the URL reader + */ + static fromConfig(options: UrlFactory): UrlPreparer { + return new UrlPreparer(options.reader, options.logger); + } + + /** {@inheritDoc PreparerBase.prepare} */ async prepare( entity: Entity, options?: { etag?: string }, From 7a9b906ec741681187de47d8dbc002353cb5c8b7 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 23 Feb 2022 14:29:42 +0100 Subject: [PATCH 3/7] refactor(techdocs-common): clean up publish api Signed-off-by: Camila Belo --- .../src/stages/publish/index.ts | 6 ++++- .../src/stages/publish/publish.ts | 17 +++++++------- .../src/stages/publish/types.ts | 23 ++++++++++++++++++- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/packages/techdocs-common/src/stages/publish/index.ts b/packages/techdocs-common/src/stages/publish/index.ts index 083cf2b8ff..c6f86f6bc1 100644 --- a/packages/techdocs-common/src/stages/publish/index.ts +++ b/packages/techdocs-common/src/stages/publish/index.ts @@ -17,6 +17,10 @@ export { Publisher } from './publish'; export type { PublisherBase, PublisherType, - TechDocsMetadata, + PublisherFactory, + PublishRequest, + PublishResponse, + MigrateRequest, ReadinessResponse, + TechDocsMetadata, } from './types'; diff --git a/packages/techdocs-common/src/stages/publish/publish.ts b/packages/techdocs-common/src/stages/publish/publish.ts index eb9e3104bf..b9ea4c7cb4 100644 --- a/packages/techdocs-common/src/stages/publish/publish.ts +++ b/packages/techdocs-common/src/stages/publish/publish.ts @@ -14,29 +14,28 @@ * limitations under the License. */ -import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { Config } from '@backstage/config'; -import { Logger } from 'winston'; import { AwsS3Publish } from './awsS3'; import { AzureBlobStoragePublish } from './azureBlobStorage'; import { GoogleGCSPublish } from './googleStorage'; import { LocalPublish } from './local'; import { OpenStackSwiftPublish } from './openStackSwift'; -import { PublisherBase, PublisherType } from './types'; - -type factoryOptions = { - logger: Logger; - discovery: PluginEndpointDiscovery; -}; +import { PublisherFactory, PublisherBase, PublisherType } from './types'; /** * Factory class to create a TechDocs publisher based on defined publisher type in app config. * Uses `techdocs.publisher.type`. + * @public */ export class Publisher { + /** + * Returns a instance of Tech Docs publisher + * @param config - A Backstage configuration + * @param options - Options for configuring the publisher factory + */ static async fromConfig( config: Config, - { logger, discovery }: factoryOptions, + { logger, discovery }: PublisherFactory, ): Promise { const publisherType = (config.getOptionalString( 'techdocs.publisher.type', diff --git a/packages/techdocs-common/src/stages/publish/types.ts b/packages/techdocs-common/src/stages/publish/types.ts index 37075a35a4..0c3c047b40 100644 --- a/packages/techdocs-common/src/stages/publish/types.ts +++ b/packages/techdocs-common/src/stages/publish/types.ts @@ -14,10 +14,22 @@ * limitations under the License. */ import { Entity, EntityName } from '@backstage/catalog-model'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { Logger } from 'winston'; import express from 'express'; +/** + * Options for building publishers + * @public + */ +export type PublisherFactory = { + logger: Logger; + discovery: PluginEndpointDiscovery; +}; + /** * Key for all the different types of TechDocs publishers that are supported. + * @public */ export type PublisherType = | 'local' @@ -26,6 +38,10 @@ export type PublisherType = | 'azureBlobStorage' | 'openStackSwift'; +/** + * Request publish definition + * @public + */ export type PublishRequest = { entity: Entity; /* The Path to the directory where the generated files are stored. */ @@ -35,6 +51,7 @@ export type PublishRequest = { /** * Response containing metadata about where files were published and what may * have been published or updated. + * @public */ export type PublishResponse = { /** @@ -51,7 +68,6 @@ export type PublishResponse = { /** * Result for the validation check. - * * @public */ export type ReadinessResponse = { @@ -62,6 +78,7 @@ export type ReadinessResponse = { /** * Type to hold metadata found in techdocs_metadata.json and associated with each site * @param etag - ETag of the resource used to generate the site. Usually the latest commit sha of the source repository. + * @public */ export type TechDocsMetadata = { site_name: string; @@ -71,6 +88,10 @@ export type TechDocsMetadata = { files?: string[]; }; +/** + * Tech Docs entity triplet migration request + * @public + */ export type MigrateRequest = { /** * Whether or not to remove the source file. Defaults to false (acting like a From 947dcc465a9528ab96b15a97d2206c3640d2d11f Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 23 Feb 2022 14:30:09 +0100 Subject: [PATCH 4/7] refactor(techdocs-common): clean up helpers api Signed-off-by: Camila Belo --- packages/techdocs-common/src/helpers.ts | 25 ++++++++++++++++++- packages/techdocs-common/src/techdocsTypes.ts | 22 ++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/techdocs-common/src/helpers.ts b/packages/techdocs-common/src/helpers.ts index ccf1256381..9075660c0e 100644 --- a/packages/techdocs-common/src/helpers.ts +++ b/packages/techdocs-common/src/helpers.ts @@ -26,11 +26,21 @@ import path from 'path'; import { Logger } from 'winston'; import { PreparerResponse, RemoteProtocol } from './stages/prepare/types'; +/** + * Parsed location annotation + * @public + */ export type ParsedLocationAnnotation = { type: RemoteProtocol; target: string; }; +/** + * Returns a parset locations annotation + * @public + * @param annotationName - The name of the annotation in the entity metadata + * @param entity - A Tech Docs entity instance + */ export const parseReferenceAnnotation = ( annotationName: string, entity: Entity, @@ -56,7 +66,7 @@ export const parseReferenceAnnotation = ( * location, it returns a `url` location with a resolved target that points to the * targeted subfolder. If the entity was registered by a `file` location, it returns * an absolute `dir` location. - * + * @public * @param entity - the entity with annotations * @param dirAnnotation - the parsed techdocs-ref annotation of type 'dir' * @param scmIntegrations - access to the scmIntegration to do url transformations @@ -101,6 +111,12 @@ export const transformDirLocation = ( } }; +/** + * Returns a entity reference based on the Tech Docs annotation type + * @public + * @param entity - A Tech Docs instance + * @param scmIntegration - An implementation for SCM integration API + */ export const getLocationForEntity = ( entity: Entity, scmIntegration: ScmIntegrationRegistry, @@ -120,6 +136,13 @@ export const getLocationForEntity = ( } }; +/** + * Returns a preparer response {@link PreparerResponse} + * @public + * @param reader - Read a tree of files from a repository + * @param entity - A Tech Docs entity instance + * @param opts - Options for configuring the reader, e.g. logger, etag, etc. + */ export const getDocFilesFromRepository = async ( reader: UrlReader, entity: Entity, diff --git a/packages/techdocs-common/src/techdocsTypes.ts b/packages/techdocs-common/src/techdocsTypes.ts index 4aa3972b31..69f7b36e9f 100644 --- a/packages/techdocs-common/src/techdocsTypes.ts +++ b/packages/techdocs-common/src/techdocsTypes.ts @@ -16,11 +16,33 @@ import { IndexableDocument } from '@backstage/search-common'; +/** + * Tech Docs indexable document interface + * @public + */ export interface TechDocsDocument extends IndexableDocument { + /** + * Entity kind + */ kind: string; + /** + * Entity metadata namespace + */ namespace: string; + /** + * Entity metadata name + */ name: string; + /** + * Entity lifecycle + */ lifecycle: string; + /** + * Entity owner + */ owner: string; + /** + * Entity path + */ path: string; } From bda799308ca2a185fd0180389393ff145dca1d48 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Wed, 23 Feb 2022 14:31:44 +0100 Subject: [PATCH 5/7] chore(techdocs-common): update api reports Signed-off-by: Camila Belo --- packages/techdocs-common/api-report.md | 182 +++++++++++------------ packages/techdocs-common/config.d.ts | 195 ------------------------- 2 files changed, 85 insertions(+), 292 deletions(-) delete mode 100644 packages/techdocs-common/config.d.ts diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md index 53d107bd17..3997a5d03d 100644 --- a/packages/techdocs-common/api-report.md +++ b/packages/techdocs-common/api-report.md @@ -17,36 +17,42 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { UrlReader } from '@backstage/backend-common'; import { Writable } from 'stream'; +// @public +export type DirectoryFactory = { + reader: UrlReader; +}; + // @public export class DirectoryPreparer implements PreparerBase { // @deprecated constructor(config: Config, _logger: Logger_2 | null, reader: UrlReader); - // Warning: (ae-forgotten-export) The symbol "DirectoryPreparerOptions" needs to be exported by the entry point index.d.ts - // - // (undocumented) - static fromConfig(options: DirectoryPreparerOptions): DirectoryPreparer; - // Warning: (ae-forgotten-export) The symbol "PreparerOptions" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "PreparerResponse" needs to be exported by the entry point index.d.ts - // - // (undocumented) + static fromConfig( + config: Config, + options: DirectoryFactory, + ): DirectoryPreparer; prepare(entity: Entity, options?: PreparerOptions): Promise; } -// Warning: (ae-missing-release-tag) "GeneratorBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type ETag = string; + +// @public export type GeneratorBase = { run(opts: GeneratorRunOptions): Promise; }; -// Warning: (ae-missing-release-tag) "GeneratorBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type GeneratorBuilder = { register(protocol: SupportedGeneratorKey, generator: GeneratorBase): void; get(entity: Entity): GeneratorBase; }; +// @public +export type GeneratorFactory = { + containerRunner: ContainerRunner; + logger: Logger_2; +}; + // @public export type GeneratorRunOptions = { inputDir: string; @@ -57,11 +63,8 @@ export type GeneratorRunOptions = { logStream?: Writable; }; -// Warning: (ae-missing-release-tag) "Generators" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export class Generators implements GeneratorBuilder { - // (undocumented) static fromConfig( config: Config, options: { @@ -69,15 +72,11 @@ export class Generators implements GeneratorBuilder { containerRunner: ContainerRunner; }, ): Promise; - // (undocumented) get(entity: Entity): GeneratorBase; - // (undocumented) register(generatorKey: SupportedGeneratorKey, generator: GeneratorBase): void; } -// Warning: (ae-missing-release-tag) "getDocFilesFromRepository" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const getDocFilesFromRepository: ( reader: UrlReader, entity: Entity, @@ -89,78 +88,74 @@ export const getDocFilesFromRepository: ( | undefined, ) => Promise; -// Warning: (ae-missing-release-tag) "getLocationForEntity" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const getLocationForEntity: ( entity: Entity, scmIntegration: ScmIntegrationRegistry, ) => ParsedLocationAnnotation; -// Warning: (ae-missing-release-tag) "ParsedLocationAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type MigrateRequest = { + removeOriginal?: boolean; + concurrency?: number; +}; + +// @public export type ParsedLocationAnnotation = { type: RemoteProtocol; target: string; }; -// Warning: (ae-missing-release-tag) "parseReferenceAnnotation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const parseReferenceAnnotation: ( annotationName: string, entity: Entity, ) => ParsedLocationAnnotation; -// Warning: (ae-missing-release-tag) "PreparerBase" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PreparerBase = { - prepare( - entity: Entity, - options?: { - logger?: Logger_2; - etag?: string; - }, - ): Promise; + prepare(entity: Entity, options?: PreparerOptions): Promise; }; -// Warning: (ae-missing-release-tag) "PreparerBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type PreparerBuilder = { register(protocol: RemoteProtocol, preparer: PreparerBase): void; get(entity: Entity): PreparerBase; }; -// Warning: (ae-missing-release-tag) "Preparers" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type PreparerFactory = { + logger: Logger_2; + reader: UrlReader; +}; + +// @public +export type PreparerOptions = { + logger?: Logger_2; + etag?: ETag; +}; + +// @public +export type PreparerResponse = { + preparedDir: string; + etag: ETag; +}; + +// @public export class Preparers implements PreparerBuilder { - // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts - // - // (undocumented) static fromConfig( config: Config, - { logger, reader }: factoryOptions, + { logger, reader }: PreparerFactory, ): Promise; - // (undocumented) get(entity: Entity): PreparerBase; - // (undocumented) register(protocol: RemoteProtocol, preparer: PreparerBase): void; } -// Warning: (ae-missing-release-tag) "Publisher" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export class Publisher { - // Warning: (ae-forgotten-export) The symbol "factoryOptions" needs to be exported by the entry point index.d.ts - // - // (undocumented) static fromConfig( config: Config, - { logger, discovery }: factoryOptions_2, + { logger, discovery }: PublisherFactory, ): Promise; } @@ -170,15 +165,16 @@ export interface PublisherBase { fetchTechDocsMetadata(entityName: EntityName): Promise; getReadiness(): Promise; hasDocsBeenGenerated(entityName: Entity): Promise; - // Warning: (ae-forgotten-export) The symbol "MigrateRequest" needs to be exported by the entry point index.d.ts migrateDocsCase?(migrateRequest: MigrateRequest): Promise; - // Warning: (ae-forgotten-export) The symbol "PublishRequest" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "PublishResponse" needs to be exported by the entry point index.d.ts publish(request: PublishRequest): Promise; } -// Warning: (ae-missing-release-tag) "PublisherType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public +export type PublisherFactory = { + logger: Logger_2; + discovery: PluginEndpointDiscovery; +}; + // @public export type PublisherType = | 'local' @@ -187,37 +183,40 @@ export type PublisherType = | 'azureBlobStorage' | 'openStackSwift'; +// @public +export type PublishRequest = { + entity: Entity; + directory: string; +}; + +// @public +export type PublishResponse = { + remoteUrl?: string; + objects?: string[]; +} | void; + // @public export type ReadinessResponse = { isAvailable: boolean; }; -// Warning: (ae-missing-release-tag) "RemoteProtocol" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type RemoteProtocol = 'url' | 'dir'; -// Warning: (ae-missing-release-tag) "TechDocsDocument" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type SupportedGeneratorKey = 'techdocs' | string; + +// @public export interface TechDocsDocument extends IndexableDocument { - // (undocumented) kind: string; - // (undocumented) lifecycle: string; - // (undocumented) name: string; - // (undocumented) namespace: string; - // (undocumented) owner: string; - // (undocumented) path: string; } -// Warning: (ae-missing-release-tag) "TechdocsGenerator" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export class TechdocsGenerator implements GeneratorBase { constructor(options: { logger: Logger_2; @@ -226,20 +225,13 @@ export class TechdocsGenerator implements GeneratorBase { scmIntegrations: ScmIntegrationRegistry; }); static readonly defaultDockerImage = 'spotify/techdocs:v0.3.7'; - // (undocumented) static fromConfig( config: Config, - options: { - containerRunner: ContainerRunner; - logger: Logger_2; - }, + options: GeneratorFactory, ): TechdocsGenerator; - // (undocumented) run(options: GeneratorRunOptions): Promise; } -// Warning: (ae-missing-release-tag) "TechDocsMetadata" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export type TechDocsMetadata = { site_name: string; @@ -249,8 +241,6 @@ export type TechDocsMetadata = { files?: string[]; }; -// Warning: (ae-missing-release-tag) "transformDirLocation" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public export const transformDirLocation: ( entity: Entity, @@ -261,12 +251,14 @@ export const transformDirLocation: ( target: string; }; -// Warning: (ae-missing-release-tag) "UrlPreparer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type UrlFactory = PreparerFactory; + +// @public export class UrlPreparer implements PreparerBase { + // @deprecated constructor(reader: UrlReader, logger: Logger_2); - // (undocumented) + static fromConfig(options: UrlFactory): UrlPreparer; prepare( entity: Entity, options?: { @@ -274,8 +266,4 @@ export class UrlPreparer implements PreparerBase { }, ): Promise; } - -// Warnings were encountered during analysis: -// -// src/stages/generate/types.d.ts:45:5 - (ae-forgotten-export) The symbol "SupportedGeneratorKey" needs to be exported by the entry point index.d.ts ``` diff --git a/packages/techdocs-common/config.d.ts b/packages/techdocs-common/config.d.ts deleted file mode 100644 index 54e76c1a1c..0000000000 --- a/packages/techdocs-common/config.d.ts +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2022 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 interface Config { - app: { - baseUrl: string; // defined in core, but repeated here without doc - }; - - backend: { - /** Backend configuration for when request authentication is enabled */ - auth?: { - /** Keys shared by all backends for signing and validating backend tokens. */ - keys: { - /** - * Secret for generating tokens. Should be a base64 string, recommended - * length is 24 bytes. - * - * @visibility secret - */ - secret: string; - }[]; - }; - - baseUrl: string; // defined in core, but repeated here without doc - - /** Address that the backend should listen to. */ - listen: - | string - | { - /** Address of the interface that the backend should bind to. */ - host?: string; - /** Port that the backend should listen to. */ - port?: string | number; - }; - - /** - * HTTPS configuration for the backend. If omitted the backend will serve HTTP. - * - * Setting this to `true` will cause self-signed certificates to be generated, which - * can be useful for local development or other non-production scenarios. - */ - https?: - | true - | { - /** Certificate configuration */ - certificate?: { - /** PEM encoded certificate. Use $file to load in a file */ - cert: string; - /** - * PEM encoded certificate key. Use $file to load in a file. - * @visibility secret - */ - key: string; - }; - }; - - /** Database connection configuration, select base database type using the `client` field */ - database: { - /** Default database client to use */ - client: 'sqlite3' | 'pg'; - /** - * Base database connection string or Knex object - * @secret - */ - connection: string | object; - /** Database name prefix override */ - prefix?: string; - /** - * Whether to ensure the given database exists by creating it if it does not. - * Defaults to true if unspecified. - */ - ensureExists?: boolean; - /** - * How plugins databases are managed/divided in the provided database instance. - * - * `database` -> Plugins are each given their own database to manage their schemas/tables. - * - * `schema` -> Plugins will be given their own schema (in the specified/default database) - * to manage their tables. - * - * NOTE: Currently only supported by the `pg` client. - * - * @default database - */ - pluginDivisionMode?: 'database' | 'schema'; - /** - * Arbitrary config object to pass to knex when initializing - * (https://knexjs.org/#Installation-client). Most notable is the debug - * and asyncStackTraces booleans - */ - knexConfig?: object; - /** Plugin specific database configuration and client override */ - plugin?: { - [pluginId: string]: { - /** Database client override */ - client?: 'sqlite3' | 'pg'; - /** - * Database connection string or Knex object override - * @secret - */ - connection?: string | object; - /** - * Whether to ensure the given database exists by creating it if it does not. - * Defaults to base config if unspecified. - */ - ensureExists?: boolean; - /** - * Arbitrary config object to pass to knex when initializing - * (https://knexjs.org/#Installation-client). Most notable is the - * debug and asyncStackTraces booleans. - * - * This is merged recursively into the base knexConfig - */ - knexConfig?: object; - }; - }; - }; - - /** Cache connection configuration, select cache type using the `store` field */ - cache?: - | { - store: 'memory'; - } - | { - store: 'memcache'; - /** - * A memcache connection string in the form `user:pass@host:port`. - * @secret - */ - connection: string; - }; - - cors?: { - origin?: string | string[]; - methods?: string | string[]; - allowedHeaders?: string | string[]; - exposedHeaders?: string | string[]; - credentials?: boolean; - maxAge?: number; - preflightContinue?: boolean; - optionsSuccessStatus?: number; - }; - - /** - * Configuration related to URL reading, used for example for reading catalog info - * files, scaffolder templates, and techdocs content. - */ - reading?: { - /** - * A list of targets to allow outgoing requests to. Users will be able to make - * requests on behalf of the backend to the targets that are allowed by this list. - */ - allow?: Array<{ - /** - * A host to allow outgoing requests to, being either a full host or - * a subdomain wildcard pattern with a leading `*`. For example `example.com` - * and `*.example.com` are valid values, `prod.*.example.com` is not. - * The host may also contain a port, for example `example.com:8080`. - */ - host: string; - - /** - * An optional list of paths. In case they are present only targets matching - * any of them will are allowed. You can use trailing slashes to make sure only - * subdirectories are allowed, for example `/mydir/` will allow targets with - * paths like `/mydir/a` but will block paths like `/mydir2`. - */ - paths?: string[]; - }>; - }; - - /** - * Content Security Policy options. - * - * The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The - * values are on the format that the helmet library expects them, as an - * array of strings. There is also the special value false, which means to - * remove the default value that Backstage puts in place for that policy. - */ - csp?: { [policyId: string]: string[] | false }; - }; -} From c13f76852145ab60e669b0bb3144955cd72af4e8 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 24 Feb 2022 09:08:23 +0100 Subject: [PATCH 6/7] refactor(techdocs-common): apply review suggestions Signed-off-by: Camila Belo --- packages/techdocs-common/api-report.md | 29 +++++---------- packages/techdocs-common/src/helpers.ts | 8 ++--- .../src/stages/generate/generators.ts | 8 ++--- .../src/stages/generate/index.ts | 2 +- .../src/stages/generate/techdocs.ts | 6 ++-- .../src/stages/generate/types.ts | 2 +- .../techdocs-common/src/stages/prepare/dir.ts | 8 ++--- .../src/stages/prepare/index.ts | 4 +-- .../src/stages/prepare/preparers.ts | 24 +++++++------ .../src/stages/prepare/types.ts | 36 ++++++------------- .../techdocs-common/src/stages/prepare/url.ts | 16 +++++---- .../src/stages/publish/publish.ts | 2 +- .../src/stages/publish/types.ts | 2 +- packages/techdocs-common/src/techdocsTypes.ts | 2 +- 14 files changed, 64 insertions(+), 85 deletions(-) diff --git a/packages/techdocs-common/api-report.md b/packages/techdocs-common/api-report.md index 3997a5d03d..7c4fc95abb 100644 --- a/packages/techdocs-common/api-report.md +++ b/packages/techdocs-common/api-report.md @@ -17,18 +17,13 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; import { UrlReader } from '@backstage/backend-common'; import { Writable } from 'stream'; -// @public -export type DirectoryFactory = { - reader: UrlReader; -}; - // @public export class DirectoryPreparer implements PreparerBase { // @deprecated constructor(config: Config, _logger: Logger_2 | null, reader: UrlReader); static fromConfig( config: Config, - options: DirectoryFactory, + { logger, reader }: PreparerConfig, ): DirectoryPreparer; prepare(entity: Entity, options?: PreparerOptions): Promise; } @@ -48,7 +43,7 @@ export type GeneratorBuilder = { }; // @public -export type GeneratorFactory = { +export type GeneratorOptions = { containerRunner: ContainerRunner; logger: Logger_2; }; @@ -124,7 +119,7 @@ export type PreparerBuilder = { }; // @public -export type PreparerFactory = { +export type PreparerConfig = { logger: Logger_2; reader: UrlReader; }; @@ -144,8 +139,8 @@ export type PreparerResponse = { // @public export class Preparers implements PreparerBuilder { static fromConfig( - config: Config, - { logger, reader }: PreparerFactory, + backstageConfig: Config, + { logger, reader }: PreparerConfig, ): Promise; get(entity: Entity): PreparerBase; register(protocol: RemoteProtocol, preparer: PreparerBase): void; @@ -227,7 +222,7 @@ export class TechdocsGenerator implements GeneratorBase { static readonly defaultDockerImage = 'spotify/techdocs:v0.3.7'; static fromConfig( config: Config, - options: GeneratorFactory, + options: GeneratorOptions, ): TechdocsGenerator; run(options: GeneratorRunOptions): Promise; } @@ -251,19 +246,11 @@ export const transformDirLocation: ( target: string; }; -// @public -export type UrlFactory = PreparerFactory; - // @public export class UrlPreparer implements PreparerBase { // @deprecated constructor(reader: UrlReader, logger: Logger_2); - static fromConfig(options: UrlFactory): UrlPreparer; - prepare( - entity: Entity, - options?: { - etag?: string; - }, - ): Promise; + static fromConfig({ reader, logger }: PreparerConfig): UrlPreparer; + prepare(entity: Entity, options?: PreparerOptions): Promise; } ``` diff --git a/packages/techdocs-common/src/helpers.ts b/packages/techdocs-common/src/helpers.ts index 9075660c0e..39a1f4c666 100644 --- a/packages/techdocs-common/src/helpers.ts +++ b/packages/techdocs-common/src/helpers.ts @@ -39,7 +39,7 @@ export type ParsedLocationAnnotation = { * Returns a parset locations annotation * @public * @param annotationName - The name of the annotation in the entity metadata - * @param entity - A Tech Docs entity instance + * @param entity - A TechDocs entity instance */ export const parseReferenceAnnotation = ( annotationName: string, @@ -112,9 +112,9 @@ export const transformDirLocation = ( }; /** - * Returns a entity reference based on the Tech Docs annotation type + * Returns a entity reference based on the TechDocs annotation type * @public - * @param entity - A Tech Docs instance + * @param entity - A TechDocs instance * @param scmIntegration - An implementation for SCM integration API */ export const getLocationForEntity = ( @@ -140,7 +140,7 @@ export const getLocationForEntity = ( * Returns a preparer response {@link PreparerResponse} * @public * @param reader - Read a tree of files from a repository - * @param entity - A Tech Docs entity instance + * @param entity - A TechDocs entity instance * @param opts - Options for configuring the reader, e.g. logger, etag, etc. */ export const getDocFilesFromRepository = async ( diff --git a/packages/techdocs-common/src/stages/generate/generators.ts b/packages/techdocs-common/src/stages/generate/generators.ts index 22d07a49b9..630fccfa44 100644 --- a/packages/techdocs-common/src/stages/generate/generators.ts +++ b/packages/techdocs-common/src/stages/generate/generators.ts @@ -34,9 +34,9 @@ export class Generators implements GeneratorBuilder { private generatorMap = new Map(); /** - * Returns a generators instance containing a generator for Tech Docs + * Returns a generators instance containing a generator for TechDocs * @param config - A Backstage configuration - * @param options - Options to configure the Tech Docs generator + * @param options - Options to configure the TechDocs generator */ static async fromConfig( config: Config, @@ -60,8 +60,8 @@ export class Generators implements GeneratorBuilder { } /** - * Returns the generator for a given Tech Docs entity - * @param entity - A Tech Docs entity instance + * Returns the generator for a given TechDocs entity + * @param entity - A TechDocs entity instance */ get(entity: Entity): GeneratorBase { const generatorKey = getGeneratorKey(entity); diff --git a/packages/techdocs-common/src/stages/generate/index.ts b/packages/techdocs-common/src/stages/generate/index.ts index 5b442be1ae..1c20c58887 100644 --- a/packages/techdocs-common/src/stages/generate/index.ts +++ b/packages/techdocs-common/src/stages/generate/index.ts @@ -17,8 +17,8 @@ export { TechdocsGenerator } from './techdocs'; export { Generators } from './generators'; export type { GeneratorBase, + GeneratorOptions, GeneratorBuilder, - GeneratorFactory, GeneratorRunOptions, SupportedGeneratorKey, } from './types'; diff --git a/packages/techdocs-common/src/stages/generate/techdocs.ts b/packages/techdocs-common/src/stages/generate/techdocs.ts index c6a170910d..baa2e008a1 100644 --- a/packages/techdocs-common/src/stages/generate/techdocs.ts +++ b/packages/techdocs-common/src/stages/generate/techdocs.ts @@ -34,11 +34,11 @@ import { import { GeneratorBase, GeneratorConfig, + GeneratorOptions, GeneratorRunInType, GeneratorRunOptions, } from './types'; import { ForwardedError } from '@backstage/errors'; -import { GeneratorFactory } from './types'; /** * Generates documentation files @@ -56,11 +56,11 @@ export class TechdocsGenerator implements GeneratorBase { private readonly scmIntegrations: ScmIntegrationRegistry; /** - * Returns a instance of Tech Docs generator + * Returns a instance of TechDocs generator * @param config - A Backstage configuration * @param options - Options to configure the generator */ - static fromConfig(config: Config, options: GeneratorFactory) { + static fromConfig(config: Config, options: GeneratorOptions) { const { containerRunner, logger } = options; const scmIntegrations = ScmIntegrations.fromConfig(config); return new TechdocsGenerator({ diff --git a/packages/techdocs-common/src/stages/generate/types.ts b/packages/techdocs-common/src/stages/generate/types.ts index 4903d886f1..2ff3064991 100644 --- a/packages/techdocs-common/src/stages/generate/types.ts +++ b/packages/techdocs-common/src/stages/generate/types.ts @@ -27,7 +27,7 @@ export type GeneratorRunInType = 'docker' | 'local'; * Options for building generators * @public */ -export type GeneratorFactory = { +export type GeneratorOptions = { containerRunner: ContainerRunner; logger: Logger; }; diff --git a/packages/techdocs-common/src/stages/prepare/dir.ts b/packages/techdocs-common/src/stages/prepare/dir.ts index 0b43a459de..42bfa5b903 100644 --- a/packages/techdocs-common/src/stages/prepare/dir.ts +++ b/packages/techdocs-common/src/stages/prepare/dir.ts @@ -26,9 +26,9 @@ import { Logger } from 'winston'; import { parseReferenceAnnotation, transformDirLocation } from '../../helpers'; import { PreparerBase, + PreparerConfig, PreparerOptions, PreparerResponse, - DirectoryFactory, } from './types'; /** @@ -48,13 +48,13 @@ export class DirectoryPreparer implements PreparerBase { /** * Returns a directory preparer instance * @param config - A backstage config - * @param options - A directory preparer options containing the URL reader + * @param options - A directory preparer options containing a logger and reader */ static fromConfig( config: Config, - options: DirectoryFactory, + { logger, reader }: PreparerConfig, ): DirectoryPreparer { - return new DirectoryPreparer(config, null, options.reader); + return new DirectoryPreparer(config, logger, reader); } /** {@inheritDoc PreparerBase.prepare} */ diff --git a/packages/techdocs-common/src/stages/prepare/index.ts b/packages/techdocs-common/src/stages/prepare/index.ts index c78e1082e2..3593b49c86 100644 --- a/packages/techdocs-common/src/stages/prepare/index.ts +++ b/packages/techdocs-common/src/stages/prepare/index.ts @@ -19,11 +19,9 @@ export { Preparers } from './preparers'; export type { PreparerBase, PreparerBuilder, - PreparerFactory, + PreparerConfig, PreparerOptions, PreparerResponse, - DirectoryFactory, - UrlFactory, RemoteProtocol, ETag, } from './types'; diff --git a/packages/techdocs-common/src/stages/prepare/preparers.ts b/packages/techdocs-common/src/stages/prepare/preparers.ts index 90207c1a1a..575294e91a 100644 --- a/packages/techdocs-common/src/stages/prepare/preparers.ts +++ b/packages/techdocs-common/src/stages/prepare/preparers.ts @@ -21,26 +21,26 @@ import { UrlPreparer } from './url'; import { PreparerBase, PreparerBuilder, - PreparerFactory, + PreparerConfig, RemoteProtocol, } from './types'; /** - * Collection of docs preparers + * Collection of docs preparers (dir and url) * @public */ export class Preparers implements PreparerBuilder { private preparerMap = new Map(); /** - * Returns a generators instance containing a generator for Tech Docs + * Returns a generators instance containing a generator for TechDocs * @public - * @param config - A Backstage configuration - * @param options - Options to configure the URL preparer + * @param backstageConfig - A Backstage configuration + * @param preparerConfig - Options to configure preparers */ static async fromConfig( - config: Config, - { logger, reader }: PreparerFactory, + backstageConfig: Config, + { logger, reader }: PreparerConfig, ): Promise { const preparers = new Preparers(); @@ -51,7 +51,11 @@ export class Preparers implements PreparerBuilder { * Dir preparer is a syntactic sugar for users to define techdocs-ref annotation. * When using dir preparer, the docs will be fetched using URL Reader. */ - const directoryPreparer = new DirectoryPreparer(config, logger, reader); + const directoryPreparer = new DirectoryPreparer( + backstageConfig, + logger, + reader, + ); preparers.register('dir', directoryPreparer); return preparers; @@ -67,8 +71,8 @@ export class Preparers implements PreparerBuilder { } /** - * Returns the preparer for a given Tech Docs entity - * @param entity - A Tech Docs entity instance + * Returns the preparer for a given TechDocs entity + * @param entity - A TechDocs entity instance * @returns */ get(entity: Entity): PreparerBase { diff --git a/packages/techdocs-common/src/stages/prepare/types.ts b/packages/techdocs-common/src/stages/prepare/types.ts index ed3d20c2dd..aee9d216ab 100644 --- a/packages/techdocs-common/src/stages/prepare/types.ts +++ b/packages/techdocs-common/src/stages/prepare/types.ts @@ -18,35 +18,21 @@ import type { Entity } from '@backstage/catalog-model'; import { UrlReader } from '@backstage/backend-common'; import { Logger } from 'winston'; -/** - * Options for building preparers - * @public - */ -export type PreparerFactory = { - logger: Logger; - reader: UrlReader; -}; - -/** - * Options to configure a directory preparer. - * @public - */ -export type DirectoryFactory = { - reader: UrlReader; -}; - -/** - * Options to configure a url preparer. - * @public - */ -export type UrlFactory = PreparerFactory; - /** * A unique identifier of the tree blob, usually the commit SHA or etag from the target. * @public */ export type ETag = string; +/** + * Options for building preparers + * @public + */ +export type PreparerConfig = { + logger: Logger; + reader: UrlReader; +}; + /** * Options for configuring the content preparation process. * @public @@ -78,7 +64,7 @@ export type PreparerResponse = { }; /** - * Definition of a Tech Docs preparer + * Definition of a TechDocs preparer * @public */ export type PreparerBase = { @@ -95,7 +81,7 @@ export type PreparerBase = { }; /** - * Definition for a Tech Docs preparer builder + * Definition for a TechDocs preparer builder * @public */ export type PreparerBuilder = { diff --git a/packages/techdocs-common/src/stages/prepare/url.ts b/packages/techdocs-common/src/stages/prepare/url.ts index 75f10b64d5..8026dca41e 100644 --- a/packages/techdocs-common/src/stages/prepare/url.ts +++ b/packages/techdocs-common/src/stages/prepare/url.ts @@ -19,7 +19,12 @@ import { UrlReader } from '@backstage/backend-common'; import { Entity } from '@backstage/catalog-model'; import { Logger } from 'winston'; import { getDocFilesFromRepository } from '../../helpers'; -import { PreparerBase, PreparerResponse, UrlFactory } from './types'; +import { + PreparerBase, + PreparerConfig, + PreparerOptions, + PreparerResponse, +} from './types'; /** * Preparer used to retrieve documentation files from a remote repository @@ -37,17 +42,16 @@ export class UrlPreparer implements PreparerBase { /** * Returns a directory preparer instance - * @param config - A backstage config - * @param options - A directory preparer options containing the URL reader + * @param config - A URL preparer config containing the a logger and reader */ - static fromConfig(options: UrlFactory): UrlPreparer { - return new UrlPreparer(options.reader, options.logger); + static fromConfig({ reader, logger }: PreparerConfig): UrlPreparer { + return new UrlPreparer(reader, logger); } /** {@inheritDoc PreparerBase.prepare} */ async prepare( entity: Entity, - options?: { etag?: string }, + options?: PreparerOptions, ): Promise { try { return await getDocFilesFromRepository(this.reader, entity, { diff --git a/packages/techdocs-common/src/stages/publish/publish.ts b/packages/techdocs-common/src/stages/publish/publish.ts index b9ea4c7cb4..bc7f50b5a3 100644 --- a/packages/techdocs-common/src/stages/publish/publish.ts +++ b/packages/techdocs-common/src/stages/publish/publish.ts @@ -29,7 +29,7 @@ import { PublisherFactory, PublisherBase, PublisherType } from './types'; */ export class Publisher { /** - * Returns a instance of Tech Docs publisher + * Returns a instance of TechDocs publisher * @param config - A Backstage configuration * @param options - Options for configuring the publisher factory */ diff --git a/packages/techdocs-common/src/stages/publish/types.ts b/packages/techdocs-common/src/stages/publish/types.ts index 0c3c047b40..c6ad032484 100644 --- a/packages/techdocs-common/src/stages/publish/types.ts +++ b/packages/techdocs-common/src/stages/publish/types.ts @@ -89,7 +89,7 @@ export type TechDocsMetadata = { }; /** - * Tech Docs entity triplet migration request + * TechDocs entity triplet migration request * @public */ export type MigrateRequest = { diff --git a/packages/techdocs-common/src/techdocsTypes.ts b/packages/techdocs-common/src/techdocsTypes.ts index 69f7b36e9f..0b722f4da5 100644 --- a/packages/techdocs-common/src/techdocsTypes.ts +++ b/packages/techdocs-common/src/techdocsTypes.ts @@ -17,7 +17,7 @@ import { IndexableDocument } from '@backstage/search-common'; /** - * Tech Docs indexable document interface + * TechDocs indexable document interface * @public */ export interface TechDocsDocument extends IndexableDocument { From 13ef228d0338d9289d58b1157282138744cfa822 Mon Sep 17 00:00:00 2001 From: Camila Belo Date: Thu, 24 Feb 2022 09:50:59 +0100 Subject: [PATCH 7/7] chore(techdocs-common): add changeset file Signed-off-by: Camila Belo --- .changeset/techdocs-hornets-turn.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/techdocs-hornets-turn.md diff --git a/.changeset/techdocs-hornets-turn.md b/.changeset/techdocs-hornets-turn.md new file mode 100644 index 0000000000..d838ca5ba2 --- /dev/null +++ b/.changeset/techdocs-hornets-turn.md @@ -0,0 +1,5 @@ +--- +'@backstage/techdocs-common': patch +--- + +Clean up the API interface for TechDocs common library.