search - Removed legacy backend support
Signed-off-by: Andre Wanlin <awanlin@spotify.com> Fixed typo Signed-off-by: Andre Wanlin <awanlin@spotify.com> Updated API report Signed-off-by: Andre Wanlin <awanlin@spotify.com> Moved types Signed-off-by: Andre Wanlin <awanlin@spotify.com> Updated changesets Signed-off-by: Andre Wanlin <awanlin@spotify.com> Fixed type error Signed-off-by: Andre Wanlin <awanlin@spotify.com> Updated changeset based on feedback Signed-off-by: Andre Wanlin <awanlin@spotify.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-techdocs-backend': major
|
||||
---
|
||||
|
||||
**BREAKING** Removed deprecated code `DefaultTechDocsCollatorFactory`. Use the `@backstage/plugin-search-backend-module-techdocs` for this instead.
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'@backstage/plugin-search-backend-module-techdocs': minor
|
||||
'@backstage/plugin-search-backend-module-explore': minor
|
||||
'@backstage/plugin-search-backend': major
|
||||
---
|
||||
|
||||
**BREAKING** Removed support for the legacy backend system and references to `@backstage/backend-common`, please migrate to the new backend system.
|
||||
@@ -43,7 +43,6 @@ import catalog from './plugins/catalog';
|
||||
import events from './plugins/events';
|
||||
import kubernetes from './plugins/kubernetes';
|
||||
import scaffolder from './plugins/scaffolder';
|
||||
import search from './plugins/search';
|
||||
import techdocs from './plugins/techdocs';
|
||||
import permission from './plugins/permission';
|
||||
import { PluginEnvironment } from './types';
|
||||
@@ -133,7 +132,6 @@ async function main() {
|
||||
const catalogEnv = useHotMemoize(module, () => createEnv('catalog'));
|
||||
const scaffolderEnv = useHotMemoize(module, () => createEnv('scaffolder'));
|
||||
const authEnv = useHotMemoize(module, () => createEnv('auth'));
|
||||
const searchEnv = useHotMemoize(module, () => createEnv('search'));
|
||||
const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
|
||||
const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes'));
|
||||
const permissionEnv = useHotMemoize(module, () => createEnv('permission'));
|
||||
@@ -144,7 +142,6 @@ async function main() {
|
||||
apiRouter.use('/events', await events(eventsEnv));
|
||||
apiRouter.use('/scaffolder', await scaffolder(scaffolderEnv));
|
||||
apiRouter.use('/auth', await authPlugin(authEnv));
|
||||
apiRouter.use('/search', await search(searchEnv));
|
||||
apiRouter.use('/techdocs', await techdocs(techdocsEnv));
|
||||
apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv));
|
||||
apiRouter.use('/permission', await permission(permissionEnv));
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 { useHotCleanup } from '@backstage/backend-common';
|
||||
import { ToolDocumentCollatorFactory } from '@backstage/plugin-search-backend-module-explore';
|
||||
import { createRouter } from '@backstage/plugin-search-backend';
|
||||
import { ElasticSearchSearchEngine } from '@backstage/plugin-search-backend-module-elasticsearch';
|
||||
import { PgSearchEngine } from '@backstage/plugin-search-backend-module-pg';
|
||||
import {
|
||||
IndexBuilder,
|
||||
SearchEngine,
|
||||
LunrSearchEngine,
|
||||
} from '@backstage/plugin-search-backend-node';
|
||||
import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
async function createSearchEngine(
|
||||
env: PluginEnvironment,
|
||||
): Promise<SearchEngine> {
|
||||
if (env.config.has('search.elasticsearch')) {
|
||||
return await ElasticSearchSearchEngine.fromConfig({
|
||||
logger: env.logger,
|
||||
config: env.config,
|
||||
});
|
||||
}
|
||||
|
||||
if (await PgSearchEngine.supported(env.database)) {
|
||||
return await PgSearchEngine.fromConfig(env.config, {
|
||||
database: env.database,
|
||||
logger: env.logger,
|
||||
});
|
||||
}
|
||||
|
||||
return new LunrSearchEngine({ logger: env.logger });
|
||||
}
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
// Initialize a connection to a search engine.
|
||||
const searchEngine = await createSearchEngine(env);
|
||||
const indexBuilder = new IndexBuilder({
|
||||
logger: env.logger,
|
||||
searchEngine,
|
||||
});
|
||||
|
||||
const schedule = env.scheduler.createScheduledTaskRunner({
|
||||
frequency: { minutes: 10 },
|
||||
timeout: { minutes: 15 },
|
||||
// A 3 second delay gives the backend server a chance to initialize before
|
||||
// any collators are executed, which may attempt requests against the API.
|
||||
initialDelay: { seconds: 3 },
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
schedule,
|
||||
factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, {
|
||||
discovery: env.discovery,
|
||||
logger: env.logger,
|
||||
tokenManager: env.tokenManager,
|
||||
}),
|
||||
});
|
||||
|
||||
indexBuilder.addCollator({
|
||||
schedule,
|
||||
factory: ToolDocumentCollatorFactory.fromConfig(env.config, {
|
||||
discovery: env.discovery,
|
||||
logger: env.logger,
|
||||
}),
|
||||
});
|
||||
|
||||
// The scheduler controls when documents are gathered from collators and sent
|
||||
// to the search engine for indexing.
|
||||
const { scheduler } = await indexBuilder.build();
|
||||
scheduler.start();
|
||||
|
||||
useHotCleanup(module, () => scheduler.stop());
|
||||
|
||||
return await createRouter({
|
||||
engine: indexBuilder.getSearchEngine(),
|
||||
types: indexBuilder.getDocumentTypes(),
|
||||
discovery: env.discovery,
|
||||
permissions: env.permissions,
|
||||
config: env.config,
|
||||
logger: env.logger,
|
||||
});
|
||||
}
|
||||
@@ -49,7 +49,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage-community/plugin-explore-common": "^0.0.7",
|
||||
"@backstage/backend-common": "^0.25.0",
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/config": "workspace:^",
|
||||
"@backstage/plugin-search-backend-node": "workspace:^",
|
||||
|
||||
@@ -3,16 +3,9 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
|
||||
import { ExploreTool } from '@backstage-community/plugin-explore-common';
|
||||
import { IndexableDocument } from '@backstage/plugin-search-common';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { Readable } from 'stream';
|
||||
import { TokenManager } from '@backstage/backend-common';
|
||||
|
||||
// @public
|
||||
const _default: BackendFeature;
|
||||
@@ -20,27 +13,4 @@ export default _default;
|
||||
|
||||
// @public
|
||||
export interface ToolDocument extends IndexableDocument, ExploreTool {}
|
||||
|
||||
// @public @deprecated
|
||||
export class ToolDocumentCollatorFactory implements DocumentCollatorFactory {
|
||||
// (undocumented)
|
||||
execute(): AsyncGenerator<ToolDocument>;
|
||||
// (undocumented)
|
||||
static fromConfig(
|
||||
_config: Config,
|
||||
options: ToolDocumentCollatorFactoryOptions,
|
||||
): ToolDocumentCollatorFactory;
|
||||
// (undocumented)
|
||||
getCollator(): Promise<Readable>;
|
||||
// (undocumented)
|
||||
readonly type: string;
|
||||
}
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type ToolDocumentCollatorFactoryOptions = {
|
||||
discovery: DiscoveryService;
|
||||
logger: LoggerService;
|
||||
tokenManager?: TokenManager;
|
||||
auth?: AuthService;
|
||||
};
|
||||
```
|
||||
|
||||
+2
@@ -61,6 +61,7 @@ describe('ToolDocumentCollatorFactory', () => {
|
||||
const options = {
|
||||
discovery: mockDiscoveryApi,
|
||||
logger,
|
||||
auth: mockServices.auth(),
|
||||
};
|
||||
|
||||
it('has expected type', () => {
|
||||
@@ -101,6 +102,7 @@ describe('ToolDocumentCollatorFactory', () => {
|
||||
factory = ToolDocumentCollatorFactory.fromConfig(config, {
|
||||
discovery: mockDiscoveryApi,
|
||||
logger,
|
||||
auth: mockServices.auth(),
|
||||
});
|
||||
collator = await factory.getCollator();
|
||||
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
createLegacyAuthAdapters,
|
||||
TokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
import {
|
||||
AuthService,
|
||||
DiscoveryService,
|
||||
@@ -39,21 +35,18 @@ import { Readable } from 'stream';
|
||||
export interface ToolDocument extends IndexableDocument, ExploreTool {}
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated This type is deprecated along with the {@link ToolDocumentCollatorFactory}.
|
||||
* @internal
|
||||
*/
|
||||
export type ToolDocumentCollatorFactoryOptions = {
|
||||
discovery: DiscoveryService;
|
||||
logger: LoggerService;
|
||||
tokenManager?: TokenManager;
|
||||
auth?: AuthService;
|
||||
auth: AuthService;
|
||||
};
|
||||
|
||||
/**
|
||||
* Search collator responsible for collecting explore tools to index.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/building-backends/migrating | new backend system} and install this collator via module instead (see {@link https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-explore/README.md#installation | here} for more installation details).
|
||||
* @internal
|
||||
*/
|
||||
export class ToolDocumentCollatorFactory implements DocumentCollatorFactory {
|
||||
public readonly type: string = 'tools';
|
||||
@@ -65,7 +58,7 @@ export class ToolDocumentCollatorFactory implements DocumentCollatorFactory {
|
||||
private constructor(options: ToolDocumentCollatorFactoryOptions) {
|
||||
this.discovery = options.discovery;
|
||||
this.logger = options.logger;
|
||||
this.auth = createLegacyAuthAdapters(options).auth;
|
||||
this.auth = options.auth;
|
||||
}
|
||||
|
||||
static fromConfig(
|
||||
|
||||
@@ -14,9 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { ToolDocumentCollatorFactory } from './ToolDocumentCollatorFactory';
|
||||
|
||||
export type {
|
||||
ToolDocument,
|
||||
ToolDocumentCollatorFactoryOptions,
|
||||
} from './ToolDocumentCollatorFactory';
|
||||
export type { ToolDocument } from './ToolDocumentCollatorFactory';
|
||||
|
||||
@@ -25,8 +25,7 @@ import {
|
||||
readSchedulerServiceTaskScheduleDefinitionFromConfig,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha';
|
||||
|
||||
import { ToolDocumentCollatorFactory } from '@backstage/plugin-search-backend-module-explore';
|
||||
import { ToolDocumentCollatorFactory } from './collators/ToolDocumentCollatorFactory';
|
||||
|
||||
/**
|
||||
* Search backend module for the Explore index.
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
"test": "backstage-cli package test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.25.0",
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
"@backstage/catalog-client": "workspace:^",
|
||||
"@backstage/catalog-model": "workspace:^",
|
||||
|
||||
@@ -3,23 +3,11 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { EntityFilterQuery } from '@backstage/catalog-client';
|
||||
import { ExtensionPoint } from '@backstage/backend-plugin-api';
|
||||
import { HttpAuthService } from '@backstage/backend-plugin-api';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { Permission } from '@backstage/plugin-permission-common';
|
||||
import { Readable } from 'stream';
|
||||
import { TechDocsCollatorDocumentTransformer as TechDocsCollatorDocumentTransformer_2 } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import { TechDocsCollatorEntityTransformer as TechDocsCollatorEntityTransformer_2 } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import { TechDocsDocument } from '@backstage/plugin-techdocs-node';
|
||||
import { TokenManager } from '@backstage/backend-common';
|
||||
|
||||
// @public
|
||||
const _default: BackendFeature;
|
||||
@@ -28,21 +16,6 @@ export default _default;
|
||||
// @public (undocumented)
|
||||
export const defaultTechDocsCollatorEntityTransformer: TechDocsCollatorEntityTransformer;
|
||||
|
||||
// @public @deprecated
|
||||
export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory {
|
||||
// (undocumented)
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options: TechDocsCollatorFactoryOptions,
|
||||
): DefaultTechDocsCollatorFactory;
|
||||
// (undocumented)
|
||||
getCollator(): Promise<Readable>;
|
||||
// (undocumented)
|
||||
readonly type: string;
|
||||
// (undocumented)
|
||||
readonly visibilityPermission: Permission;
|
||||
}
|
||||
|
||||
// @public (undocumented)
|
||||
export interface MkSearchIndexDoc {
|
||||
// (undocumented)
|
||||
@@ -93,29 +66,12 @@ export type TechDocsCollatorEntityTransformer = (
|
||||
export interface TechDocsCollatorEntityTransformerExtensionPoint {
|
||||
// (undocumented)
|
||||
setDocumentTransformer(
|
||||
transformer: TechDocsCollatorDocumentTransformer_2,
|
||||
transformer: TechDocsCollatorDocumentTransformer,
|
||||
): void;
|
||||
// (undocumented)
|
||||
setTransformer(transformer: TechDocsCollatorEntityTransformer_2): void;
|
||||
setTransformer(transformer: TechDocsCollatorEntityTransformer): void;
|
||||
}
|
||||
|
||||
// @public
|
||||
export const techdocsCollatorEntityTransformerExtensionPoint: ExtensionPoint<TechDocsCollatorEntityTransformerExtensionPoint>;
|
||||
|
||||
// @public @deprecated
|
||||
export type TechDocsCollatorFactoryOptions = {
|
||||
discovery: DiscoveryService;
|
||||
logger: LoggerService;
|
||||
tokenManager?: TokenManager;
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
locationTemplate?: string;
|
||||
catalogClient?: CatalogApi;
|
||||
parallelismLimit?: number;
|
||||
legacyPathCasing?: boolean;
|
||||
entityTransformer?: TechDocsCollatorEntityTransformer;
|
||||
documentTransformer?: TechDocsCollatorDocumentTransformer;
|
||||
entityFilterFunction?: (entity: Entity[]) => Entity[];
|
||||
customCatalogApiFilters?: EntityFilterQuery;
|
||||
};
|
||||
```
|
||||
|
||||
+2
@@ -88,6 +88,7 @@ describe('DefaultTechDocsCollatorFactory', () => {
|
||||
const options = {
|
||||
logger,
|
||||
discovery: mockDiscoveryApi,
|
||||
auth: mockServices.auth(),
|
||||
};
|
||||
|
||||
it('has expected type', () => {
|
||||
@@ -182,6 +183,7 @@ describe('DefaultTechDocsCollatorFactory', () => {
|
||||
factory = DefaultTechDocsCollatorFactory.fromConfig(_config, {
|
||||
discovery: mockDiscoveryApi,
|
||||
logger,
|
||||
auth: mockServices.auth(),
|
||||
});
|
||||
collator = await factory.getCollator();
|
||||
|
||||
|
||||
+4
-18
@@ -14,10 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
createLegacyAuthAdapters,
|
||||
TokenManager,
|
||||
} from '@backstage/backend-common';
|
||||
import {
|
||||
CATALOG_FILTER_EXISTS,
|
||||
CatalogApi,
|
||||
@@ -47,22 +43,18 @@ import { defaultTechDocsCollatorDocumentTransformer } from './defaultTechDocsCol
|
||||
import {
|
||||
AuthService,
|
||||
DiscoveryService,
|
||||
HttpAuthService,
|
||||
LoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
|
||||
/**
|
||||
* Options to configure the TechDocs collator factory
|
||||
*
|
||||
* @public
|
||||
* @deprecated This type is deprecated along with the {@link DefaultTechDocsCollatorFactory}.
|
||||
* @internal
|
||||
*/
|
||||
export type TechDocsCollatorFactoryOptions = {
|
||||
discovery: DiscoveryService;
|
||||
logger: LoggerService;
|
||||
tokenManager?: TokenManager;
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
auth: AuthService;
|
||||
locationTemplate?: string;
|
||||
catalogClient?: CatalogApi;
|
||||
parallelismLimit?: number;
|
||||
@@ -83,8 +75,7 @@ type EntityInfo = {
|
||||
* A search collator factory responsible for gathering and transforming
|
||||
* TechDocs documents.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Migrate to the {@link https://backstage.io/docs/backend-system/building-backends/migrating | new backend system} and install this collator via module instead (see {@link https://github.com/backstage/backstage/blob/nbs10/search-deprecate-create-router/plugins/search-backend-module-techdocs/README.md#installation | here} for more installation details).
|
||||
* @internal
|
||||
*/
|
||||
export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory {
|
||||
public readonly type: string = 'techdocs';
|
||||
@@ -117,12 +108,7 @@ export class DefaultTechDocsCollatorFactory implements DocumentCollatorFactory {
|
||||
this.documentTransformer = options.documentTransformer ?? (() => ({}));
|
||||
this.entityFilterFunction = options.entityFilterFunction;
|
||||
this.customCatalogApiFilters = options.customCatalogApiFilters;
|
||||
|
||||
this.auth = createLegacyAuthAdapters({
|
||||
auth: options.auth,
|
||||
discovery: options.discovery,
|
||||
tokenManager: options.tokenManager,
|
||||
}).auth;
|
||||
this.auth = options.auth;
|
||||
}
|
||||
|
||||
static fromConfig(config: Config, options: TechDocsCollatorFactoryOptions) {
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { DefaultTechDocsCollatorFactory } from './DefaultTechDocsCollatorFactory';
|
||||
|
||||
export type { TechDocsCollatorFactoryOptions } from './DefaultTechDocsCollatorFactory';
|
||||
|
||||
export { defaultTechDocsCollatorEntityTransformer } from './defaultTechDocsCollatorEntityTransformer';
|
||||
|
||||
export type { TechDocsCollatorEntityTransformer } from './TechDocsCollatorEntityTransformer';
|
||||
|
||||
@@ -28,12 +28,12 @@ import {
|
||||
import { EntityFilterQuery } from '@backstage/catalog-client';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha';
|
||||
import { DefaultTechDocsCollatorFactory } from './collators/DefaultTechDocsCollatorFactory';
|
||||
import {
|
||||
DefaultTechDocsCollatorFactory,
|
||||
TechDocsCollatorDocumentTransformer,
|
||||
TechDocsCollatorEntityTransformer,
|
||||
} from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import { searchIndexRegistryExtensionPoint } from '@backstage/plugin-search-backend-node/alpha';
|
||||
} from './collators';
|
||||
|
||||
/** @public */
|
||||
export interface TechDocsCollatorEntityTransformerExtensionPoint {
|
||||
@@ -130,7 +130,6 @@ export default createBackendModule({
|
||||
config: coreServices.rootConfig,
|
||||
logger: coreServices.logger,
|
||||
auth: coreServices.auth,
|
||||
httpAuth: coreServices.httpAuth,
|
||||
discovery: coreServices.discovery,
|
||||
scheduler: coreServices.scheduler,
|
||||
catalog: catalogServiceRef,
|
||||
@@ -140,7 +139,6 @@ export default createBackendModule({
|
||||
config,
|
||||
logger,
|
||||
auth,
|
||||
httpAuth,
|
||||
discovery,
|
||||
scheduler,
|
||||
catalog,
|
||||
@@ -163,7 +161,6 @@ export default createBackendModule({
|
||||
factory: DefaultTechDocsCollatorFactory.fromConfig(config, {
|
||||
discovery,
|
||||
auth,
|
||||
httpAuth,
|
||||
logger,
|
||||
catalogClient: catalog,
|
||||
entityTransformer,
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
"test": "backstage-cli package test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.25.0",
|
||||
"@backstage/backend-defaults": "workspace:^",
|
||||
"@backstage/backend-openapi-utils": "workspace:^",
|
||||
"@backstage/backend-plugin-api": "workspace:^",
|
||||
@@ -67,7 +66,6 @@
|
||||
"@backstage/plugin-search-backend-node": "workspace:^",
|
||||
"@backstage/plugin-search-common": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@types/express": "^4.17.6",
|
||||
"dataloader": "^2.0.0",
|
||||
"express": "^4.17.1",
|
||||
"lodash": "^4.17.21",
|
||||
@@ -79,6 +77,7 @@
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
"@backstage/cli": "workspace:^",
|
||||
"@backstage/repo-tools": "workspace:^",
|
||||
"@types/express": "^4.17.6",
|
||||
"@types/supertest": "^2.0.8",
|
||||
"supertest": "^7.0.0"
|
||||
},
|
||||
|
||||
@@ -3,34 +3,9 @@
|
||||
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
|
||||
|
||||
```ts
|
||||
import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
import { DocumentTypeInfo } from '@backstage/plugin-search-common';
|
||||
import express from 'express';
|
||||
import { HttpAuthService } from '@backstage/backend-plugin-api';
|
||||
import { LoggerService } from '@backstage/backend-plugin-api';
|
||||
import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
import { SearchEngine } from '@backstage/plugin-search-backend-node';
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export function createRouter(options: RouterOptions): Promise<express.Router>;
|
||||
|
||||
// @public
|
||||
const _default: BackendFeature;
|
||||
export default _default;
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type RouterOptions = {
|
||||
engine: SearchEngine;
|
||||
types: Record<string, DocumentTypeInfo>;
|
||||
discovery?: DiscoveryService;
|
||||
permissions: PermissionEvaluator | PermissionAuthorizer;
|
||||
config: Config;
|
||||
logger: LoggerService;
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
};
|
||||
```
|
||||
|
||||
@@ -21,4 +21,3 @@
|
||||
*/
|
||||
|
||||
export { default } from './plugin';
|
||||
export * from './service/router';
|
||||
|
||||
@@ -278,6 +278,8 @@ describe('createRouter', () => {
|
||||
permissions: mockPermissionEvaluator,
|
||||
discovery,
|
||||
logger,
|
||||
auth: mockServices.auth(),
|
||||
httpAuth: mockServices.httpAuth(),
|
||||
});
|
||||
app = express().use(router);
|
||||
});
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
import express from 'express';
|
||||
import { z } from 'zod';
|
||||
import { createLegacyAuthAdapters } from '@backstage/backend-common';
|
||||
import { InputError } from '@backstage/errors';
|
||||
import { Config } from '@backstage/config';
|
||||
import { JsonObject, JsonValue } from '@backstage/types';
|
||||
@@ -39,7 +38,6 @@ import {
|
||||
HttpAuthService,
|
||||
LoggerService,
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { HostDiscovery } from '@backstage/backend-defaults/discovery';
|
||||
|
||||
const jsonObjectSchema: z.ZodSchema<JsonObject> = z.lazy(() => {
|
||||
const jsonValueSchema: z.ZodSchema<JsonValue> = z.lazy(() =>
|
||||
@@ -57,8 +55,7 @@ const jsonObjectSchema: z.ZodSchema<JsonObject> = z.lazy(() => {
|
||||
});
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Please migrate to the new backend system as this will be removed in the future.
|
||||
* @internal
|
||||
*/
|
||||
export type RouterOptions = {
|
||||
engine: SearchEngine;
|
||||
@@ -67,9 +64,8 @@ export type RouterOptions = {
|
||||
permissions: PermissionEvaluator | PermissionAuthorizer;
|
||||
config: Config;
|
||||
logger: LoggerService;
|
||||
// TODO: Make "auth" and "httpAuth" required once we remove the usage of "tokenManager"
|
||||
auth?: AuthService;
|
||||
httpAuth?: HttpAuthService;
|
||||
auth: AuthService;
|
||||
httpAuth: HttpAuthService;
|
||||
};
|
||||
|
||||
const defaultMaxPageLimit = 100;
|
||||
@@ -77,8 +73,7 @@ const defaultMaxTermLength = 100;
|
||||
const allowedLocationProtocols = ['http:', 'https:'];
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated Please migrate to the new backend system as this will be removed in the future.
|
||||
* @internal
|
||||
*/
|
||||
export async function createRouter(
|
||||
options: RouterOptions,
|
||||
@@ -90,15 +85,10 @@ export async function createRouter(
|
||||
permissions,
|
||||
config,
|
||||
logger,
|
||||
discovery = HostDiscovery.fromConfig(config),
|
||||
auth,
|
||||
httpAuth,
|
||||
} = options;
|
||||
|
||||
// TODO: stop using this adapter when the "tokenManager" is removed
|
||||
const { auth, httpAuth } = createLegacyAuthAdapters({
|
||||
...options,
|
||||
discovery,
|
||||
});
|
||||
|
||||
const maxPageLimit =
|
||||
config.getOptionalNumber('search.maxPageLimit') ?? defaultMaxPageLimit;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import { AuthService } from '@backstage/backend-plugin-api';
|
||||
import { BackendFeature } from '@backstage/backend-plugin-api';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { Config } from '@backstage/config';
|
||||
import { DefaultTechDocsCollatorFactory as DefaultTechDocsCollatorFactory_2 } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
import { DocsBuildStrategy as DocsBuildStrategy_2 } from '@backstage/plugin-techdocs-node';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
@@ -15,42 +14,15 @@ import express from 'express';
|
||||
import { GeneratorBuilder } from '@backstage/plugin-techdocs-node';
|
||||
import { HttpAuthService } from '@backstage/backend-plugin-api';
|
||||
import { Knex } from 'knex';
|
||||
import { Logger } from 'winston';
|
||||
import { Permission } from '@backstage/plugin-permission-common';
|
||||
import { PluginCacheManager } from '@backstage/backend-common';
|
||||
import { PreparerBuilder } from '@backstage/plugin-techdocs-node';
|
||||
import { PublisherBase } from '@backstage/plugin-techdocs-node';
|
||||
import type { TechDocsCollatorFactoryOptions as TechDocsCollatorFactoryOptions_2 } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import { TechDocsDocument as TechDocsDocument_2 } from '@backstage/plugin-techdocs-node';
|
||||
import { TokenManager } from '@backstage/backend-common';
|
||||
import * as winston from 'winston';
|
||||
|
||||
// @public @deprecated
|
||||
export function createRouter(options: RouterOptions): Promise<express.Router>;
|
||||
|
||||
// @public @deprecated
|
||||
export class DefaultTechDocsCollator {
|
||||
// (undocumented)
|
||||
protected applyArgsToFormat(
|
||||
format: string,
|
||||
args: Record<string, string>,
|
||||
): string;
|
||||
// (undocumented)
|
||||
execute(): Promise<TechDocsDocument_2[]>;
|
||||
// (undocumented)
|
||||
static fromConfig(
|
||||
config: Config,
|
||||
options: TechDocsCollatorOptions,
|
||||
): DefaultTechDocsCollator;
|
||||
// (undocumented)
|
||||
readonly type: string;
|
||||
// (undocumented)
|
||||
readonly visibilityPermission: Permission;
|
||||
}
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export const DefaultTechDocsCollatorFactory: typeof DefaultTechDocsCollatorFactory_2;
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type DocsBuildStrategy = DocsBuildStrategy_2;
|
||||
|
||||
@@ -95,20 +67,6 @@ export type ShouldBuildParameters = {
|
||||
entity: Entity;
|
||||
};
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type TechDocsCollatorFactoryOptions = TechDocsCollatorFactoryOptions_2;
|
||||
|
||||
// @public
|
||||
export type TechDocsCollatorOptions = {
|
||||
discovery: DiscoveryService;
|
||||
logger: Logger;
|
||||
tokenManager: TokenManager;
|
||||
locationTemplate?: string;
|
||||
catalogClient?: CatalogApi;
|
||||
parallelismLimit?: number;
|
||||
legacyPathCasing?: boolean;
|
||||
};
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type TechDocsDocument = TechDocsDocument_2;
|
||||
|
||||
|
||||
@@ -34,15 +34,6 @@ export type {
|
||||
OutOfTheBoxDeploymentOptions,
|
||||
} from './service';
|
||||
|
||||
export {
|
||||
DefaultTechDocsCollator,
|
||||
DefaultTechDocsCollatorFactory,
|
||||
} from './search';
|
||||
export type {
|
||||
TechDocsCollatorFactoryOptions,
|
||||
TechDocsCollatorOptions,
|
||||
} from './search';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated import from `@backstage/plugin-techdocs-node` instead
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 { TokenManager, loggerToWinstonLogger } from '@backstage/backend-common';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { DefaultTechDocsCollator } from './DefaultTechDocsCollator';
|
||||
import {
|
||||
mockServices,
|
||||
registerMswTestHooks,
|
||||
} from '@backstage/backend-test-utils';
|
||||
import { setupServer } from 'msw/node';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';
|
||||
|
||||
const logger = loggerToWinstonLogger(mockServices.logger.mock());
|
||||
|
||||
const mockSearchDocIndex = {
|
||||
config: {
|
||||
lang: ['en'],
|
||||
min_search_length: 3,
|
||||
prebuild_index: false,
|
||||
separator: '[\\s\\-]+',
|
||||
},
|
||||
docs: [
|
||||
{
|
||||
location: '',
|
||||
text: 'docs docs docs',
|
||||
title: 'Home',
|
||||
},
|
||||
{
|
||||
location: 'local-development/',
|
||||
text: 'Docs for first subtitle',
|
||||
title: 'Local development',
|
||||
},
|
||||
{
|
||||
location: 'local-development/#development',
|
||||
text: 'Docs for sub-subtitle',
|
||||
title: 'Development',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const expectedEntities: Entity[] = [
|
||||
{
|
||||
apiVersion: 'backstage.io/v1alpha1',
|
||||
kind: 'Component',
|
||||
metadata: {
|
||||
title: 'Test Entity with Docs!',
|
||||
name: 'test-entity-with-docs',
|
||||
description: 'Documented description',
|
||||
annotations: {
|
||||
[TECHDOCS_ANNOTATION]: './',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
type: 'dog',
|
||||
lifecycle: 'experimental',
|
||||
owner: 'someone',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
describe('TechDocs Collator', () => {
|
||||
const worker = setupServer();
|
||||
registerMswTestHooks(worker);
|
||||
|
||||
describe('DefaultTechDocsCollator with legacyPathCasing configuration', () => {
|
||||
const mockDiscoveryApi = mockServices.discovery.mock({
|
||||
getBaseUrl: async () => 'http://test-backend',
|
||||
});
|
||||
let mockTokenManager: jest.Mocked<TokenManager>;
|
||||
let collator: DefaultTechDocsCollator;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockTokenManager = {
|
||||
getToken: jest.fn().mockResolvedValue({ token: '' }),
|
||||
authenticate: jest.fn(),
|
||||
};
|
||||
const mockConfig = new ConfigReader({
|
||||
techdocs: {
|
||||
legacyUseCaseSensitiveTripletPaths: true,
|
||||
},
|
||||
});
|
||||
collator = DefaultTechDocsCollator.fromConfig(mockConfig, {
|
||||
discovery: mockDiscoveryApi,
|
||||
tokenManager: mockTokenManager,
|
||||
logger,
|
||||
legacyPathCasing: true,
|
||||
});
|
||||
|
||||
worker.use(
|
||||
http.get(
|
||||
'http://test-backend/static/docs/default/Component/test-entity-with-docs/search/search_index.json',
|
||||
() => HttpResponse.json(mockSearchDocIndex),
|
||||
),
|
||||
http.get('http://test-backend/entities', () =>
|
||||
HttpResponse.json(expectedEntities),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('fetches from the configured catalog and tech docs services', async () => {
|
||||
const documents = await collator.execute();
|
||||
expect(mockDiscoveryApi.getBaseUrl).toHaveBeenCalledWith('catalog');
|
||||
expect(mockDiscoveryApi.getBaseUrl).toHaveBeenCalledWith('techdocs');
|
||||
expect(documents).toHaveLength(mockSearchDocIndex.docs.length);
|
||||
});
|
||||
|
||||
it('should create documents for each tech docs search index', async () => {
|
||||
const documents = await collator.execute();
|
||||
const entity = expectedEntities[0];
|
||||
documents.forEach((document, idx) => {
|
||||
expect(document).toMatchObject({
|
||||
title: mockSearchDocIndex.docs[idx].title,
|
||||
location: `/docs/default/Component/${entity.metadata.name}/${mockSearchDocIndex.docs[idx].location}`,
|
||||
text: mockSearchDocIndex.docs[idx].text,
|
||||
namespace: 'default',
|
||||
entityTitle: entity!.metadata.title,
|
||||
componentType: entity!.spec!.type,
|
||||
lifecycle: entity!.spec!.lifecycle,
|
||||
owner: '',
|
||||
kind: entity.kind,
|
||||
name: entity.metadata.name,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('DefaultTechDocsCollator', () => {
|
||||
const mockDiscoveryApi = mockServices.discovery.mock({
|
||||
getBaseUrl: async () => 'http://test-backend',
|
||||
});
|
||||
let mockTokenManager: jest.Mocked<TokenManager>;
|
||||
let collator: DefaultTechDocsCollator;
|
||||
|
||||
beforeEach(() => {
|
||||
mockTokenManager = {
|
||||
getToken: jest.fn().mockResolvedValue({ token: '' }),
|
||||
authenticate: jest.fn(),
|
||||
};
|
||||
collator = DefaultTechDocsCollator.fromConfig(new ConfigReader({}), {
|
||||
discovery: mockDiscoveryApi,
|
||||
tokenManager: mockTokenManager,
|
||||
logger,
|
||||
});
|
||||
|
||||
worker.use(
|
||||
http.get(
|
||||
'http://test-backend/static/docs/default/component/test-entity-with-docs/search/search_index.json',
|
||||
() => HttpResponse.json(mockSearchDocIndex),
|
||||
),
|
||||
http.get('http://test-backend/entities', () =>
|
||||
HttpResponse.json(expectedEntities),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
||||
it('should create documents for each tech docs search index', async () => {
|
||||
const documents = await collator.execute();
|
||||
const entity = expectedEntities[0];
|
||||
documents.forEach((document, idx) => {
|
||||
expect(document).toMatchObject({
|
||||
title: mockSearchDocIndex.docs[idx].title,
|
||||
location: `/docs/default/component/${entity.metadata.name}/${mockSearchDocIndex.docs[idx].location}`,
|
||||
text: mockSearchDocIndex.docs[idx].text,
|
||||
namespace: 'default',
|
||||
entityTitle: entity!.metadata.title,
|
||||
componentType: entity!.spec!.type,
|
||||
lifecycle: entity!.spec!.lifecycle,
|
||||
owner: '',
|
||||
kind: entity.kind.toLocaleLowerCase('en-US'),
|
||||
name: entity.metadata.name.toLocaleLowerCase('en-US'),
|
||||
authorization: {
|
||||
resourceRef: `component:default/${entity.metadata.name}`,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('maps a returned entity with a custom locationTemplate', async () => {
|
||||
const mockConfig = new ConfigReader({
|
||||
techdocs: {
|
||||
legacyUseCaseSensitiveTripletPaths: true,
|
||||
},
|
||||
});
|
||||
// Provide an alternate location template.
|
||||
collator = DefaultTechDocsCollator.fromConfig(mockConfig, {
|
||||
discovery: mockDiscoveryApi,
|
||||
tokenManager: mockTokenManager,
|
||||
locationTemplate: '/software/:name',
|
||||
logger,
|
||||
});
|
||||
|
||||
const documents = await collator.execute();
|
||||
expect(documents[0]).toMatchObject({
|
||||
location: '/software/test-entity-with-docs',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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 { TokenManager } from '@backstage/backend-common';
|
||||
import {
|
||||
Entity,
|
||||
parseEntityRef,
|
||||
RELATION_OWNED_BY,
|
||||
stringifyEntityRef,
|
||||
} from '@backstage/catalog-model';
|
||||
import unescape from 'lodash/unescape';
|
||||
import { Logger } from 'winston';
|
||||
import pLimit from 'p-limit';
|
||||
import { Config } from '@backstage/config';
|
||||
import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha';
|
||||
import { Permission } from '@backstage/plugin-permission-common';
|
||||
import {
|
||||
CatalogApi,
|
||||
CatalogClient,
|
||||
CATALOG_FILTER_EXISTS,
|
||||
} from '@backstage/catalog-client';
|
||||
import { TechDocsDocument } from '@backstage/plugin-techdocs-node';
|
||||
import { TECHDOCS_ANNOTATION } from '@backstage/plugin-techdocs-common';
|
||||
import { DiscoveryService } from '@backstage/backend-plugin-api';
|
||||
|
||||
interface MkSearchIndexDoc {
|
||||
title: string;
|
||||
text: string;
|
||||
location: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to configure the TechDocs collator
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type TechDocsCollatorOptions = {
|
||||
discovery: DiscoveryService;
|
||||
logger: Logger;
|
||||
tokenManager: TokenManager;
|
||||
locationTemplate?: string;
|
||||
catalogClient?: CatalogApi;
|
||||
parallelismLimit?: number;
|
||||
legacyPathCasing?: boolean;
|
||||
};
|
||||
|
||||
type EntityInfo = {
|
||||
name: string;
|
||||
namespace: string;
|
||||
kind: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* A search collator responsible for gathering and transforming TechDocs documents.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Upgrade to a more recent `@backstage/plugin-search-backend-node` and
|
||||
* use `DefaultTechDocsCollatorFactory` instead.
|
||||
*/
|
||||
export class DefaultTechDocsCollator {
|
||||
public readonly type: string = 'techdocs';
|
||||
public readonly visibilityPermission: Permission =
|
||||
catalogEntityReadPermission;
|
||||
|
||||
private constructor(
|
||||
private readonly legacyPathCasing: boolean,
|
||||
private readonly options: TechDocsCollatorOptions,
|
||||
) {}
|
||||
|
||||
static fromConfig(config: Config, options: TechDocsCollatorOptions) {
|
||||
const legacyPathCasing =
|
||||
config.getOptionalBoolean(
|
||||
'techdocs.legacyUseCaseSensitiveTripletPaths',
|
||||
) || false;
|
||||
return new DefaultTechDocsCollator(legacyPathCasing, options);
|
||||
}
|
||||
|
||||
async execute() {
|
||||
const {
|
||||
parallelismLimit,
|
||||
discovery,
|
||||
tokenManager,
|
||||
catalogClient,
|
||||
locationTemplate,
|
||||
logger,
|
||||
} = this.options;
|
||||
const limit = pLimit(parallelismLimit ?? 10);
|
||||
const techDocsBaseUrl = await discovery.getBaseUrl('techdocs');
|
||||
const { token } = await tokenManager.getToken();
|
||||
const entities = await (
|
||||
catalogClient ?? new CatalogClient({ discoveryApi: discovery })
|
||||
).getEntities(
|
||||
{
|
||||
filter: {
|
||||
[`metadata.annotations.${TECHDOCS_ANNOTATION}`]:
|
||||
CATALOG_FILTER_EXISTS,
|
||||
},
|
||||
fields: [
|
||||
'kind',
|
||||
'namespace',
|
||||
'metadata.annotations',
|
||||
'metadata.name',
|
||||
'metadata.title',
|
||||
'metadata.namespace',
|
||||
'spec.type',
|
||||
'spec.lifecycle',
|
||||
'relations',
|
||||
],
|
||||
},
|
||||
{ token },
|
||||
);
|
||||
const docPromises = entities.items.map((entity: Entity) =>
|
||||
limit(async (): Promise<TechDocsDocument[]> => {
|
||||
const entityInfo = DefaultTechDocsCollator.handleEntityInfoCasing(
|
||||
this.legacyPathCasing ?? false,
|
||||
{
|
||||
kind: entity.kind,
|
||||
namespace: entity.metadata.namespace || 'default',
|
||||
name: entity.metadata.name,
|
||||
},
|
||||
);
|
||||
|
||||
try {
|
||||
const { token: newToken } = await tokenManager.getToken();
|
||||
const searchIndexResponse = await fetch(
|
||||
DefaultTechDocsCollator.constructDocsIndexUrl(
|
||||
techDocsBaseUrl,
|
||||
entityInfo,
|
||||
),
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${newToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
const searchIndex = await searchIndexResponse.json();
|
||||
|
||||
return searchIndex.docs.map((doc: MkSearchIndexDoc) => ({
|
||||
title: unescape(doc.title),
|
||||
text: unescape(doc.text || ''),
|
||||
location: this.applyArgsToFormat(
|
||||
locationTemplate || '/docs/:namespace/:kind/:name/:path',
|
||||
{
|
||||
...entityInfo,
|
||||
path: doc.location,
|
||||
},
|
||||
),
|
||||
path: doc.location,
|
||||
...entityInfo,
|
||||
entityTitle: entity.metadata.title,
|
||||
componentType: entity.spec?.type?.toString() || 'other',
|
||||
lifecycle: (entity.spec?.lifecycle as string) || '',
|
||||
owner: getSimpleEntityOwnerString(entity),
|
||||
authorization: {
|
||||
resourceRef: stringifyEntityRef(entity),
|
||||
},
|
||||
}));
|
||||
} catch (e) {
|
||||
logger.debug(
|
||||
`Failed to retrieve tech docs search index for entity ${entityInfo.namespace}/${entityInfo.kind}/${entityInfo.name}`,
|
||||
e,
|
||||
);
|
||||
return [];
|
||||
}
|
||||
}),
|
||||
);
|
||||
return (await Promise.all(docPromises)).flat();
|
||||
}
|
||||
|
||||
protected applyArgsToFormat(
|
||||
format: string,
|
||||
args: Record<string, string>,
|
||||
): string {
|
||||
let formatted = format;
|
||||
for (const [key, value] of Object.entries(args)) {
|
||||
formatted = formatted.replace(`:${key}`, value);
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
private static constructDocsIndexUrl(
|
||||
techDocsBaseUrl: string,
|
||||
entityInfo: { kind: string; namespace: string; name: string },
|
||||
) {
|
||||
return `${techDocsBaseUrl}/static/docs/${entityInfo.namespace}/${entityInfo.kind}/${entityInfo.name}/search/search_index.json`;
|
||||
}
|
||||
|
||||
private static handleEntityInfoCasing(
|
||||
legacyPaths: boolean,
|
||||
entityInfo: EntityInfo,
|
||||
): EntityInfo {
|
||||
return legacyPaths
|
||||
? entityInfo
|
||||
: Object.entries(entityInfo).reduce((acc, [key, value]) => {
|
||||
return { ...acc, [key]: value.toLocaleLowerCase('en-US') };
|
||||
}, {} as EntityInfo);
|
||||
}
|
||||
}
|
||||
|
||||
function getSimpleEntityOwnerString(entity: Entity): string {
|
||||
if (entity.relations) {
|
||||
const owner = entity.relations.find(r => r.type === RELATION_OWNED_BY);
|
||||
if (owner) {
|
||||
const { name } = parseEntityRef(owner.targetRef);
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* todo(backstage/techdocs-core): stop exporting these in a future release.
|
||||
*/
|
||||
export { DefaultTechDocsCollator } from './DefaultTechDocsCollator';
|
||||
export type { TechDocsCollatorOptions } from './DefaultTechDocsCollator';
|
||||
|
||||
import { DefaultTechDocsCollatorFactory as _DefaultTechDocsCollatorFactory } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
import type { TechDocsCollatorFactoryOptions as _TechDocsCollatorFactoryOptions } from '@backstage/plugin-search-backend-module-techdocs';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated import from `@backstage/plugin-search-backend-module-techdocs` instead
|
||||
*/
|
||||
export type TechDocsCollatorFactoryOptions = _TechDocsCollatorFactoryOptions;
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated import from `@backstage/plugin-search-backend-module-techdocs` instead
|
||||
*/
|
||||
export const DefaultTechDocsCollatorFactory = _DefaultTechDocsCollatorFactory;
|
||||
@@ -8093,7 +8093,6 @@ __metadata:
|
||||
resolution: "@backstage/plugin-search-backend-module-explore@workspace:plugins/search-backend-module-explore"
|
||||
dependencies:
|
||||
"@backstage-community/plugin-explore-common": ^0.0.7
|
||||
"@backstage/backend-common": ^0.25.0
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/cli": "workspace:^"
|
||||
@@ -8139,7 +8138,6 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@backstage/plugin-search-backend-module-techdocs@workspace:plugins/search-backend-module-techdocs"
|
||||
dependencies:
|
||||
"@backstage/backend-common": ^0.25.0
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
"@backstage/backend-test-utils": "workspace:^"
|
||||
"@backstage/catalog-client": "workspace:^"
|
||||
@@ -8183,7 +8181,6 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@backstage/plugin-search-backend@workspace:plugins/search-backend"
|
||||
dependencies:
|
||||
"@backstage/backend-common": ^0.25.0
|
||||
"@backstage/backend-defaults": "workspace:^"
|
||||
"@backstage/backend-openapi-utils": "workspace:^"
|
||||
"@backstage/backend-plugin-api": "workspace:^"
|
||||
|
||||
Reference in New Issue
Block a user