From 311efd906c03f3d2ee4e6ed1a2ee3a8e337ea28d Mon Sep 17 00:00:00 2001 From: Alex Eftimie Date: Tue, 2 Jul 2024 15:12:31 +0200 Subject: [PATCH] Techdocs: allow custom collation of mkdocs search document Signed-off-by: Alex Eftimie --- .../api-report.md | 30 +++++++++++++++ .../DefaultTechDocsCollatorFactory.ts | 20 +++++----- .../TechDocsCollatorDocumentTransformer.ts | 38 +++++++++++++++++++ ...aultTechDocsCollatorDocumentTransformer.ts | 30 +++++++++++++++ .../src/collators/index.ts | 7 ++++ 5 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 plugins/search-backend-module-techdocs/src/collators/TechDocsCollatorDocumentTransformer.ts create mode 100644 plugins/search-backend-module-techdocs/src/collators/defaultTechDocsCollatorDocumentTransformer.ts diff --git a/plugins/search-backend-module-techdocs/api-report.md b/plugins/search-backend-module-techdocs/api-report.md index 9c9fae1a38..3f4ece1cea 100644 --- a/plugins/search-backend-module-techdocs/api-report.md +++ b/plugins/search-backend-module-techdocs/api-report.md @@ -18,6 +18,9 @@ import { Readable } from 'stream'; import { TechDocsDocument } from '@backstage/plugin-techdocs-node'; import { TokenManager } from '@backstage/backend-common'; +// @public (undocumented) +export const defaultTechDocsCollatorDocumentTransformer: TechDocsCollatorDocumentTransformer; + // @public (undocumented) export const defaultTechDocsCollatorEntityTransformer: TechDocsCollatorEntityTransformer; @@ -36,6 +39,32 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { readonly visibilityPermission: Permission; } +// @public (undocumented) +export interface MkSearchIndexDoc { + // (undocumented) + location: string; + // (undocumented) + tags?: string[]; + // (undocumented) + text: string; + // (undocumented) + title: string; +} + +// @public (undocumented) +export type TechDocsCollatorDocumentTransformer = ( + doc: MkSearchIndexDoc, +) => Omit< + TechDocsDocument, + | 'location' + | 'authorization' + | 'kind' + | 'namespace' + | 'name' + | 'lifecycle' + | 'owner' +>; + // @public (undocumented) export type TechDocsCollatorEntityTransformer = ( entity: Entity, @@ -53,5 +82,6 @@ export type TechDocsCollatorFactoryOptions = { parallelismLimit?: number; legacyPathCasing?: boolean; entityTransformer?: TechDocsCollatorEntityTransformer; + documentTransformer?: TechDocsCollatorDocumentTransformer; }; ``` diff --git a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts index 748cb515d9..6b0eb6255b 100644 --- a/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts +++ b/plugins/search-backend-module-techdocs/src/collators/DefaultTechDocsCollatorFactory.ts @@ -34,12 +34,16 @@ import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/al import { Permission } from '@backstage/plugin-permission-common'; import { DocumentCollatorFactory } from '@backstage/plugin-search-common'; import { TechDocsDocument } from '@backstage/plugin-techdocs-node'; -import unescape from 'lodash/unescape'; import fetch from 'node-fetch'; import pLimit from 'p-limit'; import { Readable } from 'stream'; import { TechDocsCollatorEntityTransformer } from './TechDocsCollatorEntityTransformer'; +import { + MkSearchIndexDoc, + TechDocsCollatorDocumentTransformer, +} from './TechDocsCollatorDocumentTransformer'; import { defaultTechDocsCollatorEntityTransformer } from './defaultTechDocsCollatorEntityTransformer'; +import { defaultTechDocsCollatorDocumentTransformer } from './defaultTechDocsCollatorDocumentTransformer'; import { AuthService, DiscoveryService, @@ -47,12 +51,6 @@ import { LoggerService, } from '@backstage/backend-plugin-api'; -interface MkSearchIndexDoc { - title: string; - text: string; - location: string; -} - /** * Options to configure the TechDocs collator factory * @@ -70,6 +68,7 @@ export type TechDocsCollatorFactoryOptions = { parallelismLimit?: number; legacyPathCasing?: boolean; entityTransformer?: TechDocsCollatorEntityTransformer; + documentTransformer?: TechDocsCollatorDocumentTransformer; }; type EntityInfo = { @@ -98,6 +97,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { private readonly parallelismLimit: number; private readonly legacyPathCasing: boolean; private entityTransformer: TechDocsCollatorEntityTransformer; + private documentTransformer: TechDocsCollatorDocumentTransformer; private constructor(options: TechDocsCollatorFactoryOptions) { this.discovery = options.discovery; @@ -111,6 +111,8 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { this.legacyPathCasing = options.legacyPathCasing ?? false; this.entityTransformer = options.entityTransformer ?? defaultTechDocsCollatorEntityTransformer; + this.documentTransformer = + options.documentTransformer ?? defaultTechDocsCollatorDocumentTransformer; this.auth = createLegacyAuthAdapters({ auth: options.auth, @@ -225,8 +227,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { return searchIndex.docs.map((doc: MkSearchIndexDoc) => ({ ...this.entityTransformer(entity), - title: unescape(doc.title), - text: unescape(doc.text || ''), + ...this.documentTransformer(doc), location: this.applyArgsToFormat( this.locationTemplate || '/docs/:namespace/:kind/:name/:path', { @@ -234,7 +235,6 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory { path: doc.location, }, ), - path: doc.location, ...entityInfo, entityTitle: entity.metadata.title, componentType: entity.spec?.type?.toString() || 'other', diff --git a/plugins/search-backend-module-techdocs/src/collators/TechDocsCollatorDocumentTransformer.ts b/plugins/search-backend-module-techdocs/src/collators/TechDocsCollatorDocumentTransformer.ts new file mode 100644 index 0000000000..b95187bde4 --- /dev/null +++ b/plugins/search-backend-module-techdocs/src/collators/TechDocsCollatorDocumentTransformer.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2024 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. + */ +import { TechDocsDocument } from '@backstage/plugin-techdocs-node'; + +/** @public */ +export interface MkSearchIndexDoc { + title: string; + text: string; + location: string; + tags?: string[]; +} + +/** @public */ +export type TechDocsCollatorDocumentTransformer = ( + doc: MkSearchIndexDoc, +) => Omit< + TechDocsDocument, + | 'location' + | 'authorization' + | 'kind' + | 'namespace' + | 'name' + | 'lifecycle' + | 'owner' +>; diff --git a/plugins/search-backend-module-techdocs/src/collators/defaultTechDocsCollatorDocumentTransformer.ts b/plugins/search-backend-module-techdocs/src/collators/defaultTechDocsCollatorDocumentTransformer.ts new file mode 100644 index 0000000000..36492de6bd --- /dev/null +++ b/plugins/search-backend-module-techdocs/src/collators/defaultTechDocsCollatorDocumentTransformer.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 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. + */ +import unescape from 'lodash/unescape'; +import { + TechDocsCollatorDocumentTransformer, + MkSearchIndexDoc, +} from './TechDocsCollatorDocumentTransformer'; + +/** @public */ +export const defaultTechDocsCollatorDocumentTransformer: TechDocsCollatorDocumentTransformer = + (doc: MkSearchIndexDoc) => { + return { + title: unescape(doc.title), + text: unescape(doc.text || ''), + path: doc.location, + }; + }; diff --git a/plugins/search-backend-module-techdocs/src/collators/index.ts b/plugins/search-backend-module-techdocs/src/collators/index.ts index 94be458e33..1f0795368f 100644 --- a/plugins/search-backend-module-techdocs/src/collators/index.ts +++ b/plugins/search-backend-module-techdocs/src/collators/index.ts @@ -21,3 +21,10 @@ export type { TechDocsCollatorFactoryOptions } from './DefaultTechDocsCollatorFa export { defaultTechDocsCollatorEntityTransformer } from './defaultTechDocsCollatorEntityTransformer'; export type { TechDocsCollatorEntityTransformer } from './TechDocsCollatorEntityTransformer'; + +export { defaultTechDocsCollatorDocumentTransformer } from './defaultTechDocsCollatorDocumentTransformer'; + +export type { + TechDocsCollatorDocumentTransformer, + MkSearchIndexDoc, +} from './TechDocsCollatorDocumentTransformer';