@rwdocs/backstage-plugin-search-backend-module-rw 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.d.ts +22 -0
- package/dist/collator/RwDocsCollatorFactory.cjs.js +139 -0
- package/dist/collator/RwDocsCollatorFactory.cjs.js.map +1 -0
- package/dist/index.cjs.js +10 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/module.cjs.js +41 -0
- package/dist/module.cjs.js.map +1 -0
- package/package.json +85 -0
package/config.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface Config {
|
|
2
|
+
search?: {
|
|
3
|
+
collators?: {
|
|
4
|
+
rw?: {
|
|
5
|
+
/**
|
|
6
|
+
* Schedule configuration. Parsed by Backstage's
|
|
7
|
+
* readSchedulerServiceTaskScheduleDefinitionFromConfig.
|
|
8
|
+
* Accepts HumanDuration values (minutes, hours, days, etc.) and cron expressions.
|
|
9
|
+
*/
|
|
10
|
+
schedule?: object;
|
|
11
|
+
/**
|
|
12
|
+
* Search result type identifier. Set to "techdocs" to unify RW docs
|
|
13
|
+
* results with TechDocs under the same search filter tab.
|
|
14
|
+
* @default 'rw'
|
|
15
|
+
*/
|
|
16
|
+
type?: string;
|
|
17
|
+
/** @default '/catalog/:namespace/:kind/:name/docs/:path' */
|
|
18
|
+
locationTemplate?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var stream = require('stream');
|
|
4
|
+
var alpha = require('@backstage/plugin-catalog-common/alpha');
|
|
5
|
+
var catalogClient = require('@backstage/catalog-client');
|
|
6
|
+
var catalogModel = require('@backstage/catalog-model');
|
|
7
|
+
var core = require('@rwdocs/core');
|
|
8
|
+
var backstagePluginRwCommon = require('@rwdocs/backstage-plugin-rw-common');
|
|
9
|
+
|
|
10
|
+
const RW_ANNOTATION = "rwdocs.org/ref";
|
|
11
|
+
const DEFAULT_LOCATION_TEMPLATE = "/catalog/:namespace/:kind/:name/docs/:path";
|
|
12
|
+
function applyLocationTemplate(template, params) {
|
|
13
|
+
return template.replace(":namespace", encodeURIComponent(params.namespace)).replace(":kind", encodeURIComponent(params.kind)).replace(":name", encodeURIComponent(params.name)).replace(":path", params.path);
|
|
14
|
+
}
|
|
15
|
+
function collectPaths(items) {
|
|
16
|
+
const paths = [];
|
|
17
|
+
for (const item of items) {
|
|
18
|
+
paths.push(item.path.replace(/^\//, ""));
|
|
19
|
+
if (item.children) {
|
|
20
|
+
paths.push(...collectPaths(item.children));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return paths;
|
|
24
|
+
}
|
|
25
|
+
class RwDocsCollatorFactory {
|
|
26
|
+
constructor(type, siteConfig, locationTemplate, logger, auth, catalog) {
|
|
27
|
+
this.siteConfig = siteConfig;
|
|
28
|
+
this.locationTemplate = locationTemplate;
|
|
29
|
+
this.logger = logger;
|
|
30
|
+
this.auth = auth;
|
|
31
|
+
this.catalog = catalog;
|
|
32
|
+
this.type = type;
|
|
33
|
+
}
|
|
34
|
+
type;
|
|
35
|
+
visibilityPermission = alpha.catalogEntityReadPermission;
|
|
36
|
+
static fromConfig(config, deps) {
|
|
37
|
+
const siteConfig = backstagePluginRwCommon.readRwSiteConfig(config);
|
|
38
|
+
const type = config.getOptionalString("search.collators.rw.type") ?? "rw";
|
|
39
|
+
const locationTemplate = config.getOptionalString("search.collators.rw.locationTemplate") ?? DEFAULT_LOCATION_TEMPLATE;
|
|
40
|
+
return new RwDocsCollatorFactory(
|
|
41
|
+
type,
|
|
42
|
+
siteConfig,
|
|
43
|
+
locationTemplate,
|
|
44
|
+
deps.logger,
|
|
45
|
+
deps.auth,
|
|
46
|
+
deps.catalog
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
async getCollator() {
|
|
50
|
+
return stream.Readable.from(this.execute());
|
|
51
|
+
}
|
|
52
|
+
async *execute() {
|
|
53
|
+
this.logger.info("Starting RW docs indexing");
|
|
54
|
+
const credentials = await this.auth.getOwnServiceCredentials();
|
|
55
|
+
const localEntityPath = this.siteConfig.entity ? backstagePluginRwCommon.toEntityPath(this.siteConfig.entity) : void 0;
|
|
56
|
+
let docCount = 0;
|
|
57
|
+
let cursor;
|
|
58
|
+
do {
|
|
59
|
+
const response = await this.catalog.queryEntities(
|
|
60
|
+
cursor ? { cursor } : {
|
|
61
|
+
filter: {
|
|
62
|
+
[`metadata.annotations.${RW_ANNOTATION}`]: catalogClient.CATALOG_FILTER_EXISTS
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{ credentials }
|
|
66
|
+
);
|
|
67
|
+
for (const entity of response.items) {
|
|
68
|
+
try {
|
|
69
|
+
for await (const doc of this.indexEntity(entity, localEntityPath)) {
|
|
70
|
+
docCount++;
|
|
71
|
+
yield doc;
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
const ref = catalogModel.stringifyEntityRef(entity);
|
|
75
|
+
this.logger.warn(`Failed to index entity ${ref}: ${err}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
cursor = response.pageInfo.nextCursor;
|
|
79
|
+
} while (cursor);
|
|
80
|
+
this.logger.info(`RW docs indexing complete: ${docCount} documents indexed`);
|
|
81
|
+
}
|
|
82
|
+
async *indexEntity(entity, localEntityPath) {
|
|
83
|
+
const annotationValue = entity.metadata?.annotations?.[RW_ANNOTATION];
|
|
84
|
+
const selfEntityPath = backstagePluginRwCommon.toEntityPath(catalogModel.stringifyEntityRef(entity));
|
|
85
|
+
const parsed = backstagePluginRwCommon.parseAnnotation(annotationValue, selfEntityPath);
|
|
86
|
+
if (!parsed) return;
|
|
87
|
+
if (localEntityPath && parsed.entityPath !== localEntityPath) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const site = this.createSite(parsed.entityPath);
|
|
91
|
+
const navigation = await site.getNavigation(parsed.sectionRef ?? null);
|
|
92
|
+
const scopePath = navigation.scope?.path?.replace(/^\//, "") ?? "";
|
|
93
|
+
const paths = collectPaths(navigation.items);
|
|
94
|
+
const entityRef = catalogModel.stringifyEntityRef(entity);
|
|
95
|
+
this.logger.info(`Indexing entity ${entityRef} (${paths.length} pages)`);
|
|
96
|
+
const ref = {
|
|
97
|
+
kind: entity.kind.toLocaleLowerCase("en-US"),
|
|
98
|
+
namespace: entity.metadata?.namespace ?? "default",
|
|
99
|
+
name: entity.metadata?.name
|
|
100
|
+
};
|
|
101
|
+
for (const path of paths) {
|
|
102
|
+
try {
|
|
103
|
+
const doc = await site.renderSearchDocument(path);
|
|
104
|
+
if (!doc) continue;
|
|
105
|
+
const relativePath = scopePath && path.startsWith(scopePath) ? path.slice(scopePath.length + 1) : path;
|
|
106
|
+
yield {
|
|
107
|
+
title: doc.title,
|
|
108
|
+
text: doc.text,
|
|
109
|
+
location: applyLocationTemplate(this.locationTemplate, {
|
|
110
|
+
namespace: ref.namespace,
|
|
111
|
+
kind: ref.kind,
|
|
112
|
+
name: ref.name,
|
|
113
|
+
path: relativePath
|
|
114
|
+
}),
|
|
115
|
+
authorization: {
|
|
116
|
+
resourceRef: entityRef
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
} catch (err) {
|
|
120
|
+
this.logger.warn(`Failed to render page ${path} for ${entityRef}: ${err}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
createSite(entityPath) {
|
|
125
|
+
if (this.siteConfig.projectDir) {
|
|
126
|
+
return core.createSite({
|
|
127
|
+
projectDir: this.siteConfig.projectDir,
|
|
128
|
+
diagrams: this.siteConfig.diagrams
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return core.createSite({
|
|
132
|
+
s3: { ...this.siteConfig.s3, entity: entityPath },
|
|
133
|
+
diagrams: this.siteConfig.diagrams
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
exports.RwDocsCollatorFactory = RwDocsCollatorFactory;
|
|
139
|
+
//# sourceMappingURL=RwDocsCollatorFactory.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RwDocsCollatorFactory.cjs.js","sources":["../../src/collator/RwDocsCollatorFactory.ts"],"sourcesContent":["import { Readable } from \"stream\";\nimport type { Config } from \"@backstage/config\";\nimport type { LoggerService, AuthService } from \"@backstage/backend-plugin-api\";\nimport type { CatalogService } from \"@backstage/plugin-catalog-node\";\nimport type { DocumentCollatorFactory, IndexableDocument } from \"@backstage/plugin-search-common\";\nimport type { Permission } from \"@backstage/plugin-permission-common\";\nimport { catalogEntityReadPermission } from \"@backstage/plugin-catalog-common/alpha\";\nimport { CATALOG_FILTER_EXISTS } from \"@backstage/catalog-client\";\nimport { stringifyEntityRef } from \"@backstage/catalog-model\";\nimport type { Entity } from \"@backstage/catalog-model\";\nimport { createSite, type RwSite, type NavItemResponse } from \"@rwdocs/core\";\nimport {\n parseAnnotation,\n toEntityPath,\n readRwSiteConfig,\n type RwSiteConfig,\n} from \"@rwdocs/backstage-plugin-rw-common\";\n\nconst RW_ANNOTATION = \"rwdocs.org/ref\";\nconst DEFAULT_LOCATION_TEMPLATE = \"/catalog/:namespace/:kind/:name/docs/:path\";\n\nfunction applyLocationTemplate(\n template: string,\n params: { namespace: string; kind: string; name: string; path: string },\n): string {\n return template\n .replace(\":namespace\", encodeURIComponent(params.namespace))\n .replace(\":kind\", encodeURIComponent(params.kind))\n .replace(\":name\", encodeURIComponent(params.name))\n .replace(\":path\", params.path);\n}\n\nfunction collectPaths(items: NavItemResponse[]): string[] {\n const paths: string[] = [];\n for (const item of items) {\n paths.push(item.path.replace(/^\\//, \"\"));\n if (item.children) {\n paths.push(...collectPaths(item.children));\n }\n }\n return paths;\n}\n\nexport class RwDocsCollatorFactory implements DocumentCollatorFactory {\n readonly type: string;\n readonly visibilityPermission: Permission = catalogEntityReadPermission;\n\n private constructor(\n type: string,\n private readonly siteConfig: RwSiteConfig,\n private readonly locationTemplate: string,\n private readonly logger: LoggerService,\n private readonly auth: AuthService,\n private readonly catalog: CatalogService,\n ) {\n this.type = type;\n }\n\n static fromConfig(\n config: Config,\n deps: {\n logger: LoggerService;\n auth: AuthService;\n catalog: CatalogService;\n },\n ): RwDocsCollatorFactory {\n const siteConfig = readRwSiteConfig(config);\n\n const type = config.getOptionalString(\"search.collators.rw.type\") ?? \"rw\";\n const locationTemplate =\n config.getOptionalString(\"search.collators.rw.locationTemplate\") ?? DEFAULT_LOCATION_TEMPLATE;\n\n return new RwDocsCollatorFactory(\n type,\n siteConfig,\n locationTemplate,\n deps.logger,\n deps.auth,\n deps.catalog,\n );\n }\n\n async getCollator(): Promise<Readable> {\n return Readable.from(this.execute());\n }\n\n private async *execute(): AsyncGenerator<IndexableDocument> {\n this.logger.info(\"Starting RW docs indexing\");\n const credentials = await this.auth.getOwnServiceCredentials();\n const localEntityPath = this.siteConfig.entity\n ? toEntityPath(this.siteConfig.entity)\n : undefined;\n\n let docCount = 0;\n let cursor: string | undefined;\n\n do {\n const response = await this.catalog.queryEntities(\n cursor\n ? { cursor }\n : {\n filter: {\n [`metadata.annotations.${RW_ANNOTATION}`]: CATALOG_FILTER_EXISTS,\n },\n },\n { credentials },\n );\n\n for (const entity of response.items) {\n try {\n for await (const doc of this.indexEntity(entity, localEntityPath)) {\n docCount++;\n yield doc;\n }\n } catch (err) {\n const ref = stringifyEntityRef(entity);\n this.logger.warn(`Failed to index entity ${ref}: ${err}`);\n }\n }\n\n cursor = response.pageInfo.nextCursor;\n } while (cursor);\n\n this.logger.info(`RW docs indexing complete: ${docCount} documents indexed`);\n }\n\n private async *indexEntity(\n entity: Entity,\n localEntityPath: string | undefined,\n ): AsyncGenerator<IndexableDocument> {\n const annotationValue = entity.metadata?.annotations?.[RW_ANNOTATION];\n const selfEntityPath = toEntityPath(stringifyEntityRef(entity));\n const parsed = parseAnnotation(annotationValue, selfEntityPath);\n if (!parsed) return;\n\n // In projectDir mode, skip entities whose target doesn't match the configured entity\n if (localEntityPath && parsed.entityPath !== localEntityPath) {\n return;\n }\n\n const site = this.createSite(parsed.entityPath);\n const navigation = await site.getNavigation(parsed.sectionRef ?? null);\n const scopePath = navigation.scope?.path?.replace(/^\\//, \"\") ?? \"\";\n const paths = collectPaths(navigation.items);\n\n const entityRef = stringifyEntityRef(entity);\n this.logger.info(`Indexing entity ${entityRef} (${paths.length} pages)`);\n const ref = {\n kind: entity.kind.toLocaleLowerCase(\"en-US\"),\n namespace: entity.metadata?.namespace ?? \"default\",\n name: entity.metadata?.name as string,\n };\n\n for (const path of paths) {\n try {\n const doc = await site.renderSearchDocument(path);\n if (!doc) continue;\n\n const relativePath =\n scopePath && path.startsWith(scopePath) ? path.slice(scopePath.length + 1) : path;\n\n yield {\n title: doc.title,\n text: doc.text,\n location: applyLocationTemplate(this.locationTemplate, {\n namespace: ref.namespace,\n kind: ref.kind,\n name: ref.name,\n path: relativePath,\n }),\n authorization: {\n resourceRef: entityRef,\n },\n };\n } catch (err) {\n this.logger.warn(`Failed to render page ${path} for ${entityRef}: ${err}`);\n }\n }\n }\n\n private createSite(entityPath: string): RwSite {\n if (this.siteConfig.projectDir) {\n return createSite({\n projectDir: this.siteConfig.projectDir,\n diagrams: this.siteConfig.diagrams,\n });\n }\n\n return createSite({\n s3: { ...this.siteConfig.s3!, entity: entityPath },\n diagrams: this.siteConfig.diagrams,\n });\n }\n}\n"],"names":["catalogEntityReadPermission","readRwSiteConfig","Readable","toEntityPath","CATALOG_FILTER_EXISTS","stringifyEntityRef","parseAnnotation","createSite"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
6
|
+
var alpha = require('@backstage/plugin-search-backend-node/alpha');
|
|
7
|
+
var pluginCatalogNode = require('@backstage/plugin-catalog-node');
|
|
8
|
+
var RwDocsCollatorFactory = require('./collator/RwDocsCollatorFactory.cjs.js');
|
|
9
|
+
|
|
10
|
+
var module$1 = backendPluginApi.createBackendModule({
|
|
11
|
+
pluginId: "search",
|
|
12
|
+
moduleId: "rw-collator",
|
|
13
|
+
register(env) {
|
|
14
|
+
env.registerInit({
|
|
15
|
+
deps: {
|
|
16
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
17
|
+
logger: backendPluginApi.coreServices.logger,
|
|
18
|
+
scheduler: backendPluginApi.coreServices.scheduler,
|
|
19
|
+
auth: backendPluginApi.coreServices.auth,
|
|
20
|
+
indexRegistry: alpha.searchIndexRegistryExtensionPoint,
|
|
21
|
+
catalog: pluginCatalogNode.catalogServiceRef
|
|
22
|
+
},
|
|
23
|
+
async init({ config, logger, scheduler, auth, indexRegistry, catalog }) {
|
|
24
|
+
const schedule = config.has("search.collators.rw.schedule") ? backendPluginApi.readSchedulerServiceTaskScheduleDefinitionFromConfig(
|
|
25
|
+
config.getConfig("search.collators.rw.schedule")
|
|
26
|
+
) : {
|
|
27
|
+
frequency: { minutes: 10 },
|
|
28
|
+
timeout: { minutes: 15 },
|
|
29
|
+
initialDelay: { seconds: 3 }
|
|
30
|
+
};
|
|
31
|
+
indexRegistry.addCollator({
|
|
32
|
+
schedule: scheduler.createScheduledTaskRunner(schedule),
|
|
33
|
+
factory: RwDocsCollatorFactory.RwDocsCollatorFactory.fromConfig(config, { logger, auth, catalog })
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
exports.default = module$1;
|
|
41
|
+
//# sourceMappingURL=module.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.cjs.js","sources":["../src/module.ts"],"sourcesContent":["import {\n coreServices,\n createBackendModule,\n readSchedulerServiceTaskScheduleDefinitionFromConfig,\n} from \"@backstage/backend-plugin-api\";\nimport { searchIndexRegistryExtensionPoint } from \"@backstage/plugin-search-backend-node/alpha\";\nimport { catalogServiceRef } from \"@backstage/plugin-catalog-node\";\nimport { RwDocsCollatorFactory } from \"./collator/RwDocsCollatorFactory\";\n\nexport default createBackendModule({\n pluginId: \"search\",\n moduleId: \"rw-collator\",\n register(env) {\n env.registerInit({\n deps: {\n config: coreServices.rootConfig,\n logger: coreServices.logger,\n scheduler: coreServices.scheduler,\n auth: coreServices.auth,\n indexRegistry: searchIndexRegistryExtensionPoint,\n catalog: catalogServiceRef,\n },\n async init({ config, logger, scheduler, auth, indexRegistry, catalog }) {\n const schedule = config.has(\"search.collators.rw.schedule\")\n ? readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config.getConfig(\"search.collators.rw.schedule\"),\n )\n : {\n frequency: { minutes: 10 },\n timeout: { minutes: 15 },\n initialDelay: { seconds: 3 },\n };\n\n indexRegistry.addCollator({\n schedule: scheduler.createScheduledTaskRunner(schedule),\n factory: RwDocsCollatorFactory.fromConfig(config, { logger, auth, catalog }),\n });\n },\n });\n },\n});\n"],"names":["createBackendModule","coreServices","searchIndexRegistryExtensionPoint","catalogServiceRef","readSchedulerServiceTaskScheduleDefinitionFromConfig","RwDocsCollatorFactory"],"mappings":";;;;;;;;;AASA,eAAeA,oCAAA,CAAoB;AAAA,EACjC,QAAA,EAAU,QAAA;AAAA,EACV,QAAA,EAAU,aAAA;AAAA,EACV,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,YAAA,CAAa;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,QAAQC,6BAAA,CAAa,UAAA;AAAA,QACrB,QAAQA,6BAAA,CAAa,MAAA;AAAA,QACrB,WAAWA,6BAAA,CAAa,SAAA;AAAA,QACxB,MAAMA,6BAAA,CAAa,IAAA;AAAA,QACnB,aAAA,EAAeC,uCAAA;AAAA,QACf,OAAA,EAASC;AAAA,OACX;AAAA,MACA,MAAM,KAAK,EAAE,MAAA,EAAQ,QAAQ,SAAA,EAAW,IAAA,EAAM,aAAA,EAAe,OAAA,EAAQ,EAAG;AACtE,QAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,8BAA8B,CAAA,GACtDC,qEAAA;AAAA,UACE,MAAA,CAAO,UAAU,8BAA8B;AAAA,SACjD,GACA;AAAA,UACE,SAAA,EAAW,EAAE,OAAA,EAAS,EAAA,EAAG;AAAA,UACzB,OAAA,EAAS,EAAE,OAAA,EAAS,EAAA,EAAG;AAAA,UACvB,YAAA,EAAc,EAAE,OAAA,EAAS,CAAA;AAAE,SAC7B;AAEJ,QAAA,aAAA,CAAc,WAAA,CAAY;AAAA,UACxB,QAAA,EAAU,SAAA,CAAU,yBAAA,CAA0B,QAAQ,CAAA;AAAA,UACtD,OAAA,EAASC,4CAAsB,UAAA,CAAW,MAAA,EAAQ,EAAE,MAAA,EAAQ,IAAA,EAAM,SAAS;AAAA,SAC5E,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC,CAAA;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rwdocs/backstage-plugin-search-backend-module-rw",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"license": "MIT OR Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/rwdocs/backstage-plugins.git",
|
|
8
|
+
"directory": "plugins/search-backend-module-rw"
|
|
9
|
+
},
|
|
10
|
+
"main": "dist/index.cjs.js",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"backstage": "@backstage/BackendFeature",
|
|
15
|
+
"require": "./dist/index.cjs.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.cjs.js"
|
|
18
|
+
},
|
|
19
|
+
"./package.json": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public",
|
|
23
|
+
"main": "dist/index.cjs.js",
|
|
24
|
+
"types": "dist/index.d.ts"
|
|
25
|
+
},
|
|
26
|
+
"backstage": {
|
|
27
|
+
"role": "backend-plugin-module",
|
|
28
|
+
"pluginId": "search",
|
|
29
|
+
"pluginPackage": "@backstage/plugin-search-backend",
|
|
30
|
+
"features": {
|
|
31
|
+
".": "@backstage/BackendFeature"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"configSchema": "config.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"config.d.ts",
|
|
38
|
+
"LICENSE-MIT",
|
|
39
|
+
"LICENSE-APACHE"
|
|
40
|
+
],
|
|
41
|
+
"scripts": {
|
|
42
|
+
"start": "backstage-cli package start",
|
|
43
|
+
"build": "backstage-cli package build",
|
|
44
|
+
"lint": "backstage-cli package lint",
|
|
45
|
+
"test": "backstage-cli package test",
|
|
46
|
+
"clean": "backstage-cli package clean",
|
|
47
|
+
"format": "prettier --write src/",
|
|
48
|
+
"format:check": "prettier --check src/",
|
|
49
|
+
"prepack": "backstage-cli package prepack",
|
|
50
|
+
"postpack": "backstage-cli package postpack"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@backstage/catalog-client": "^1.9.3",
|
|
54
|
+
"@backstage/catalog-model": "^1.7.6",
|
|
55
|
+
"@backstage/config": "^1.3.6",
|
|
56
|
+
"@backstage/plugin-catalog-common": "^1.1.5",
|
|
57
|
+
"@backstage/plugin-permission-common": "^0.9.6",
|
|
58
|
+
"@backstage/plugin-search-common": "^1.2.16",
|
|
59
|
+
"@rwdocs/backstage-plugin-rw-common": "^0.1.4",
|
|
60
|
+
"@rwdocs/core": "^0.1.22"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"@backstage/backend-plugin-api": "^1.0.0",
|
|
64
|
+
"@backstage/plugin-catalog-node": "^1.16.0",
|
|
65
|
+
"@backstage/plugin-search-backend-node": "^1.3.10"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@backstage/backend-plugin-api": "^1.0.0",
|
|
69
|
+
"@backstage/backend-test-utils": "^1.11.0",
|
|
70
|
+
"@backstage/cli": "^0.36.0",
|
|
71
|
+
"@backstage/plugin-catalog-node": "^2.0.0",
|
|
72
|
+
"@backstage/plugin-search-backend-node": "^1.3.10",
|
|
73
|
+
"@types/jest": "^30.0.0",
|
|
74
|
+
"jest": "^30.2.0",
|
|
75
|
+
"prettier": "^3.4.2",
|
|
76
|
+
"typescript": "^5.7.0"
|
|
77
|
+
},
|
|
78
|
+
"typesVersions": {
|
|
79
|
+
"*": {
|
|
80
|
+
"package.json": [
|
|
81
|
+
"package.json"
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|