Merge branch 'master' into mobile-sidebar
This commit is contained in:
@@ -34,9 +34,7 @@ import { Server } from 'http';
|
||||
import * as winston from 'winston';
|
||||
import { Writable } from 'stream';
|
||||
|
||||
// Warning: (ae-missing-release-tag) "AwsS3UrlReader" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export class AwsS3UrlReader implements UrlReader {
|
||||
constructor(
|
||||
integration: AwsS3Integration,
|
||||
@@ -59,7 +57,7 @@ export class AwsS3UrlReader implements UrlReader {
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export class AzureUrlReader implements UrlReader {
|
||||
constructor(
|
||||
integration: AzureIntegration,
|
||||
@@ -114,12 +112,12 @@ export interface CacheClient {
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type CacheClientOptions = {
|
||||
defaultTtl?: number;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type CacheClientSetOptions = {
|
||||
ttl?: number;
|
||||
};
|
||||
@@ -133,18 +131,17 @@ export class CacheManager {
|
||||
): CacheManager;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type CacheManagerOptions = {
|
||||
logger?: Logger_2;
|
||||
onError?: (err: Error) => void;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export const coloredFormat: winston.Logform.Format;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface ContainerRunner {
|
||||
// (undocumented)
|
||||
runContainer(opts: RunContainerOptions): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -157,7 +154,7 @@ export function createDatabaseClient(
|
||||
overrides?: Partial<Knex.Config>,
|
||||
): Knex<any, unknown[]>;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export function createRootLogger(
|
||||
options?: winston.LoggerOptions,
|
||||
env?: NodeJS.ProcessEnv,
|
||||
@@ -166,14 +163,14 @@ export function createRootLogger(
|
||||
// @public
|
||||
export function createServiceBuilder(_module: NodeModule): ServiceBuilder;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export function createStatusCheckRouter(options: {
|
||||
logger: Logger_2;
|
||||
path?: string;
|
||||
statusCheck?: StatusCheck;
|
||||
}): Promise<express.Router>;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export class DatabaseManager {
|
||||
forPlugin(pluginId: string): PluginDatabaseManager;
|
||||
static fromConfig(
|
||||
@@ -187,7 +184,7 @@ export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export class DockerContainerRunner implements ContainerRunner {
|
||||
constructor(options: { dockerClient: Docker });
|
||||
// (undocumented)
|
||||
@@ -205,7 +202,7 @@ export function errorHandler(
|
||||
options?: ErrorHandlerOptions,
|
||||
): ErrorRequestHandler;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type ErrorHandlerOptions = {
|
||||
showStackTraces?: boolean;
|
||||
logger?: Logger_2;
|
||||
@@ -218,13 +215,13 @@ export type FromReadableArrayOptions = Array<{
|
||||
path: string;
|
||||
}>;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export function getRootLogger(): winston.Logger;
|
||||
|
||||
// @public
|
||||
export function getVoidLogger(): winston.Logger;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export class Git {
|
||||
// (undocumented)
|
||||
add(options: { dir: string; filepath: string }): Promise<void>;
|
||||
@@ -310,7 +307,7 @@ export class GithubUrlReader implements UrlReader {
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export class GitlabUrlReader implements UrlReader {
|
||||
constructor(
|
||||
integration: GitLabIntegration,
|
||||
@@ -398,7 +395,7 @@ export type ReadTreeResponseDirOptions = {
|
||||
targetDir?: string;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface ReadTreeResponseFactory {
|
||||
// (undocumented)
|
||||
fromReadableArray(
|
||||
@@ -448,7 +445,7 @@ export type ReadUrlResponse = {
|
||||
// @public
|
||||
export function requestLoggingHandler(logger?: Logger_2): RequestHandler;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type RequestLoggingHandlerFactory = (
|
||||
logger?: Logger_2,
|
||||
) => RequestHandler;
|
||||
@@ -459,7 +456,7 @@ export function resolvePackagePath(name: string, ...paths: string[]): string;
|
||||
// @public
|
||||
export function resolveSafeChildPath(base: string, path: string): string;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type RunContainerOptions = {
|
||||
imageName: string;
|
||||
command?: string | string[];
|
||||
@@ -508,7 +505,7 @@ export class ServerTokenManager implements TokenManager {
|
||||
static noop(): TokenManager;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type ServiceBuilder = {
|
||||
loadConfig(config: Config): ServiceBuilder;
|
||||
setPort(port: number): ServiceBuilder;
|
||||
@@ -534,7 +531,7 @@ export type ServiceBuilder = {
|
||||
start(): Promise<Server>;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export function setRootLogger(newLogger: winston.Logger): void;
|
||||
|
||||
// @public @deprecated
|
||||
@@ -554,7 +551,7 @@ export class SingleHostDiscovery implements PluginEndpointDiscovery {
|
||||
getExternalBaseUrl(pluginId: string): Promise<string>;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type StatusCheck = () => Promise<any>;
|
||||
|
||||
// @public
|
||||
@@ -562,7 +559,7 @@ export function statusCheckHandler(
|
||||
options?: StatusCheckHandlerOptions,
|
||||
): Promise<RequestHandler>;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface StatusCheckHandlerOptions {
|
||||
statusCheck?: StatusCheck;
|
||||
}
|
||||
@@ -597,7 +594,7 @@ export class UrlReaders {
|
||||
static default(options: UrlReadersOptions): UrlReader;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type UrlReadersOptions = {
|
||||
config: Config;
|
||||
logger: Logger_2;
|
||||
@@ -612,8 +609,4 @@ export function useHotCleanup(
|
||||
|
||||
// @public
|
||||
export function useHotMemoize<T>(_module: NodeModule, valueFactory: () => T): T;
|
||||
|
||||
// Warnings were encountered during analysis:
|
||||
//
|
||||
// src/database/types.d.ts:23:12 - (tsdoc-undefined-tag) The TSDoc tag "@default" is not defined in this configuration
|
||||
```
|
||||
|
||||
+5
-1
@@ -22,7 +22,11 @@ type CacheClientArgs = {
|
||||
client: Keyv;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Options passed to {@link CacheClient.set}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CacheClientSetOptions = {
|
||||
/**
|
||||
* Optional TTL in milliseconds. Defaults to the TTL provided when the client
|
||||
|
||||
+4
-3
@@ -55,8 +55,8 @@ export class CacheManager {
|
||||
private readonly errorHandler: CacheManagerOptions['onError'];
|
||||
|
||||
/**
|
||||
* Creates a new CacheManager instance by reading from the `backend` config
|
||||
* section, specifically the `.cache` key.
|
||||
* Creates a new {@link CacheManager} instance by reading from the `backend`
|
||||
* config section, specifically the `.cache` key.
|
||||
*
|
||||
* @param config - The loaded application configuration.
|
||||
*/
|
||||
@@ -93,7 +93,8 @@ export class CacheManager {
|
||||
/**
|
||||
* Generates a PluginCacheManager for consumption by plugins.
|
||||
*
|
||||
* @param pluginId - The plugin that the cache manager should be created for. Plugin names should be unique.
|
||||
* @param pluginId - The plugin that the cache manager should be created for.
|
||||
* Plugin names should be unique.
|
||||
*/
|
||||
forPlugin(pluginId: string): PluginCacheManager {
|
||||
return {
|
||||
|
||||
+17
-7
@@ -17,7 +17,11 @@
|
||||
import { Logger } from 'winston';
|
||||
import { CacheClient } from './CacheClient';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Options given when constructing a {@link CacheClient}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CacheClientOptions = {
|
||||
/**
|
||||
* An optional default TTL (in milliseconds) to be set when getting a client
|
||||
@@ -27,7 +31,11 @@ export type CacheClientOptions = {
|
||||
defaultTtl?: number;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Options given when constructing a {@link CacheManager}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CacheManagerOptions = {
|
||||
/**
|
||||
* An optional logger for use by the PluginCacheManager.
|
||||
@@ -42,17 +50,19 @@ export type CacheManagerOptions = {
|
||||
};
|
||||
|
||||
/**
|
||||
* The PluginCacheManager manages access to cache stores that Plugins get.
|
||||
* Manages access to cache stores that plugins get.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type PluginCacheManager = {
|
||||
/**
|
||||
* getClient provides backend plugins cache connections for itself.
|
||||
* Provides backend plugins cache connections for themselves.
|
||||
*
|
||||
* The purpose of this method is to allow plugins to get isolated data
|
||||
* stores so that plugins are discouraged from cache-level integration
|
||||
* and/or cache key collisions.
|
||||
* @remarks
|
||||
*
|
||||
* The purpose of this method is to allow plugins to get isolated data stores
|
||||
* so that plugins are discouraged from cache-level integration and/or cache
|
||||
* key collisions.
|
||||
*/
|
||||
getClient: (options?: CacheClientOptions) => CacheClient;
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ function pluginPath(pluginId: string): string {
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration options object.
|
||||
* Creation options for {@link DatabaseManager}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
@@ -46,15 +46,20 @@ export type DatabaseManagerOptions = {
|
||||
migrations?: PluginDatabaseManager['migrations'];
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Manages database connections for Backstage backend plugins.
|
||||
*
|
||||
* The database manager allows the user to set connection and client settings on
|
||||
* a per pluginId basis by defining a database config block under
|
||||
* `plugin.<pluginId>` in addition to top level defaults. Optionally, a user may
|
||||
* set `prefix` which is used to prefix generated database names if config is
|
||||
* not provided.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class DatabaseManager {
|
||||
/**
|
||||
* Creates a DatabaseManager from `backend.database` config.
|
||||
*
|
||||
* The database manager allows the user to set connection and client settings on a per pluginId
|
||||
* basis by defining a database config block under `plugin.<pluginId>` in addition to top level
|
||||
* defaults. Optionally, a user may set `prefix` which is used to prefix generated database
|
||||
* names if config is not provided.
|
||||
* Creates a {@link DatabaseManager} from `backend.database` config.
|
||||
*
|
||||
* @param config - The loaded application configuration.
|
||||
* @param options - An optional configuration object.
|
||||
@@ -108,7 +113,7 @@ export class DatabaseManager {
|
||||
* which is the pluginId prefixed with 'backstage_plugin_'. If `pluginDivisionMode` is
|
||||
* `schema`, it will fallback to using the default database for the knex instance.
|
||||
*
|
||||
* @param pluginId Lookup the database name for given plugin
|
||||
* @param pluginId - Lookup the database name for given plugin
|
||||
* @returns String representing the plugin's database name
|
||||
*/
|
||||
private getDatabaseName(pluginId: string): string | undefined {
|
||||
@@ -143,12 +148,13 @@ export class DatabaseManager {
|
||||
/**
|
||||
* Provides the client type which should be used for a given plugin.
|
||||
*
|
||||
* The client type is determined by plugin specific config if present. Otherwise the base
|
||||
* client is used as the fallback.
|
||||
* The client type is determined by plugin specific config if present.
|
||||
* Otherwise the base client is used as the fallback.
|
||||
*
|
||||
* @param pluginId Plugin to get the client type for
|
||||
* @returns Object with client type returned as `client` and boolean representing whether
|
||||
* or not the client was overridden as `overridden`
|
||||
* @param pluginId - Plugin to get the client type for
|
||||
* @returns Object with client type returned as `client` and boolean
|
||||
* representing whether or not the client was overridden as
|
||||
* `overridden`
|
||||
*/
|
||||
private getClientType(pluginId: string): {
|
||||
client: string;
|
||||
@@ -169,8 +175,8 @@ export class DatabaseManager {
|
||||
/**
|
||||
* Provides the knexConfig which should be used for a given plugin.
|
||||
*
|
||||
* @param pluginId Plugin to get the knexConfig for
|
||||
* @returns the merged kexConfig value or undefined if it isn't specified
|
||||
* @param pluginId - Plugin to get the knexConfig for
|
||||
* @returns The merged knexConfig value or undefined if it isn't specified
|
||||
*/
|
||||
private getAdditionalKnexConfig(pluginId: string): JsonObject | undefined {
|
||||
const pluginConfig = this.config
|
||||
@@ -197,13 +203,15 @@ export class DatabaseManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a Knex connection plugin config by combining base and plugin config.
|
||||
* Provides a Knex connection plugin config by combining base and plugin
|
||||
* config.
|
||||
*
|
||||
* This method provides a baseConfig for a plugin database connector. If the client type
|
||||
* has not been overridden, the global connection config will be included with plugin
|
||||
* specific config as the base. Values from the plugin connection take precedence over the
|
||||
* base. Base database name is omitted for all supported databases excluding SQLite unless
|
||||
* `pluginDivisionMode` is set to `schema`.
|
||||
* This method provides a baseConfig for a plugin database connector. If the
|
||||
* client type has not been overridden, the global connection config will be
|
||||
* included with plugin specific config as the base. Values from the plugin
|
||||
* connection take precedence over the base. Base database name is omitted for
|
||||
* all supported databases excluding SQLite unless `pluginDivisionMode` is set
|
||||
* to `schema`.
|
||||
*/
|
||||
private getConnectionConfig(
|
||||
pluginId: string,
|
||||
@@ -249,9 +257,10 @@ export class DatabaseManager {
|
||||
/**
|
||||
* Provides a Knex database config for a given plugin.
|
||||
*
|
||||
* This method provides a Knex configuration object along with the plugin's client type.
|
||||
* This method provides a Knex configuration object along with the plugin's
|
||||
* client type.
|
||||
*
|
||||
* @param pluginId The plugin that the database config should correspond with
|
||||
* @param pluginId - The plugin that the database config should correspond with
|
||||
*/
|
||||
private getConfigForPlugin(pluginId: string): Knex.Config {
|
||||
const { client } = this.getClientType(pluginId);
|
||||
@@ -264,20 +273,21 @@ export class DatabaseManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a partial Knex.Config database schema override for a given plugin.
|
||||
* Provides a partial `Knex.Config` database schema override for a given
|
||||
* plugin.
|
||||
*
|
||||
* @param pluginId Target plugin to get database schema override
|
||||
* @returns Partial Knex.Config with database schema override
|
||||
* @param pluginId - Target plugin to get database schema override
|
||||
* @returns Partial `Knex.Config` with database schema override
|
||||
*/
|
||||
private getSchemaOverrides(pluginId: string): Knex.Config | undefined {
|
||||
return createSchemaOverride(this.getClientType(pluginId).client, pluginId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a partial Knex.Config database name override for a given plugin.
|
||||
* Provides a partial `Knex.Config`• database name override for a given plugin.
|
||||
*
|
||||
* @param pluginId Target plugin to get database name override
|
||||
* @returns Partial Knex.Config with database name override
|
||||
* @param pluginId - Target plugin to get database name override
|
||||
* @returns Partial `Knex.Config` with database name override
|
||||
*/
|
||||
private getDatabaseOverrides(pluginId: string): Knex.Config {
|
||||
const databaseName = this.getDatabaseName(pluginId);
|
||||
@@ -289,8 +299,9 @@ export class DatabaseManager {
|
||||
/**
|
||||
* Provides a scoped Knex client for a plugin as per application config.
|
||||
*
|
||||
* @param pluginId Plugin to get a Knex client for
|
||||
* @returns Promise which resolves to a scoped Knex database client for a plugin
|
||||
* @param pluginId - Plugin to get a Knex client for
|
||||
* @returns Promise which resolves to a scoped Knex database client for a
|
||||
* plugin
|
||||
*/
|
||||
private async getDatabase(pluginId: string): Promise<Knex> {
|
||||
const pluginConfig = new ConfigReader(
|
||||
|
||||
@@ -58,7 +58,7 @@ export function createDatabaseClient(
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for createDatabaseClient
|
||||
* Alias for {@link createDatabaseClient}
|
||||
*
|
||||
* @public
|
||||
* @deprecated Use createDatabaseClient instead
|
||||
@@ -100,7 +100,8 @@ export async function ensureSchemaExists(
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a Knex.Config object with the provided database name for a given client.
|
||||
* Provides a `Knex.Config` object with the provided database name for a given
|
||||
* client.
|
||||
*/
|
||||
export function createNameOverride(
|
||||
client: string,
|
||||
@@ -117,7 +118,8 @@ export function createNameOverride(
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a Knex.Config object with the provided database schema for a given client. Currently only supported by `pg`.
|
||||
* Provides a `Knex.Config` object with the provided database schema for a given
|
||||
* client. Currently only supported by `pg`.
|
||||
*/
|
||||
export function createSchemaOverride(
|
||||
client: string,
|
||||
@@ -156,7 +158,8 @@ export function parseConnectionString(
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a connection config or string into an object which can be passed to Knex.
|
||||
* Normalizes a connection config or string into an object which can be passed
|
||||
* to Knex.
|
||||
*/
|
||||
export function normalizeConnection(
|
||||
connection: Knex.StaticConnectionConfig | JsonObject | string | undefined,
|
||||
|
||||
@@ -38,7 +38,7 @@ export interface PluginDatabaseManager {
|
||||
/**
|
||||
* skip database migrations. Useful if connecting to a read-only database.
|
||||
*
|
||||
* @default false
|
||||
* @defaultValue false
|
||||
*/
|
||||
skip?: boolean;
|
||||
};
|
||||
|
||||
@@ -31,7 +31,11 @@ const coloredTemplate = (info: TransformableInfo) => {
|
||||
return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A logging format that adds coloring to console output.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const coloredFormat = winston.format.combine(
|
||||
winston.format.timestamp(),
|
||||
winston.format.colorize({
|
||||
|
||||
@@ -23,12 +23,29 @@ import { escapeRegExp } from '../util/escapeRegExp';
|
||||
let rootLogger: winston.Logger;
|
||||
let redactionRegExp: RegExp | undefined;
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Gets the current root logger.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function getRootLogger(): winston.Logger {
|
||||
return rootLogger;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Sets a completely custom default "root" logger.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This is the logger instance that will be the foundation for all other logger
|
||||
* instances passed to plugins etc, in a given backend.
|
||||
*
|
||||
* Only use this if you absolutely need to make a completely custom logger.
|
||||
* Normally if you want to make light adaptations to the default logger
|
||||
* behavior, you would instead call {@link createRootLogger}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function setRootLogger(newLogger: winston.Logger) {
|
||||
rootLogger = newLogger;
|
||||
}
|
||||
@@ -67,7 +84,17 @@ function redactLogLine(info: winston.Logform.TransformableInfo) {
|
||||
return info;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Creates a default "root" logger. This also calls {@link setRootLogger} under
|
||||
* the hood.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This is the logger instance that will be the foundation for all other logger
|
||||
* instances passed to plugins etc, in a given backend.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export function createRootLogger(
|
||||
options: winston.LoggerOptions = {},
|
||||
env = process.env,
|
||||
|
||||
@@ -28,7 +28,11 @@ import { ErrorRequestHandler, NextFunction, Request, Response } from 'express';
|
||||
import { Logger } from 'winston';
|
||||
import { getRootLogger } from '../logging';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Options passed to the {@link errorHandler} middleware.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ErrorHandlerOptions = {
|
||||
/**
|
||||
* Whether error response bodies should show error stack traces or not.
|
||||
|
||||
@@ -16,10 +16,19 @@
|
||||
|
||||
import { NextFunction, Request, Response, RequestHandler } from 'express';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A custom status checking function, passed to {@link statusCheckHandler} and
|
||||
* {@link createStatusCheckRouter}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type StatusCheck = () => Promise<any>;
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Options passed to {@link statusCheckHandler}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface StatusCheckHandlerOptions {
|
||||
/**
|
||||
* Optional status function which returns a message.
|
||||
|
||||
@@ -94,6 +94,11 @@ const parseURL = (
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements a {@link UrlReader} for AWS S3 buckets.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class AwsS3UrlReader implements UrlReader {
|
||||
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
@@ -38,7 +38,11 @@ import {
|
||||
ReadUrlResponse,
|
||||
} from './types';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Implements a {@link UrlReader} for Azure repos.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class AzureUrlReader implements UrlReader {
|
||||
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
@@ -41,8 +41,8 @@ import {
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* A processor that adds the ability to read files from Bitbucket v1 and v2 APIs, such as
|
||||
* the one exposed by Bitbucket Cloud itself.
|
||||
* Implements a {@link UrlReader} for files from Bitbucket v1 and v2 APIs, such
|
||||
* as the one exposed by Bitbucket Cloud itself.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
|
||||
@@ -27,7 +27,7 @@ import {
|
||||
import path from 'path';
|
||||
|
||||
/**
|
||||
* A UrlReader that does a plain fetch of the URL.
|
||||
* A {@link UrlReader} that does a plain fetch of the URL.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
|
||||
@@ -50,7 +50,7 @@ export type GhBlobResponse =
|
||||
RestEndpointMethodTypes['git']['getBlob']['response']['data'];
|
||||
|
||||
/**
|
||||
* A processor that adds the ability to read files from GitHub v3 APIs, such as
|
||||
* Implements a {@link UrlReader} for files through the GitHub v3 APIs, such as
|
||||
* the one exposed by GitHub itself.
|
||||
*
|
||||
* @public
|
||||
|
||||
@@ -39,7 +39,11 @@ import {
|
||||
} from './types';
|
||||
import { trimEnd } from 'lodash';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Implements a {@link UrlReader} for files on GitLab.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class GitlabUrlReader implements UrlReader {
|
||||
static factory: ReaderFactory = ({ config, treeResponseFactory }) => {
|
||||
const integrations = ScmIntegrations.fromConfig(config);
|
||||
|
||||
@@ -48,7 +48,11 @@ const parseURL = (
|
||||
};
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Implements a {@link UrlReader} for files on Google GCS.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class GoogleGcsUrlReader implements UrlReader {
|
||||
static factory: ReaderFactory = ({ config, logger }) => {
|
||||
if (!config.has('integrations.googleGcs')) {
|
||||
|
||||
@@ -27,7 +27,11 @@ import { FetchUrlReader } from './FetchUrlReader';
|
||||
import { GoogleGcsUrlReader } from './GoogleGcsUrlReader';
|
||||
import { AwsS3UrlReader } from './AwsS3UrlReader';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Creation options for {@link UrlReaders}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type UrlReadersOptions = {
|
||||
/** Root config object */
|
||||
config: Config;
|
||||
@@ -38,13 +42,13 @@ export type UrlReadersOptions = {
|
||||
};
|
||||
|
||||
/**
|
||||
* UrlReaders provide various utilities related to the UrlReader interface.
|
||||
* Helps construct {@link UrlReader}s.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class UrlReaders {
|
||||
/**
|
||||
* Creates a UrlReader without any known types.
|
||||
* Creates a custom {@link UrlReader} wrapper for your own set of factories.
|
||||
*/
|
||||
static create(options: UrlReadersOptions): UrlReader {
|
||||
const { logger, config, factories } = options;
|
||||
@@ -65,7 +69,8 @@ export class UrlReaders {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a UrlReader that includes all the default factories from this package.
|
||||
* Creates a {@link UrlReader} wrapper that includes all the default factories
|
||||
* from this package.
|
||||
*
|
||||
* Any additional factories passed will be loaded before the default ones.
|
||||
*/
|
||||
|
||||
@@ -281,7 +281,12 @@ export type FromReadableArrayOptions = Array<{
|
||||
path: string;
|
||||
}>;
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A factory for response factories that handle the unpacking and inspection of
|
||||
* complex responses such as archive data.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface ReadTreeResponseFactory {
|
||||
fromTarArchive(
|
||||
options: ReadTreeResponseFactoryOptions,
|
||||
|
||||
@@ -33,7 +33,11 @@ From : https://isomorphic-git.org/docs/en/onAuth with fix for GitHub
|
||||
Azure 'notempty' token
|
||||
*/
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A convenience wrapper around the `isomorphic-git` library.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class Git {
|
||||
private constructor(
|
||||
private readonly config: {
|
||||
|
||||
@@ -19,9 +19,26 @@ import Router from 'express-promise-router';
|
||||
import express from 'express';
|
||||
import { errorHandler, statusCheckHandler, StatusCheck } from '../middleware';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Creates a default status checking router, that you can add to your express
|
||||
* app.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This adds a `/healthcheck` route (or any other path, if given as an
|
||||
* argument), which your infra can call to see if the service is ready to serve
|
||||
* requests.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export async function createStatusCheckRouter(options: {
|
||||
logger: Logger;
|
||||
/**
|
||||
* The path (including a leading slash) that the health check should be
|
||||
* mounted on.
|
||||
*
|
||||
* @defaultValue '/healthcheck'
|
||||
*/
|
||||
path?: string;
|
||||
/**
|
||||
* If not implemented, the default express middleware always returns 200.
|
||||
|
||||
@@ -20,7 +20,11 @@ import { Router, RequestHandler, ErrorRequestHandler } from 'express';
|
||||
import { Server } from 'http';
|
||||
import { Logger } from 'winston';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A helper for building backend service instances.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type ServiceBuilder = {
|
||||
/**
|
||||
* Sets the service parameters based on configuration.
|
||||
@@ -119,5 +123,9 @@ export type ServiceBuilder = {
|
||||
start(): Promise<Server>;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A factory for request loggers.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type RequestLoggingHandlerFactory = (logger?: Logger) => RequestHandler;
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
|
||||
import { Writable } from 'stream';
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Options passed to the {@link ContainerRunner.runContainer} method.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type RunContainerOptions = {
|
||||
imageName: string;
|
||||
command?: string | string[];
|
||||
@@ -28,7 +32,14 @@ export type RunContainerOptions = {
|
||||
pullImage?: boolean;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Handles the running of containers, on behalf of others.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface ContainerRunner {
|
||||
/**
|
||||
* Runs a container image to completion.
|
||||
*/
|
||||
runContainer(opts: RunContainerOptions): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,11 @@ export type UserOptions = {
|
||||
User?: string;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* A {@link ContainerRunner} for Docker containers.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export class DockerContainerRunner implements ContainerRunner {
|
||||
private readonly dockerClient: Docker;
|
||||
|
||||
|
||||
@@ -265,6 +265,19 @@ describe('ConfigReader', () => {
|
||||
withLogCollector(() => config.getOptionalConfigArray('b')),
|
||||
).toMatchObject({ warn: [] });
|
||||
});
|
||||
|
||||
it('should coerce number strings to numbers', () => {
|
||||
const config = ConfigReader.fromConfigs([
|
||||
{
|
||||
data: {
|
||||
port: '123',
|
||||
},
|
||||
context: '1',
|
||||
},
|
||||
]);
|
||||
|
||||
expect(config.getNumber('port')).toEqual(123);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ConfigReader with fallback', () => {
|
||||
@@ -661,16 +674,50 @@ describe('ConfigReader.get()', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('coerces number strings to numbers', () => {
|
||||
const config = ConfigReader.fromConfigs([
|
||||
{
|
||||
data: {
|
||||
port: '123',
|
||||
},
|
||||
context: '1',
|
||||
it('should return deep clones of the backing data', () => {
|
||||
const data1 = {
|
||||
foo: {
|
||||
bar: [],
|
||||
baz: {},
|
||||
},
|
||||
};
|
||||
const data2 = {
|
||||
x: {
|
||||
y: {
|
||||
z: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const reader = ConfigReader.fromConfigs([
|
||||
{ data: data1, context: '1' },
|
||||
{ data: data2, context: '2' },
|
||||
]);
|
||||
|
||||
expect(config.getNumber('port')).toEqual(123);
|
||||
reader.get<any>().foo.bar.push(1);
|
||||
reader.get<any>('foo').bar.push(1);
|
||||
reader.get<any>('foo.bar').push(1);
|
||||
reader.get<any>().foo.baz.x = 1;
|
||||
reader.get<any>('foo').baz.x = 1;
|
||||
reader.get<any>('foo.baz').x = 1;
|
||||
reader.get<any>().x.y.z.w = 1;
|
||||
reader.get<any>('x').y.z.w = 1;
|
||||
reader.get<any>('x.y').z.w = 1;
|
||||
reader.get<any>('x.y.z').w = 1;
|
||||
|
||||
const readerSingle = ConfigReader.fromConfigs([
|
||||
{ data: data1, context: '1' },
|
||||
]);
|
||||
|
||||
readerSingle.get<any>().foo.bar.push(1);
|
||||
readerSingle.get<any>('foo').bar.push(1);
|
||||
readerSingle.get<any>('foo.bar').push(1);
|
||||
readerSingle.get<any>().foo.baz.x = 1;
|
||||
readerSingle.get<any>('foo').baz.x = 1;
|
||||
readerSingle.get<any>('foo.baz').x = 1;
|
||||
|
||||
expect(data1.foo.bar).toEqual([]);
|
||||
expect(data1.foo.baz).toEqual({});
|
||||
expect(data2.x.y.z).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -126,7 +126,7 @@ export class ConfigReader implements Config {
|
||||
|
||||
/** {@inheritdoc Config.getOptional} */
|
||||
getOptional<T = JsonValue>(key?: string): T | undefined {
|
||||
const value = this.readValue(key);
|
||||
const value = cloneDeep(this.readValue(key));
|
||||
const fallbackValue = this.fallback?.getOptional<T>(key);
|
||||
|
||||
if (value === undefined) {
|
||||
@@ -153,11 +153,8 @@ export class ConfigReader implements Config {
|
||||
|
||||
// Avoid merging arrays and primitive values, since that's how merging works for other
|
||||
// methods for reading config.
|
||||
return mergeWith(
|
||||
{},
|
||||
{ value: cloneDeep(fallbackValue) },
|
||||
{ value },
|
||||
(into, from) => (!isObject(from) || !isObject(into) ? from : undefined),
|
||||
return mergeWith({}, { value: fallbackValue }, { value }, (into, from) =>
|
||||
!isObject(from) || !isObject(into) ? from : undefined,
|
||||
).value as T;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@
|
||||
"@backstage/plugin-explore": "*",
|
||||
"@backstage/plugin-github-actions": "*",
|
||||
"@backstage/plugin-lighthouse": "*",
|
||||
"@backstage/plugin-permission-common": "*",
|
||||
"@backstage/plugin-permission-node": "*",
|
||||
"@backstage/plugin-proxy-backend": "*",
|
||||
"@backstage/plugin-rollbar-backend": "*",
|
||||
"@backstage/plugin-scaffolder": "*",
|
||||
|
||||
@@ -57,6 +57,8 @@ import { version as pluginExplore } from '../../../../plugins/explore/package.js
|
||||
import { version as pluginGithubActions } from '../../../../plugins/github-actions/package.json';
|
||||
import { version as pluginLighthouse } from '../../../../plugins/lighthouse/package.json';
|
||||
import { version as pluginOrg } from '../../../../plugins/org/package.json';
|
||||
import { version as pluginPermissionCommon } from '../../../../plugins/permission-common/package.json';
|
||||
import { version as pluginPermissionNode } from '../../../../plugins/permission-node/package.json';
|
||||
import { version as pluginProxyBackend } from '../../../../plugins/proxy-backend/package.json';
|
||||
import { version as pluginRollbarBackend } from '../../../../plugins/rollbar-backend/package.json';
|
||||
import { version as pluginScaffolder } from '../../../../plugins/scaffolder/package.json';
|
||||
@@ -94,6 +96,8 @@ export const packageVersions = {
|
||||
'@backstage/plugin-github-actions': pluginGithubActions,
|
||||
'@backstage/plugin-lighthouse': pluginLighthouse,
|
||||
'@backstage/plugin-org': pluginOrg,
|
||||
'@backstage/plugin-permission-common': pluginPermissionCommon,
|
||||
'@backstage/plugin-permission-node': pluginPermissionNode,
|
||||
'@backstage/plugin-proxy-backend': pluginProxyBackend,
|
||||
'@backstage/plugin-rollbar-backend': pluginRollbarBackend,
|
||||
'@backstage/plugin-scaffolder': pluginScaffolder,
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
"@backstage/plugin-app-backend": "^{{version '@backstage/plugin-app-backend'}}",
|
||||
"@backstage/plugin-auth-backend": "^{{version '@backstage/plugin-auth-backend'}}",
|
||||
"@backstage/plugin-catalog-backend": "^{{version '@backstage/plugin-catalog-backend'}}",
|
||||
"@backstage/plugin-permission-common": "^{{version '@backstage/plugin-permission-common'}}",
|
||||
"@backstage/plugin-permission-node": "^{{version '@backstage/plugin-permission-node'}}",
|
||||
"@backstage/plugin-proxy-backend": "^{{version '@backstage/plugin-proxy-backend'}}",
|
||||
"@backstage/plugin-scaffolder-backend": "^{{version '@backstage/plugin-scaffolder-backend'}}",
|
||||
"@backstage/plugin-search-backend": "^{{version '@backstage/plugin-search-backend'}}",
|
||||
|
||||
@@ -29,6 +29,7 @@ import proxy from './plugins/proxy';
|
||||
import techdocs from './plugins/techdocs';
|
||||
import search from './plugins/search';
|
||||
import { PluginEnvironment } from './types';
|
||||
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
||||
|
||||
function makeCreateEnv(config: Config) {
|
||||
const root = getRootLogger();
|
||||
@@ -38,6 +39,10 @@ function makeCreateEnv(config: Config) {
|
||||
const databaseManager = DatabaseManager.fromConfig(config);
|
||||
const tokenManager = ServerTokenManager.noop();
|
||||
const taskScheduler = TaskScheduler.fromConfig(config);
|
||||
const permissions = ServerPermissionClient.fromConfig(config, {
|
||||
discovery,
|
||||
tokenManager,
|
||||
});
|
||||
|
||||
root.info(`Created UrlReader ${reader}`);
|
||||
|
||||
@@ -55,6 +60,7 @@ function makeCreateEnv(config: Config) {
|
||||
discovery,
|
||||
tokenManager,
|
||||
scheduler,
|
||||
permissions,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
UrlReader,
|
||||
} from '@backstage/backend-common';
|
||||
import { PluginTaskScheduler } from '@backstage/backend-tasks';
|
||||
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
|
||||
|
||||
export type PluginEnvironment = {
|
||||
logger: Logger;
|
||||
@@ -18,4 +19,5 @@ export type PluginEnvironment = {
|
||||
discovery: PluginEndpointDiscovery;
|
||||
tokenManager: TokenManager;
|
||||
scheduler: PluginTaskScheduler;
|
||||
permissions: PermissionAuthorizer;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user