From 4e08dda90960a5618c1ef7965497694fe8a03391 Mon Sep 17 00:00:00 2001 From: Andre Wanlin Date: Fri, 7 Apr 2023 08:07:39 -0500 Subject: [PATCH] Implemented interface for API Signed-off-by: Andre Wanlin --- plugins/linguist-backend/api-report.md | 22 ++++++-------- ....test.ts => LinguistBackendClient.test.ts} | 8 ++--- ...BackendApi.ts => LinguistBackendClient.ts} | 30 +++++++++++++------ plugins/linguist-backend/src/api/index.ts | 3 +- plugins/linguist-backend/src/index.ts | 3 +- .../src/service/router.test.ts | 2 +- .../linguist-backend/src/service/router.ts | 10 +++---- 7 files changed, 44 insertions(+), 34 deletions(-) rename plugins/linguist-backend/src/api/{LinguistBackendApi.test.ts => LinguistBackendClient.test.ts} (97%) rename plugins/linguist-backend/src/api/{LinguistBackendApi.ts => LinguistBackendClient.ts} (90%) diff --git a/plugins/linguist-backend/api-report.md b/plugins/linguist-backend/api-report.md index 907a48c50f..795271f46c 100644 --- a/plugins/linguist-backend/api-report.md +++ b/plugins/linguist-backend/api-report.md @@ -4,7 +4,6 @@ ```ts import { CatalogApi } from '@backstage/catalog-client'; -import { EntitiesOverview } from '@backstage/plugin-linguist-common'; import { EntityResults } from '@backstage/plugin-linguist-common'; import express from 'express'; import { HumanDuration } from '@backstage/types'; @@ -15,7 +14,6 @@ import { PluginDatabaseManager } from '@backstage/backend-common'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { ProcessedEntity } from '@backstage/plugin-linguist-common'; -import { Results } from 'linguist-js/dist/types'; import { TaskScheduleDefinition } from '@backstage/backend-tasks'; import { TokenManager } from '@backstage/backend-common'; import { UrlReader } from '@backstage/backend-common'; @@ -27,7 +25,15 @@ export function createRouter( ): Promise; // @public (undocumented) -export class LinguistBackendApi { +export interface LinguistBackendApi { + // (undocumented) + getEntityLanguages(entityRef: string): Promise; + // (undocumented) + processEntities(): Promise; +} + +// @public (undocumented) +export class LinguistBackendClient implements LinguistBackendApi { constructor( logger: Logger, store: LinguistBackendStore, @@ -41,18 +47,8 @@ export class LinguistBackendApi { linguistJsOptions?: Record, ); // (undocumented) - addNewEntities(): Promise; - // (undocumented) - generateEntitiesLanguages(): Promise; - // (undocumented) - generateEntityLanguages(entityRef: string, url: string): Promise; - // (undocumented) - getEntitiesOverview(): Promise; - // (undocumented) getEntityLanguages(entityRef: string): Promise; // (undocumented) - getLinguistResults(dir: string): Promise; - // (undocumented) processEntities(): Promise; } diff --git a/plugins/linguist-backend/src/api/LinguistBackendApi.test.ts b/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts similarity index 97% rename from plugins/linguist-backend/src/api/LinguistBackendApi.test.ts rename to plugins/linguist-backend/src/api/LinguistBackendClient.test.ts index b0f20f0207..58aae70106 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendApi.test.ts +++ b/plugins/linguist-backend/src/api/LinguistBackendClient.test.ts @@ -24,7 +24,7 @@ import { CatalogApi, GetEntitiesResponse } from '@backstage/catalog-client'; import { Results } from 'linguist-js/dist/types'; import { DateTime } from 'luxon'; import { LinguistBackendStore } from '../db'; -import { kindOrDefault, LinguistBackendApi } from './LinguistBackendApi'; +import { kindOrDefault, LinguistBackendClient } from './LinguistBackendClient'; import fs from 'fs-extra'; import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; @@ -94,7 +94,7 @@ describe('Linguist backend API', () => { const tokenManager = ServerTokenManager.noop(); - const api = new LinguistBackendApi( + const api = new LinguistBackendClient( logger, store, urlReader, @@ -203,7 +203,7 @@ describe('Linguist backend API', () => { }); it('should get entity overview with stale items', async () => { - const apiWithAge = new LinguistBackendApi( + const apiWithAge = new LinguistBackendClient( logger, store, urlReader, @@ -326,7 +326,7 @@ describe('Linguist backend API', () => { }); it('should generate languages for entities using defined batch size', async () => { - const apiWithBatchSize = new LinguistBackendApi( + const apiWithBatchSize = new LinguistBackendClient( logger, store, urlReader, diff --git a/plugins/linguist-backend/src/api/LinguistBackendApi.ts b/plugins/linguist-backend/src/api/LinguistBackendClient.ts similarity index 90% rename from plugins/linguist-backend/src/api/LinguistBackendApi.ts rename to plugins/linguist-backend/src/api/LinguistBackendClient.ts index f00aebcee1..890e6438b2 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendApi.ts +++ b/plugins/linguist-backend/src/api/LinguistBackendClient.ts @@ -39,9 +39,16 @@ import { } from '@backstage/catalog-model'; import { assertError } from '@backstage/errors'; import { HumanDuration } from '@backstage/types'; +import { Results } from 'linguist-js/dist/types'; /** @public */ -export class LinguistBackendApi { +export interface LinguistBackendApi { + getEntityLanguages(entityRef: string): Promise; + processEntities(): Promise; +} + +/** @public */ +export class LinguistBackendClient implements LinguistBackendApi { private readonly logger: Logger; private readonly store: LinguistBackendStore; private readonly urlReader: UrlReader; @@ -77,13 +84,13 @@ export class LinguistBackendApi { this.linguistJsOptions = linguistJsOptions; } - public async getEntityLanguages(entityRef: string): Promise { + async getEntityLanguages(entityRef: string): Promise { this.logger?.debug(`Getting languages for entity "${entityRef}"`); return this.store.getEntityResults(entityRef); } - public async processEntities() { + async processEntities(): Promise { this.logger?.info('Updating list of entities'); await this.addNewEntities(); @@ -93,7 +100,8 @@ export class LinguistBackendApi { await this.generateEntitiesLanguages(); } - public async addNewEntities() { + /** @internal */ + async addNewEntities(): Promise { const annotationKey = this.useSourceLocation ? ANNOTATION_SOURCE_LOCATION : LINGUIST_ANNOTATION; @@ -115,7 +123,8 @@ export class LinguistBackendApi { }); } - public async generateEntitiesLanguages() { + /** @internal */ + async generateEntitiesLanguages(): Promise { const entitiesOverview = await this.getEntitiesOverview(); this.logger?.info( `Entities overview: Entity: ${entitiesOverview.entityCount}, Processed: ${entitiesOverview.processedCount}, Pending: ${entitiesOverview.pendingCount}, Stale ${entitiesOverview.staleCount}`, @@ -152,7 +161,8 @@ export class LinguistBackendApi { } } - public async getEntitiesOverview(): Promise { + /** @internal */ + async getEntitiesOverview(): Promise { this.logger?.debug('Getting pending entities'); const processedEntities = await this.store.getProcessedEntities(); @@ -178,7 +188,8 @@ export class LinguistBackendApi { return entitiesOverview; } - public async generateEntityLanguages( + /** @internal */ + async generateEntityLanguages( entityRef: string, url: string, ): Promise { @@ -230,13 +241,14 @@ export class LinguistBackendApi { } } - public async getLinguistResults(dir: string) { + /** @internal */ + async getLinguistResults(dir: string): Promise { const results = await linguist(dir, this.linguistJsOptions); return results; } } -export function kindOrDefault(kind?: string[]) { +export function kindOrDefault(kind?: string[]): string[] { if (!kind || kind.length === 0) { return ['API', 'Component', 'Template']; } diff --git a/plugins/linguist-backend/src/api/index.ts b/plugins/linguist-backend/src/api/index.ts index a88fa051d4..53b427b3a7 100644 --- a/plugins/linguist-backend/src/api/index.ts +++ b/plugins/linguist-backend/src/api/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ -export { LinguistBackendApi } from './LinguistBackendApi'; +export { LinguistBackendClient } from './LinguistBackendClient'; +export type { LinguistBackendApi } from './LinguistBackendClient'; diff --git a/plugins/linguist-backend/src/index.ts b/plugins/linguist-backend/src/index.ts index da1e0ffb00..8969880618 100644 --- a/plugins/linguist-backend/src/index.ts +++ b/plugins/linguist-backend/src/index.ts @@ -15,6 +15,7 @@ */ export * from './service/router'; -export { LinguistBackendApi } from './api'; +export { LinguistBackendClient } from './api'; +export type { LinguistBackendApi } from './api'; export { LinguistBackendDatabase } from './db'; export type { LinguistBackendStore } from './db'; diff --git a/plugins/linguist-backend/src/service/router.test.ts b/plugins/linguist-backend/src/service/router.test.ts index b8bde9d35d..7ab8f1c238 100644 --- a/plugins/linguist-backend/src/service/router.test.ts +++ b/plugins/linguist-backend/src/service/router.test.ts @@ -73,7 +73,7 @@ describe('createRouter', () => { const router = await createRouter( { schedule: schedule, age: { days: 30 }, useSourceLocation: false }, { - linguistBackendApi, + linguistBackendApi: linguistBackendApi, discovery: testDiscovery, database: createDatabase(), reader: mockUrlReader, diff --git a/plugins/linguist-backend/src/service/router.ts b/plugins/linguist-backend/src/service/router.ts index 4c636aa854..21f03e08a3 100644 --- a/plugins/linguist-backend/src/service/router.ts +++ b/plugins/linguist-backend/src/service/router.ts @@ -24,7 +24,7 @@ import { import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; -import { LinguistBackendApi } from '../api'; +import { LinguistBackendApi, LinguistBackendClient } from '../api'; import { LinguistBackendDatabase } from '../db'; import { PluginTaskScheduler, @@ -77,9 +77,9 @@ export async function createRouter( const catalogClient = new CatalogClient({ discoveryApi: discovery }); - const linguistBackendApi = + const linguistBackendClient = routerOptions.linguistBackendApi || - new LinguistBackendApi( + new LinguistBackendClient( logger, linguistBackendStore, reader, @@ -103,7 +103,7 @@ export async function createRouter( initialDelay: schedule.initialDelay, scope: schedule.scope, fn: async () => { - await linguistBackendApi.processEntities(); + await linguistBackendClient.processEntities(); }, }); } @@ -125,7 +125,7 @@ export async function createRouter( throw new Error('No entityRef was provided'); } - const entityLanguages = await linguistBackendApi.getEntityLanguages( + const entityLanguages = await linguistBackendClient.getEntityLanguages( entityRef as string, ); res.status(200).json(entityLanguages);