@red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend 0.3.0
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/CHANGELOG.md +25 -0
- package/README.md +37 -0
- package/dist/index.cjs.js +10 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/plugin.cjs.js +164 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/package.json +65 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 986f8ad: Backstage version bump to v1.42.5
|
|
8
|
+
|
|
9
|
+
## 0.2.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 551bffa: remove backend catalog dependency
|
|
14
|
+
|
|
15
|
+
## 0.2.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 237c394: removing temporary duplicate code for model catalog bridge config now that 'catalog-backend-module-model-config' exposes the requisite types/methods
|
|
20
|
+
|
|
21
|
+
## 0.2.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- 7dc735d: a new backstage plugin, a sevice factory, is delivered to provide a URLReader that interacts with the model catalog bridges techdoc/model card endpoint; the catalog backend module is also updated so that the bridge configration information is exported and reusable by the techdoc plugin
|
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# catalog-techdoc-url-reader
|
|
2
|
+
|
|
3
|
+
This plugin backend provides implementations around the [URL Readers](https://backstage.io/docs/backend-system/core-services/url-reader) extension point of Backstage's Core Services. We introduce the extension via a Backstage service factory, per the documentation.
|
|
4
|
+
|
|
5
|
+
Our new URL Reader here allows for TechDoc generation to access a REST API provided by the RHDH Model Catalog Bridge. This allows AI Platform Engineers to leverage AI Model Cards provided by Red Hat OpenShift AI (RHOAI) as the TechDocs for the AI Models that the RHDH Model Catalog Bridge imports into the Backstage Catalog included with RHDH.
|
|
6
|
+
|
|
7
|
+
Coupled with our `URLReaderService` implementation is also an customized implementation of the Backstage `UrlReaderServiceReadTreeResponse` interface. This implemenation both
|
|
8
|
+
facilitates customization of how the Model Catalog Bridge REST APIs for TechDocs are accessed, and allows for future customization of the final TechDoc compilation, in the event we want to augment the RHOAI Model Cards to leverage the varioud Backstage TechDoc extensions and addons.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
This plugin is installed via the `@@red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend` package. To install it to your backend package, run the following command:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# From your root directory
|
|
16
|
+
yarn --cwd packages/backend add @@red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then add the plugin to your backend in `packages/backend/src/index.ts`:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const backend = createBackend();
|
|
23
|
+
// ...
|
|
24
|
+
backend.add(
|
|
25
|
+
import(
|
|
26
|
+
'@@red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend'
|
|
27
|
+
),
|
|
28
|
+
);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Development
|
|
32
|
+
|
|
33
|
+
This plugin backend can be started in a standalone mode from directly in this
|
|
34
|
+
package with `yarn start`. It is a limited setup that is most convenient when
|
|
35
|
+
developing the plugin backend itself.
|
|
36
|
+
|
|
37
|
+
If you want to run the entire project, including the frontend, run `yarn dev` from the root directory.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
3
|
+
import { ReaderFactory } from '@backstage/backend-defaults/urlReader';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* catalogTechdocUrlReaderPlugin define the factory for the ModelCatalogBridgeUrlReader service
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
declare const catalogTechdocUrlReaderPlugin: _backstage_backend_plugin_api.ServiceFactory<ReaderFactory, "plugin", "multiton">;
|
|
11
|
+
|
|
12
|
+
export { catalogTechdocUrlReaderPlugin as default };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var urlReader = require('@backstage/backend-defaults/urlReader');
|
|
4
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
5
|
+
var errors = require('@backstage/errors');
|
|
6
|
+
var fs = require('fs');
|
|
7
|
+
var platformPath = require('path');
|
|
8
|
+
var os = require('os');
|
|
9
|
+
|
|
10
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
13
|
+
var platformPath__default = /*#__PURE__*/_interopDefaultCompat(platformPath);
|
|
14
|
+
var os__default = /*#__PURE__*/_interopDefaultCompat(os);
|
|
15
|
+
|
|
16
|
+
class ModelCatalogBridgeUrlReaderServiceReadTreeResponse {
|
|
17
|
+
constructor(workDir, etag, buffer, logger) {
|
|
18
|
+
this.workDir = workDir;
|
|
19
|
+
this.etag = etag;
|
|
20
|
+
this.buffer = buffer;
|
|
21
|
+
this.logger = logger;
|
|
22
|
+
this.logger = logger.child({
|
|
23
|
+
source: 'ModelCatalogBridgeUrlReaderServiceReadTreeResponse"'
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async files() {
|
|
27
|
+
throw new Error(
|
|
28
|
+
"ModelCatalogBridgeUrlReaderServiceReadTreeResponse does not implement files"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
async archive() {
|
|
32
|
+
throw new Error(
|
|
33
|
+
"ModelCatalogBridgeUrlReaderServiceReadTreeResponse does not implement archive"
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
async dir(options) {
|
|
37
|
+
const dir = options?.targetDir ?? await fs__default.default.promises.mkdtemp(
|
|
38
|
+
platformPath__default.default.join(this.workDir, "backstage-")
|
|
39
|
+
);
|
|
40
|
+
const subDir = platformPath__default.default.join(dir, "docs");
|
|
41
|
+
const filePath = platformPath__default.default.join(subDir, "index.md");
|
|
42
|
+
try {
|
|
43
|
+
fs__default.default.mkdirSync(subDir);
|
|
44
|
+
const buf = await this.buffer;
|
|
45
|
+
await fs__default.default.promises.writeFile(filePath, buf);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
this.logger.error(`Error writing to file ${filePath}:`, error);
|
|
48
|
+
}
|
|
49
|
+
return dir;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function readBridgeConfigs(config) {
|
|
53
|
+
const configs = config.getOptionalConfig("catalog.providers.modelCatalog");
|
|
54
|
+
if (!configs) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
return configs.keys().map((id) => readBridgeConfig(id, configs.getConfig(id)));
|
|
58
|
+
}
|
|
59
|
+
function readBridgeConfig(id, config) {
|
|
60
|
+
const url = config.getString("baseUrl");
|
|
61
|
+
return { id, baseUrl: url };
|
|
62
|
+
}
|
|
63
|
+
class ModeCatalogBridgeTechdocUrlReader {
|
|
64
|
+
workDir;
|
|
65
|
+
logger;
|
|
66
|
+
bridgeConfigs;
|
|
67
|
+
static factory = ({ config, logger }) => {
|
|
68
|
+
const reader = new ModeCatalogBridgeTechdocUrlReader(config, logger);
|
|
69
|
+
const predicate = (url) => reader.bridgePredicate(url);
|
|
70
|
+
return [{ reader, predicate }];
|
|
71
|
+
};
|
|
72
|
+
constructor(config, logger) {
|
|
73
|
+
this.logger = logger.child({
|
|
74
|
+
source: 'ModeCatalogBridgeTechdocUrlReader"'
|
|
75
|
+
});
|
|
76
|
+
this.bridgeConfigs = readBridgeConfigs(config);
|
|
77
|
+
this.workDir = os__default.default.tmpdir();
|
|
78
|
+
const bkend = config.getOptionalString("backend.workingDirectory");
|
|
79
|
+
if (bkend) {
|
|
80
|
+
this.workDir = bkend;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
bridgePredicate = (url) => {
|
|
84
|
+
for (let index = 0; index < this.bridgeConfigs.length; index++) {
|
|
85
|
+
const bc = this.bridgeConfigs[index];
|
|
86
|
+
const bcUrl = new URL(bc.baseUrl);
|
|
87
|
+
if (url.hostname === bcUrl.hostname && url.port === bcUrl.port && url.pathname.startsWith("/modelcard")) {
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (url.hostname === "localhost" && url.port === "9090" && url.pathname.startsWith("/modelcard")) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
};
|
|
96
|
+
async readUrl(url, options) {
|
|
97
|
+
this.logger.info(`ModelCatalogBridgeTechdocUrlReader.readUrl of ${url}`);
|
|
98
|
+
let response;
|
|
99
|
+
try {
|
|
100
|
+
response = await fetch(url, {
|
|
101
|
+
signal: options?.signal
|
|
102
|
+
});
|
|
103
|
+
} catch (e) {
|
|
104
|
+
throw new Error(`Unable to read ${url}, ${e}`);
|
|
105
|
+
}
|
|
106
|
+
if (response.ok) {
|
|
107
|
+
return urlReader.ReadUrlResponseFactory.fromResponse(response);
|
|
108
|
+
}
|
|
109
|
+
const message = `could not read ${url}, ${response.status} ${response.statusText}`;
|
|
110
|
+
if (response.status === 404) {
|
|
111
|
+
throw new errors.NotFoundError(message);
|
|
112
|
+
}
|
|
113
|
+
if (response.status === 304) {
|
|
114
|
+
throw new errors.NotModifiedError();
|
|
115
|
+
}
|
|
116
|
+
throw new Error(message);
|
|
117
|
+
}
|
|
118
|
+
async search(url, options) {
|
|
119
|
+
this.logger.info(
|
|
120
|
+
`ModelCatalogBridgeTechdocUrlReader.search of ${url} with options ${JSON.stringify(
|
|
121
|
+
options
|
|
122
|
+
)}`
|
|
123
|
+
);
|
|
124
|
+
throw new Error(
|
|
125
|
+
"ModeCatalogBridgeTechdocUrlReader does not implement search"
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
async readTree(url, options) {
|
|
129
|
+
this.logger.info(`ModelCatalogBridgeTechdocUrlReader.readTree of ${url}`);
|
|
130
|
+
const data = await this.readUrl(url, options);
|
|
131
|
+
const et = options?.etag;
|
|
132
|
+
if (!et) {
|
|
133
|
+
return await new ModelCatalogBridgeUrlReaderServiceReadTreeResponse(
|
|
134
|
+
this.workDir,
|
|
135
|
+
"",
|
|
136
|
+
data.buffer(),
|
|
137
|
+
this.logger
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return await new ModelCatalogBridgeUrlReaderServiceReadTreeResponse(
|
|
141
|
+
this.workDir,
|
|
142
|
+
et,
|
|
143
|
+
data.buffer(),
|
|
144
|
+
this.logger
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const catalogTechdocUrlReaderPlugin = backendPluginApi.createServiceFactory({
|
|
149
|
+
service: urlReader.urlReaderFactoriesServiceRef,
|
|
150
|
+
deps: {
|
|
151
|
+
logger: backendPluginApi.coreServices.logger
|
|
152
|
+
},
|
|
153
|
+
async factory({ logger }) {
|
|
154
|
+
logger.child({ source: 'catalogTechdocUrlReaderPlugin"' }).info("Registering the model catalog bridge URL reader ");
|
|
155
|
+
return ModeCatalogBridgeTechdocUrlReader.factory;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
exports.ModeCatalogBridgeTechdocUrlReader = ModeCatalogBridgeTechdocUrlReader;
|
|
160
|
+
exports.ModelCatalogBridgeUrlReaderServiceReadTreeResponse = ModelCatalogBridgeUrlReaderServiceReadTreeResponse;
|
|
161
|
+
exports.catalogTechdocUrlReaderPlugin = catalogTechdocUrlReaderPlugin;
|
|
162
|
+
exports.readBridgeConfig = readBridgeConfig;
|
|
163
|
+
exports.readBridgeConfigs = readBridgeConfigs;
|
|
164
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n ReaderFactory,\n ReadUrlResponseFactory,\n urlReaderFactoriesServiceRef,\n} from '@backstage/backend-defaults/urlReader';\nimport {\n coreServices,\n createServiceFactory,\n UrlReaderService,\n UrlReaderServiceReadUrlOptions,\n UrlReaderServiceSearchOptions,\n UrlReaderServiceSearchResponse,\n UrlReaderServiceReadUrlResponse,\n UrlReaderServiceReadTreeOptions,\n UrlReaderServiceReadTreeResponse,\n UrlReaderServiceReadTreeResponseFile,\n UrlReaderServiceReadTreeResponseDirOptions,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { NotFoundError, NotModifiedError } from '@backstage/errors';\nimport { Readable } from 'stream';\nimport fs from 'fs';\nimport platformPath from 'path';\nimport os from 'os';\n\nexport class ModelCatalogBridgeUrlReaderServiceReadTreeResponse\n implements UrlReaderServiceReadTreeResponse\n{\n constructor(\n private readonly workDir: string,\n public readonly etag: string,\n private readonly buffer: Promise<Buffer>,\n private readonly logger: LoggerService,\n ) {\n this.logger = logger.child({\n source: 'ModelCatalogBridgeUrlReaderServiceReadTreeResponse\"',\n });\n }\n async files(): Promise<UrlReaderServiceReadTreeResponseFile[]> {\n throw new Error(\n 'ModelCatalogBridgeUrlReaderServiceReadTreeResponse does not implement files',\n );\n }\n async archive(): Promise<Readable> {\n throw new Error(\n 'ModelCatalogBridgeUrlReaderServiceReadTreeResponse does not implement archive',\n );\n }\n\n async dir(\n options?: UrlReaderServiceReadTreeResponseDirOptions,\n ): Promise<string> {\n const dir =\n options?.targetDir ??\n (await fs.promises.mkdtemp(\n platformPath.join(this.workDir, 'backstage-'),\n ));\n\n const subDir = platformPath.join(dir, 'docs');\n const filePath = platformPath.join(subDir, 'index.md');\n try {\n fs.mkdirSync(subDir);\n const buf = await this.buffer;\n await fs.promises.writeFile(filePath, buf);\n } catch (error) {\n this.logger.error(`Error writing to file ${filePath}:`, error);\n }\n\n return dir;\n }\n}\n\nexport type BridgeConfig = {\n id: string;\n baseUrl: string;\n};\n\nexport function readBridgeConfigs(config: Config): BridgeConfig[] {\n const configs = config.getOptionalConfig('catalog.providers.modelCatalog');\n if (!configs) {\n return [];\n }\n return configs.keys().map(id => readBridgeConfig(id, configs.getConfig(id)));\n}\n\nexport function readBridgeConfig(id: string, config: Config): BridgeConfig {\n const url = config.getString('baseUrl');\n return { id, baseUrl: url };\n}\n\nexport class ModeCatalogBridgeTechdocUrlReader implements UrlReaderService {\n private readonly workDir: string;\n private readonly logger: LoggerService;\n private readonly bridgeConfigs: BridgeConfig[];\n\n static factory: ReaderFactory = ({ config, logger }) => {\n const reader = new ModeCatalogBridgeTechdocUrlReader(config, logger);\n const predicate = (url: URL) => reader.bridgePredicate(url);\n\n return [{ reader, predicate }];\n };\n\n constructor(config: Config, logger: LoggerService) {\n this.logger = logger.child({\n source: 'ModeCatalogBridgeTechdocUrlReader\"',\n });\n this.bridgeConfigs = readBridgeConfigs(config);\n this.workDir = os.tmpdir();\n\n const bkend = config.getOptionalString('backend.workingDirectory');\n if (bkend) {\n this.workDir = bkend;\n }\n }\n\n bridgePredicate = (url: URL): boolean => {\n for (let index = 0; index < this.bridgeConfigs.length; index++) {\n const bc = this.bridgeConfigs[index];\n const bcUrl = new URL(bc.baseUrl);\n if (\n url.hostname === bcUrl.hostname &&\n url.port === bcUrl.port &&\n url.pathname.startsWith('/modelcard')\n ) {\n return true;\n }\n }\n if (\n url.hostname === 'localhost' &&\n url.port === '9090' &&\n url.pathname.startsWith('/modelcard')\n ) {\n return true;\n }\n return false;\n };\n\n async readUrl(\n url: string,\n options?: UrlReaderServiceReadUrlOptions,\n ): Promise<UrlReaderServiceReadUrlResponse> {\n this.logger.info(`ModelCatalogBridgeTechdocUrlReader.readUrl of ${url}`);\n let response: Response;\n try {\n response = await fetch(url, {\n signal: options?.signal as any,\n });\n } catch (e) {\n throw new Error(`Unable to read ${url}, ${e}`);\n }\n\n if (response.ok) {\n return ReadUrlResponseFactory.fromResponse(response);\n }\n\n const message = `could not read ${url}, ${response.status} ${response.statusText}`;\n if (response.status === 404) {\n throw new NotFoundError(message);\n }\n if (response.status === 304) {\n throw new NotModifiedError();\n }\n throw new Error(message);\n }\n\n async search(\n url: string,\n options?: UrlReaderServiceSearchOptions,\n ): Promise<UrlReaderServiceSearchResponse> {\n this.logger.info(\n `ModelCatalogBridgeTechdocUrlReader.search of ${url} with options ${JSON.stringify(\n options,\n )}`,\n );\n\n throw new Error(\n 'ModeCatalogBridgeTechdocUrlReader does not implement search',\n );\n // const { pathname } = new URL(url);\n\n // if (pathname.match(/[*?]/)) {\n // throw new Error('Unsupported search pattern URL');\n // }\n\n // try {\n // const data = await this.readUrl(url, options);\n\n // return {\n // files: [\n // {\n // url: url,\n // content: data.buffer,\n // lastModifiedAt: data.lastModifiedAt,\n // },\n // ],\n // etag: data.etag ?? '',\n // };\n // } catch (error) {\n // assertError(error);\n // if (error.name === 'NotFoundError') {\n // return {\n // files: [],\n // etag: '',\n // };\n // }\n // throw error;\n // }\n }\n\n async readTree(\n url: string,\n options?: UrlReaderServiceReadTreeOptions,\n ): Promise<UrlReaderServiceReadTreeResponse> {\n this.logger.info(`ModelCatalogBridgeTechdocUrlReader.readTree of ${url}`);\n const data = await this.readUrl(url, options);\n\n const et = options?.etag;\n if (!et) {\n return await new ModelCatalogBridgeUrlReaderServiceReadTreeResponse(\n this.workDir,\n '',\n data.buffer(),\n this.logger,\n );\n }\n return await new ModelCatalogBridgeUrlReaderServiceReadTreeResponse(\n this.workDir,\n et,\n data.buffer(),\n this.logger,\n );\n }\n}\n\n/**\n * catalogTechdocUrlReaderPlugin define the factory for the ModelCatalogBridgeUrlReader service\n *\n * @public\n */\nexport const catalogTechdocUrlReaderPlugin = createServiceFactory({\n service: urlReaderFactoriesServiceRef,\n deps: {\n logger: coreServices.logger,\n },\n async factory({ logger }) {\n logger\n .child({ source: 'catalogTechdocUrlReaderPlugin\"' })\n .info('Registering the model catalog bridge URL reader ');\n\n return ModeCatalogBridgeTechdocUrlReader.factory;\n },\n});\n"],"names":["fs","platformPath","os","ReadUrlResponseFactory","NotFoundError","NotModifiedError","createServiceFactory","urlReaderFactoriesServiceRef","coreServices"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.cjs.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/redhat-developer/rhdh-plugins",
|
|
15
|
+
"directory": "workspaces/ai-integrations/plugins/catalog-techdoc-url-reader-backend"
|
|
16
|
+
},
|
|
17
|
+
"backstage": {
|
|
18
|
+
"role": "backend-plugin",
|
|
19
|
+
"pluginId": "catalog-techdoc-url-reader-backend",
|
|
20
|
+
"pluginPackages": [
|
|
21
|
+
"@red-hat-developer-hub/backstage-plugin-catalog-techdoc-url-reader-backend"
|
|
22
|
+
],
|
|
23
|
+
"features": {
|
|
24
|
+
".": "@backstage/BackendFeature"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"start": "backstage-cli package start",
|
|
29
|
+
"build": "backstage-cli package build",
|
|
30
|
+
"lint": "backstage-cli package lint",
|
|
31
|
+
"test": "backstage-cli package test",
|
|
32
|
+
"clean": "backstage-cli package clean",
|
|
33
|
+
"prepack": "backstage-cli package prepack",
|
|
34
|
+
"postpack": "backstage-cli package postpack"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@backstage/backend-defaults": "^0.12.0",
|
|
38
|
+
"@backstage/backend-plugin-api": "^1.4.2",
|
|
39
|
+
"@backstage/catalog-client": "^1.11.0",
|
|
40
|
+
"@backstage/config": "^1.3.3",
|
|
41
|
+
"@backstage/errors": "^1.2.7",
|
|
42
|
+
"@backstage/plugin-catalog-node": "^1.18.0",
|
|
43
|
+
"express": "^4.17.1",
|
|
44
|
+
"express-promise-router": "^4.1.0",
|
|
45
|
+
"zod": "^3.22.4"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@backstage/backend-test-utils": "^1.8.0",
|
|
49
|
+
"@backstage/cli": "^0.34.1",
|
|
50
|
+
"@types/express": "^4.17.6",
|
|
51
|
+
"@types/supertest": "^2.0.12",
|
|
52
|
+
"supertest": "^6.2.4",
|
|
53
|
+
"tmp": "^0.2.3"
|
|
54
|
+
},
|
|
55
|
+
"files": [
|
|
56
|
+
"dist"
|
|
57
|
+
],
|
|
58
|
+
"typesVersions": {
|
|
59
|
+
"*": {
|
|
60
|
+
"package.json": [
|
|
61
|
+
"package.json"
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|