Techdocs: allow custom collation of mkdocs search document

Signed-off-by: Alex Eftimie <alex.eftimie@getyourguide.com>
This commit is contained in:
Alex Eftimie
2024-07-02 15:12:31 +02:00
parent c2384b1391
commit 311efd906c
5 changed files with 115 additions and 10 deletions
@@ -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;
};
```
@@ -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',
@@ -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'
>;
@@ -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,
};
};
@@ -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';