@backstage/catalog-client 0.8.0 → 1.0.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 +40 -0
- package/dist/index.cjs.js +2 -20
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -23
- package/dist/index.esm.js +3 -21
- package/dist/index.esm.js.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# @backstage/catalog-client
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- b58c70c223: This package has been promoted to v1.0! To understand how this change affects the package, please check out our [versioning policy](https://backstage.io/docs/overview/versioning-policy).
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- 0163c41be2: **BREAKING**: Removed the deprecated `presence` field in the `Location` and `AddLocationRequest` types. This field was already being ignored by the catalog backend and can be safely removed.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
- @backstage/catalog-model@1.0.0
|
|
17
|
+
- @backstage/errors@1.0.0
|
|
18
|
+
|
|
19
|
+
## 0.9.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- bf95bb806c: **BREAKING**: Removed previously deprecated `CatalogApi.getEntityByName`, please use `getEntityByRef` instead.
|
|
24
|
+
- a3eb3d2afa: **BREAKING**: Removed `CatalogClient.getLocationByEntity` and `CatalogClient.getOriginLocationByEntity` which had previously been deprecated. Please use `CatalogApi.getLocationByRef` instead. Note that this only affects you if you were using `CatalogClient` (the class) directly, rather than `CatalogApi` (the interface), since it has been removed from the interface in an earlier release.
|
|
25
|
+
|
|
26
|
+
### Patch Changes
|
|
27
|
+
|
|
28
|
+
- Updated dependencies
|
|
29
|
+
- @backstage/catalog-model@0.13.0
|
|
30
|
+
|
|
31
|
+
## 0.9.0-next.0
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- bf95bb806c: **BREAKING**: Removed previously deprecated `CatalogApi.getEntityByName`, please use `getEntityByRef` instead.
|
|
36
|
+
- a3eb3d2afa: **BREAKING**: Removed `CatalogClient.getLocationByEntity` and `CatalogClient.getOriginLocationByEntity` which had previously been deprecated. Please use `CatalogApi.getLocationByRef` instead. Note that this only affects you if you were using `CatalogClient` (the class) directly, rather than `CatalogApi` (the interface), since it has been removed from the interface in an earlier release.
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- Updated dependencies
|
|
41
|
+
- @backstage/catalog-model@0.13.0-next.0
|
|
42
|
+
|
|
3
43
|
## 0.8.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -118,14 +118,14 @@ class CatalogClient {
|
|
|
118
118
|
const query = params.length ? `?${params.join("&")}` : "";
|
|
119
119
|
return await this.requestOptional("GET", `/entity-facets${query}`, options);
|
|
120
120
|
}
|
|
121
|
-
async addLocation({ type = "url", target, dryRun
|
|
121
|
+
async addLocation({ type = "url", target, dryRun }, options) {
|
|
122
122
|
const response = await this.fetchApi.fetch(`${await this.discoveryApi.getBaseUrl("catalog")}/locations${dryRun ? "?dryRun=true" : ""}`, {
|
|
123
123
|
headers: {
|
|
124
124
|
"Content-Type": "application/json",
|
|
125
125
|
...(options == null ? void 0 : options.token) && { Authorization: `Bearer ${options == null ? void 0 : options.token}` }
|
|
126
126
|
},
|
|
127
127
|
method: "POST",
|
|
128
|
-
body: JSON.stringify({ type, target
|
|
128
|
+
body: JSON.stringify({ type, target })
|
|
129
129
|
});
|
|
130
130
|
if (response.status !== 201) {
|
|
131
131
|
throw new Error(await response.text());
|
|
@@ -140,24 +140,6 @@ class CatalogClient {
|
|
|
140
140
|
exists
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
|
-
async getOriginLocationByEntity(entity, options) {
|
|
144
|
-
var _a;
|
|
145
|
-
const locationCompound = (_a = entity.metadata.annotations) == null ? void 0 : _a[catalogModel.ANNOTATION_ORIGIN_LOCATION];
|
|
146
|
-
if (!locationCompound) {
|
|
147
|
-
return void 0;
|
|
148
|
-
}
|
|
149
|
-
const all = await this.requestRequired("GET", "/locations", options);
|
|
150
|
-
return all.map((r) => r.data).find((l) => locationCompound === catalogModel.stringifyLocationRef(l));
|
|
151
|
-
}
|
|
152
|
-
async getLocationByEntity(entity, options) {
|
|
153
|
-
var _a;
|
|
154
|
-
const locationCompound = (_a = entity.metadata.annotations) == null ? void 0 : _a[catalogModel.ANNOTATION_LOCATION];
|
|
155
|
-
if (!locationCompound) {
|
|
156
|
-
return void 0;
|
|
157
|
-
}
|
|
158
|
-
const all = await this.requestRequired("GET", "/locations", options);
|
|
159
|
-
return all.map((r) => r.data).find((l) => locationCompound === catalogModel.stringifyLocationRef(l));
|
|
160
|
-
}
|
|
161
143
|
async getLocationByRef(locationRef, options) {
|
|
162
144
|
const all = await this.requestRequired("GET", "/locations", options);
|
|
163
145
|
return all.map((r) => r.data).find((l) => locationRef === catalogModel.stringifyLocationRef(l));
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/types/api.ts","../src/CatalogClient.ts","../src/types/status.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { CompoundEntityRef, Entity } from '@backstage/catalog-model';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogClient.getEntities}, to signify that you want to filter on the\n * presence of that key no matter what its value is.\n *\n * @public\n */\nexport const CATALOG_FILTER_EXISTS = Symbol.for(\n // Random UUID to ensure no collisions\n 'CATALOG_FILTER_EXISTS_0e15b590c0b343a2bae3e787e84c2111',\n);\n\n/**\n * The request type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * If given, return only the parts of each entity that match those dot\n * separated paths in each object.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations']`, then response\n * objects will be shaped like\n *\n * ```\n * {\n * \"kind\": \"Component\",\n * \"metadata\": {\n * \"annotations\": {\n * \"foo\": \"bar\"\n * }\n * }\n * }\n * ```\n */\n fields?: string[] | undefined;\n /**\n * If given, skips over the first N items in the result set.\n */\n offset?: number;\n /**\n * If given, returns at most N items from the result set.\n */\n limit?: number;\n /**\n * If given, skips over all items before that cursor as returned by a previous\n * request.\n */\n after?: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsResponse {\n rootEntityRef: string;\n items: Array<{\n entity: Entity;\n parentEntityRefs: string[];\n }>;\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * Dot separated paths for the facets to extract from each entity.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations.backstage.io/orphan']`, then the\n * response will be shaped like\n *\n * ```\n * {\n * \"facets\": {\n * \"kind\": [\n * { \"key\": \"Component\", \"count\": 22 },\n * { \"key\": \"API\", \"count\": 13 }\n * ],\n * \"metadata.annotations.backstage.io/orphan\": [\n * { \"key\": \"true\", \"count\": 2 }\n * ]\n * }\n * }\n * ```\n */\n facets: string[];\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsResponse {\n /**\n * The computed facets, one entry per facet in the request.\n */\n facets: Record<string, Array<{ value: string; count: number }>>;\n}\n\n/**\n * Options you can pass into a catalog request for additional information.\n *\n * @public\n */\nexport interface CatalogRequestOptions {\n token?: string;\n}\n\n/**\n * Entity location for a specific entity.\n *\n * @public\n */\nexport type Location = {\n id: string;\n type: string;\n target: string;\n /** @deprecated This field is is ignored */\n presence?: 'optional' | 'required';\n};\n\n/**\n * The request type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n dryRun?: boolean;\n /** @deprecated This field is is ignored */\n presence?: 'optional' | 'required';\n};\n\n/**\n * The response type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n entities: Entity[];\n // Only set in dryRun mode.\n exists?: boolean;\n};\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets entity ancestor information, i.e. the hierarchy of parent entities\n * whose processing resulted in a given entity appearing in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse>;\n\n /**\n * Gets a single entity from the catalog by its ref (kind, namespace, name)\n * triplet.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n * @returns The matching entity, or undefined if there was no entity with that ref\n */\n getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined>;\n\n /**\n * Gets a single entity from the catalog by its ref (kind, namespace, name)\n * triplet.\n *\n * @deprecated Use getEntityRef instead\n * @param name - A complete entity ref\n * @param options - Additional options\n */\n getEntityByName(\n name: CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined>;\n\n /**\n * Removes a single entity from the catalog by entity UID.\n *\n * @param uid - An entity UID\n * @param options - Additional options\n */\n removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Refreshes (marks for reprocessing) an entity in the catalog.\n *\n * @param entityRef - An entity ref on string form (e.g.\n * 'component/default:my-component')\n * @param options - Additional options\n */\n refreshEntity(\n entityRef: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Gets a summary of field facets of entities in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse>;\n\n // Locations\n\n /**\n * Gets a registered location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Gets a registered location by its ref.\n *\n * @param locationRef - A location ref, e.g. \"url:https://github.com/...\"\n * @param options - Additional options\n */\n getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Registers a new location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n addLocation(\n location: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse>;\n\n /**\n * Removes a registered Location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n}\n","/*\n * Copyright 2020 The Backstage Authors\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 ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n Entity,\n CompoundEntityRef,\n parseEntityRef,\n stringifyEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport crossFetch from 'cross-fetch';\nimport {\n CATALOG_FILTER_EXISTS,\n AddLocationRequest,\n AddLocationResponse,\n CatalogApi,\n GetEntitiesRequest,\n GetEntitiesResponse,\n CatalogRequestOptions,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n Location,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n} from './types/api';\nimport { DiscoveryApi } from './types/discovery';\nimport { FetchApi } from './types/fetch';\n\n/**\n * A frontend and backend compatible client for communicating with the Backstage\n * software catalog.\n *\n * @public\n */\nexport class CatalogClient implements CatalogApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi || { fetch: crossFetch };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n const { kind, namespace, name } = parseEntityRef(request.entityRef);\n return await this.requestRequired(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}/ancestry`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationById}\n */\n async getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n 'GET',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const { filter = [], fields = [], offset, limit, after } = request ?? {};\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n if (fields.length) {\n params.push(`fields=${fields.map(encodeURIComponent).join(',')}`);\n }\n\n if (offset !== undefined) {\n params.push(`offset=${offset}`);\n }\n if (limit !== undefined) {\n params.push(`limit=${limit}`);\n }\n if (after !== undefined) {\n params.push(`after=${encodeURIComponent(after)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n const entities: Entity[] = await this.requestRequired(\n 'GET',\n `/entities${query}`,\n options,\n );\n\n const refCompare = (a: Entity, b: Entity) => {\n // in case field filtering is used, these fields might not be part of the response\n if (\n a.metadata?.name === undefined ||\n a.kind === undefined ||\n b.metadata?.name === undefined ||\n b.kind === undefined\n ) {\n return 0;\n }\n\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) {\n return -1;\n }\n if (aRef > bRef) {\n return 1;\n }\n return 0;\n };\n\n return { items: entities.sort(refCompare) };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace, name } = parseEntityRef(entityRef);\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n // NOTE(freben): When we deprecate getEntityByName from the interface, we may\n // still want to leave this implementation in place for quite some time\n // longer, to minimize the risk for breakages. Suggested date for removal:\n // August 2022\n /**\n * {@inheritdoc CatalogApi.getEntityByName}\n */\n async getEntityByName(\n compoundName: CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace = 'default', name } = compoundName;\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/refresh`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entityRef }),\n },\n );\n\n if (response.status !== 200) {\n throw new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n for (const facet of facets) {\n params.push(`facet=${encodeURIComponent(facet)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n return await this.requestOptional('GET', `/entity-facets${query}`, options);\n }\n\n /**\n * {@inheritdoc CatalogApi.addLocation}\n */\n async addLocation(\n { type = 'url', target, dryRun, presence }: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/locations${\n dryRun ? '?dryRun=true' : ''\n }`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ type, target, presence }),\n },\n );\n\n if (response.status !== 201) {\n throw new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * @deprecated please use getLocationByRef instead\n */\n async getOriginLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const locationCompound =\n entity.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION];\n if (!locationCompound) {\n return undefined;\n }\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationCompound === stringifyLocationRef(l));\n }\n\n /**\n * @deprecated please use getLocationByRef instead\n */\n async getLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const locationCompound = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n if (!locationCompound) {\n return undefined;\n }\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationCompound === stringifyLocationRef(l));\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationRef === stringifyLocationRef(l));\n }\n\n /**\n * {@inheritdoc CatalogApi.removeLocationById}\n */\n async removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.removeEntityByUid}\n */\n async removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/entities/by-uid/${encodeURIComponent(uid)}`,\n options,\n );\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private async requestOptional(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any | undefined> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\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\n/**\n * The entity `status.items[].type` for the status of the processing engine in\n * regards to an entity.\n *\n * @public\n */\nexport const ENTITY_STATUS_CATALOG_PROCESSING_TYPE =\n 'backstage.io/catalog-processing';\n"],"names":["crossFetch","parseEntityRef","stringifyEntityRef","ANNOTATION_ORIGIN_LOCATION","stringifyLocationRef","ANNOTATION_LOCATION","ResponseError"],"mappings":";;;;;;;;;;;;MAyBa,wBAAwB,OAAO,IAE1C;;oBCuB+C;AAAA,EAI/C,YAAY,SAGT;AACD,SAAK,eAAe,QAAQ;AAC5B,SAAK,WAAW,QAAQ,YAAY,EAAE,OAAOA;AAAA;AAAA,QAMzC,mBACJ,SACA,SACqC;AACrC,UAAM,EAAE,MAAM,WAAW,SAASC,4BAAe,QAAQ;AACzD,WAAO,MAAM,KAAK,gBAChB,OACA,qBAAqB,mBAAmB,SAAS,mBAC/C,cACG,mBAAmB,kBACxB;AAAA;AAAA,QAOE,gBACJ,IACA,SAC+B;AAC/B,WAAO,MAAM,KAAK,gBAChB,OACA,cAAc,mBAAmB,OACjC;AAAA;AAAA,QAOE,YACJ,SACA,SAC8B;AAC9B,UAAM,EAAE,SAAS,IAAI,SAAS,IAAI,QAAQ,OAAO,UAAU,4BAAW;AACtE,UAAM,SAAmB;AAMzB,eAAW,cAAc,CAAC,QAAQ,QAAQ;AACxC,YAAM,cAAwB;AAC9B,iBAAW,CAAC,KAAK,UAAU,OAAO,QAAQ,aAAa;AACrD,mBAAW,KAAK,CAAC,OAAO,QAAQ;AAC9B,cAAI,MAAM,uBAAuB;AAC/B,wBAAY,KAAK,mBAAmB;AAAA,qBAC3B,OAAO,MAAM,UAAU;AAChC,wBAAY,KACV,GAAG,mBAAmB,QAAQ,mBAAmB;AAAA;AAAA;AAAA;AAMzD,UAAI,YAAY,QAAQ;AACtB,eAAO,KAAK,UAAU,YAAY,KAAK;AAAA;AAAA;AAI3C,QAAI,OAAO,QAAQ;AACjB,aAAO,KAAK,UAAU,OAAO,IAAI,oBAAoB,KAAK;AAAA;AAG5D,QAAI,WAAW,QAAW;AACxB,aAAO,KAAK,UAAU;AAAA;AAExB,QAAI,UAAU,QAAW;AACvB,aAAO,KAAK,SAAS;AAAA;AAEvB,QAAI,UAAU,QAAW;AACvB,aAAO,KAAK,SAAS,mBAAmB;AAAA;AAG1C,UAAM,QAAQ,OAAO,SAAS,IAAI,OAAO,KAAK,SAAS;AACvD,UAAM,WAAqB,MAAM,KAAK,gBACpC,OACA,YAAY,SACZ;AAGF,UAAM,aAAa,CAAC,GAAW,MAAc;AAnJjD;AAqJM,UACE,SAAE,aAAF,mBAAY,UAAS,UACrB,EAAE,SAAS,UACX,SAAE,aAAF,mBAAY,UAAS,UACrB,EAAE,SAAS,QACX;AACA,eAAO;AAAA;AAGT,YAAM,OAAOC,gCAAmB;AAChC,YAAM,OAAOA,gCAAmB;AAChC,UAAI,OAAO,MAAM;AACf,eAAO;AAAA;AAET,UAAI,OAAO,MAAM;AACf,eAAO;AAAA;AAET,aAAO;AAAA;AAGT,WAAO,EAAE,OAAO,SAAS,KAAK;AAAA;AAAA,QAM1B,eACJ,WACA,SAC6B;AAC7B,UAAM,EAAE,MAAM,WAAW,SAASD,4BAAe;AACjD,WAAO,KAAK,gBACV,OACA,qBAAqB,mBAAmB,SAAS,mBAC/C,cACG,mBAAmB,SACxB;AAAA;AAAA,QAWE,gBACJ,cACA,SAC6B;AAC7B,UAAM,EAAE,MAAM,YAAY,WAAW,SAAS;AAC9C,WAAO,KAAK,gBACV,OACA,qBAAqB,mBAAmB,SAAS,mBAC/C,cACG,mBAAmB,SACxB;AAAA;AAAA,QAOE,cAAc,WAAmB,SAAiC;AACtE,UAAM,WAAW,MAAM,KAAK,SAAS,MACnC,GAAG,MAAM,KAAK,aAAa,WAAW,sBACtC;AAAA,MACE,SAAS;AAAA,QACP,gBAAgB;AAAA,WACZ,oCAAS,UAAS,EAAE,eAAe,UAAU,mCAAS;AAAA;AAAA,MAE5D,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,EAAE;AAAA;AAI3B,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,IAAI,MAAM,MAAM,SAAS;AAAA;AAAA;AAAA,QAO7B,gBACJ,SACA,SACkC;AAClC,UAAM,EAAE,SAAS,IAAI,WAAW;AAChC,UAAM,SAAmB;AAMzB,eAAW,cAAc,CAAC,QAAQ,QAAQ;AACxC,YAAM,cAAwB;AAC9B,iBAAW,CAAC,KAAK,UAAU,OAAO,QAAQ,aAAa;AACrD,mBAAW,KAAK,CAAC,OAAO,QAAQ;AAC9B,cAAI,MAAM,uBAAuB;AAC/B,wBAAY,KAAK,mBAAmB;AAAA,qBAC3B,OAAO,MAAM,UAAU;AAChC,wBAAY,KACV,GAAG,mBAAmB,QAAQ,mBAAmB;AAAA;AAAA;AAAA;AAMzD,UAAI,YAAY,QAAQ;AACtB,eAAO,KAAK,UAAU,YAAY,KAAK;AAAA;AAAA;AAI3C,eAAW,SAAS,QAAQ;AAC1B,aAAO,KAAK,SAAS,mBAAmB;AAAA;AAG1C,UAAM,QAAQ,OAAO,SAAS,IAAI,OAAO,KAAK,SAAS;AACvD,WAAO,MAAM,KAAK,gBAAgB,OAAO,iBAAiB,SAAS;AAAA;AAAA,QAM/D,YACJ,EAAE,OAAO,OAAO,QAAQ,QAAQ,YAChC,SAC8B;AAC9B,UAAM,WAAW,MAAM,KAAK,SAAS,MACnC,GAAG,MAAM,KAAK,aAAa,WAAW,uBACpC,SAAS,iBAAiB,MAE5B;AAAA,MACE,SAAS;AAAA,QACP,gBAAgB;AAAA,WACZ,oCAAS,UAAS,EAAE,eAAe,UAAU,mCAAS;AAAA;AAAA,MAE5D,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,EAAE,MAAM,QAAQ;AAAA;AAIzC,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,IAAI,MAAM,MAAM,SAAS;AAAA;AAGjC,UAAM,EAAE,UAAU,UAAU,WAAW,MAAM,SAAS;AAEtD,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,0BAA0B;AAAA;AAG5C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,QAOE,0BACJ,QACA,SAC+B;AA5TnC;AA6TI,UAAM,mBACJ,aAAO,SAAS,gBAAhB,mBAA8BE;AAChC,QAAI,CAAC,kBAAkB;AACrB,aAAO;AAAA;AAET,UAAM,MAA4B,MAAM,KAAK,gBAC3C,OACA,cACA;AAEF,WAAO,IACJ,IAAI,OAAK,EAAE,MACX,KAAK,OAAK,qBAAqBC,kCAAqB;AAAA;AAAA,QAMnD,oBACJ,QACA,SAC+B;AAlVnC;AAmVI,UAAM,mBAAmB,aAAO,SAAS,gBAAhB,mBAA8BC;AACvD,QAAI,CAAC,kBAAkB;AACrB,aAAO;AAAA;AAET,UAAM,MAA4B,MAAM,KAAK,gBAC3C,OACA,cACA;AAEF,WAAO,IACJ,IAAI,OAAK,EAAE,MACX,KAAK,OAAK,qBAAqBD,kCAAqB;AAAA;AAAA,QAMnD,iBACJ,aACA,SAC+B;AAC/B,UAAM,MAA4B,MAAM,KAAK,gBAC3C,OACA,cACA;AAEF,WAAO,IACJ,IAAI,OAAK,EAAE,MACX,KAAK,OAAK,gBAAgBA,kCAAqB;AAAA;AAAA,QAM9C,mBACJ,IACA,SACe;AACf,UAAM,KAAK,eACT,UACA,cAAc,mBAAmB,OACjC;AAAA;AAAA,QAOE,kBACJ,KACA,SACe;AACf,UAAM,KAAK,eACT,UACA,oBAAoB,mBAAmB,QACvC;AAAA;AAAA,QAQU,eACZ,QACA,MACA,SACe;AACf,UAAM,MAAM,GAAG,MAAM,KAAK,aAAa,WAAW,aAAa;AAC/D,UAAM,UAAkC,oCAAS,SAC7C,EAAE,eAAe,UAAU,QAAQ,YACnC;AACJ,UAAM,WAAW,MAAM,KAAK,SAAS,MAAM,KAAK,EAAE,QAAQ;AAE1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,MAAME,qBAAc,aAAa;AAAA;AAAA;AAAA,QAI7B,gBACZ,QACA,MACA,SACc;AACd,UAAM,MAAM,GAAG,MAAM,KAAK,aAAa,WAAW,aAAa;AAC/D,UAAM,UAAkC,oCAAS,SAC7C,EAAE,eAAe,UAAU,QAAQ,YACnC;AACJ,UAAM,WAAW,MAAM,KAAK,SAAS,MAAM,KAAK,EAAE,QAAQ;AAE1D,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,MAAMA,qBAAc,aAAa;AAAA;AAGzC,WAAO,MAAM,SAAS;AAAA;AAAA,QAGV,gBACZ,QACA,MACA,SAC0B;AAC1B,UAAM,MAAM,GAAG,MAAM,KAAK,aAAa,WAAW,aAAa;AAC/D,UAAM,UAAkC,oCAAS,SAC7C,EAAE,eAAe,UAAU,QAAQ,YACnC;AACJ,UAAM,WAAW,MAAM,KAAK,SAAS,MAAM,KAAK,EAAE,QAAQ;AAE1D,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,SAAS,WAAW,KAAK;AAC3B,eAAO;AAAA;AAET,YAAM,MAAMA,qBAAc,aAAa;AAAA;AAGzC,WAAO,MAAM,SAAS;AAAA;AAAA;;MChbb,wCACX;;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/types/api.ts","../src/CatalogClient.ts","../src/types/status.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { CompoundEntityRef, Entity } from '@backstage/catalog-model';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogClient.getEntities}, to signify that you want to filter on the\n * presence of that key no matter what its value is.\n *\n * @public\n */\nexport const CATALOG_FILTER_EXISTS = Symbol.for(\n // Random UUID to ensure no collisions\n 'CATALOG_FILTER_EXISTS_0e15b590c0b343a2bae3e787e84c2111',\n);\n\n/**\n * The request type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * If given, return only the parts of each entity that match those dot\n * separated paths in each object.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations']`, then response\n * objects will be shaped like\n *\n * ```\n * {\n * \"kind\": \"Component\",\n * \"metadata\": {\n * \"annotations\": {\n * \"foo\": \"bar\"\n * }\n * }\n * }\n * ```\n */\n fields?: string[] | undefined;\n /**\n * If given, skips over the first N items in the result set.\n */\n offset?: number;\n /**\n * If given, returns at most N items from the result set.\n */\n limit?: number;\n /**\n * If given, skips over all items before that cursor as returned by a previous\n * request.\n */\n after?: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsResponse {\n rootEntityRef: string;\n items: Array<{\n entity: Entity;\n parentEntityRefs: string[];\n }>;\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * Dot separated paths for the facets to extract from each entity.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations.backstage.io/orphan']`, then the\n * response will be shaped like\n *\n * ```\n * {\n * \"facets\": {\n * \"kind\": [\n * { \"key\": \"Component\", \"count\": 22 },\n * { \"key\": \"API\", \"count\": 13 }\n * ],\n * \"metadata.annotations.backstage.io/orphan\": [\n * { \"key\": \"true\", \"count\": 2 }\n * ]\n * }\n * }\n * ```\n */\n facets: string[];\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsResponse {\n /**\n * The computed facets, one entry per facet in the request.\n */\n facets: Record<string, Array<{ value: string; count: number }>>;\n}\n\n/**\n * Options you can pass into a catalog request for additional information.\n *\n * @public\n */\nexport interface CatalogRequestOptions {\n token?: string;\n}\n\n/**\n * Entity location for a specific entity.\n *\n * @public\n */\nexport type Location = {\n id: string;\n type: string;\n target: string;\n};\n\n/**\n * The request type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n dryRun?: boolean;\n};\n\n/**\n * The response type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n entities: Entity[];\n // Only set in dryRun mode.\n exists?: boolean;\n};\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets entity ancestor information, i.e. the hierarchy of parent entities\n * whose processing resulted in a given entity appearing in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse>;\n\n /**\n * Gets a single entity from the catalog by its ref (kind, namespace, name)\n * triplet.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n * @returns The matching entity, or undefined if there was no entity with that ref\n */\n getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined>;\n\n /**\n * Removes a single entity from the catalog by entity UID.\n *\n * @param uid - An entity UID\n * @param options - Additional options\n */\n removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Refreshes (marks for reprocessing) an entity in the catalog.\n *\n * @param entityRef - An entity ref on string form (e.g.\n * 'component/default:my-component')\n * @param options - Additional options\n */\n refreshEntity(\n entityRef: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Gets a summary of field facets of entities in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse>;\n\n // Locations\n\n /**\n * Gets a registered location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Gets a registered location by its ref.\n *\n * @param locationRef - A location ref, e.g. \"url:https://github.com/...\"\n * @param options - Additional options\n */\n getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Registers a new location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n addLocation(\n location: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse>;\n\n /**\n * Removes a registered Location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n}\n","/*\n * Copyright 2020 The Backstage Authors\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 Entity,\n CompoundEntityRef,\n parseEntityRef,\n stringifyEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport crossFetch from 'cross-fetch';\nimport {\n CATALOG_FILTER_EXISTS,\n AddLocationRequest,\n AddLocationResponse,\n CatalogApi,\n GetEntitiesRequest,\n GetEntitiesResponse,\n CatalogRequestOptions,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n Location,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n} from './types/api';\nimport { DiscoveryApi } from './types/discovery';\nimport { FetchApi } from './types/fetch';\n\n/**\n * A frontend and backend compatible client for communicating with the Backstage\n * software catalog.\n *\n * @public\n */\nexport class CatalogClient implements CatalogApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi || { fetch: crossFetch };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n const { kind, namespace, name } = parseEntityRef(request.entityRef);\n return await this.requestRequired(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}/ancestry`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationById}\n */\n async getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n 'GET',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const { filter = [], fields = [], offset, limit, after } = request ?? {};\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n if (fields.length) {\n params.push(`fields=${fields.map(encodeURIComponent).join(',')}`);\n }\n\n if (offset !== undefined) {\n params.push(`offset=${offset}`);\n }\n if (limit !== undefined) {\n params.push(`limit=${limit}`);\n }\n if (after !== undefined) {\n params.push(`after=${encodeURIComponent(after)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n const entities: Entity[] = await this.requestRequired(\n 'GET',\n `/entities${query}`,\n options,\n );\n\n const refCompare = (a: Entity, b: Entity) => {\n // in case field filtering is used, these fields might not be part of the response\n if (\n a.metadata?.name === undefined ||\n a.kind === undefined ||\n b.metadata?.name === undefined ||\n b.kind === undefined\n ) {\n return 0;\n }\n\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) {\n return -1;\n }\n if (aRef > bRef) {\n return 1;\n }\n return 0;\n };\n\n return { items: entities.sort(refCompare) };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace, name } = parseEntityRef(entityRef);\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n // NOTE(freben): When we deprecate getEntityByName from the interface, we may\n // still want to leave this implementation in place for quite some time\n // longer, to minimize the risk for breakages. Suggested date for removal:\n // August 2022\n /**\n * @deprecated Use getEntityByRef instead\n */\n async getEntityByName(\n compoundName: CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace = 'default', name } = compoundName;\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/refresh`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entityRef }),\n },\n );\n\n if (response.status !== 200) {\n throw new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n for (const facet of facets) {\n params.push(`facet=${encodeURIComponent(facet)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n return await this.requestOptional('GET', `/entity-facets${query}`, options);\n }\n\n /**\n * {@inheritdoc CatalogApi.addLocation}\n */\n async addLocation(\n { type = 'url', target, dryRun }: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/locations${\n dryRun ? '?dryRun=true' : ''\n }`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ type, target }),\n },\n );\n\n if (response.status !== 201) {\n throw new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationRef === stringifyLocationRef(l));\n }\n\n /**\n * {@inheritdoc CatalogApi.removeLocationById}\n */\n async removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.removeEntityByUid}\n */\n async removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/entities/by-uid/${encodeURIComponent(uid)}`,\n options,\n );\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private async requestOptional(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any | undefined> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\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\n/**\n * The entity `status.items[].type` for the status of the processing engine in\n * regards to an entity.\n *\n * @public\n */\nexport const ENTITY_STATUS_CATALOG_PROCESSING_TYPE =\n 'backstage.io/catalog-processing';\n"],"names":["crossFetch","parseEntityRef","stringifyEntityRef","stringifyLocationRef","ResponseError"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -214,8 +214,6 @@ declare type Location = {
|
|
|
214
214
|
id: string;
|
|
215
215
|
type: string;
|
|
216
216
|
target: string;
|
|
217
|
-
/** @deprecated This field is is ignored */
|
|
218
|
-
presence?: 'optional' | 'required';
|
|
219
217
|
};
|
|
220
218
|
/**
|
|
221
219
|
* The request type for {@link CatalogClient.addLocation}.
|
|
@@ -226,8 +224,6 @@ declare type AddLocationRequest = {
|
|
|
226
224
|
type?: string;
|
|
227
225
|
target: string;
|
|
228
226
|
dryRun?: boolean;
|
|
229
|
-
/** @deprecated This field is is ignored */
|
|
230
|
-
presence?: 'optional' | 'required';
|
|
231
227
|
};
|
|
232
228
|
/**
|
|
233
229
|
* The response type for {@link CatalogClient.addLocation}.
|
|
@@ -269,15 +265,6 @@ interface CatalogApi {
|
|
|
269
265
|
* @returns The matching entity, or undefined if there was no entity with that ref
|
|
270
266
|
*/
|
|
271
267
|
getEntityByRef(entityRef: string | CompoundEntityRef, options?: CatalogRequestOptions): Promise<Entity | undefined>;
|
|
272
|
-
/**
|
|
273
|
-
* Gets a single entity from the catalog by its ref (kind, namespace, name)
|
|
274
|
-
* triplet.
|
|
275
|
-
*
|
|
276
|
-
* @deprecated Use getEntityRef instead
|
|
277
|
-
* @param name - A complete entity ref
|
|
278
|
-
* @param options - Additional options
|
|
279
|
-
*/
|
|
280
|
-
getEntityByName(name: CompoundEntityRef, options?: CatalogRequestOptions): Promise<Entity | undefined>;
|
|
281
268
|
/**
|
|
282
269
|
* Removes a single entity from the catalog by entity UID.
|
|
283
270
|
*
|
|
@@ -364,7 +351,7 @@ declare class CatalogClient implements CatalogApi {
|
|
|
364
351
|
*/
|
|
365
352
|
getEntityByRef(entityRef: string | CompoundEntityRef, options?: CatalogRequestOptions): Promise<Entity | undefined>;
|
|
366
353
|
/**
|
|
367
|
-
*
|
|
354
|
+
* @deprecated Use getEntityByRef instead
|
|
368
355
|
*/
|
|
369
356
|
getEntityByName(compoundName: CompoundEntityRef, options?: CatalogRequestOptions): Promise<Entity | undefined>;
|
|
370
357
|
/**
|
|
@@ -378,15 +365,7 @@ declare class CatalogClient implements CatalogApi {
|
|
|
378
365
|
/**
|
|
379
366
|
* {@inheritdoc CatalogApi.addLocation}
|
|
380
367
|
*/
|
|
381
|
-
addLocation({ type, target, dryRun
|
|
382
|
-
/**
|
|
383
|
-
* @deprecated please use getLocationByRef instead
|
|
384
|
-
*/
|
|
385
|
-
getOriginLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location | undefined>;
|
|
386
|
-
/**
|
|
387
|
-
* @deprecated please use getLocationByRef instead
|
|
388
|
-
*/
|
|
389
|
-
getLocationByEntity(entity: Entity, options?: CatalogRequestOptions): Promise<Location | undefined>;
|
|
368
|
+
addLocation({ type, target, dryRun }: AddLocationRequest, options?: CatalogRequestOptions): Promise<AddLocationResponse>;
|
|
390
369
|
/**
|
|
391
370
|
* {@inheritdoc CatalogApi.getLocationByRef}
|
|
392
371
|
*/
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseEntityRef,
|
|
1
|
+
import { parseEntityRef, stringifyLocationRef, stringifyEntityRef } from '@backstage/catalog-model';
|
|
2
2
|
import { ResponseError } from '@backstage/errors';
|
|
3
3
|
import crossFetch from 'cross-fetch';
|
|
4
4
|
|
|
@@ -110,14 +110,14 @@ class CatalogClient {
|
|
|
110
110
|
const query = params.length ? `?${params.join("&")}` : "";
|
|
111
111
|
return await this.requestOptional("GET", `/entity-facets${query}`, options);
|
|
112
112
|
}
|
|
113
|
-
async addLocation({ type = "url", target, dryRun
|
|
113
|
+
async addLocation({ type = "url", target, dryRun }, options) {
|
|
114
114
|
const response = await this.fetchApi.fetch(`${await this.discoveryApi.getBaseUrl("catalog")}/locations${dryRun ? "?dryRun=true" : ""}`, {
|
|
115
115
|
headers: {
|
|
116
116
|
"Content-Type": "application/json",
|
|
117
117
|
...(options == null ? void 0 : options.token) && { Authorization: `Bearer ${options == null ? void 0 : options.token}` }
|
|
118
118
|
},
|
|
119
119
|
method: "POST",
|
|
120
|
-
body: JSON.stringify({ type, target
|
|
120
|
+
body: JSON.stringify({ type, target })
|
|
121
121
|
});
|
|
122
122
|
if (response.status !== 201) {
|
|
123
123
|
throw new Error(await response.text());
|
|
@@ -132,24 +132,6 @@ class CatalogClient {
|
|
|
132
132
|
exists
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
|
-
async getOriginLocationByEntity(entity, options) {
|
|
136
|
-
var _a;
|
|
137
|
-
const locationCompound = (_a = entity.metadata.annotations) == null ? void 0 : _a[ANNOTATION_ORIGIN_LOCATION];
|
|
138
|
-
if (!locationCompound) {
|
|
139
|
-
return void 0;
|
|
140
|
-
}
|
|
141
|
-
const all = await this.requestRequired("GET", "/locations", options);
|
|
142
|
-
return all.map((r) => r.data).find((l) => locationCompound === stringifyLocationRef(l));
|
|
143
|
-
}
|
|
144
|
-
async getLocationByEntity(entity, options) {
|
|
145
|
-
var _a;
|
|
146
|
-
const locationCompound = (_a = entity.metadata.annotations) == null ? void 0 : _a[ANNOTATION_LOCATION];
|
|
147
|
-
if (!locationCompound) {
|
|
148
|
-
return void 0;
|
|
149
|
-
}
|
|
150
|
-
const all = await this.requestRequired("GET", "/locations", options);
|
|
151
|
-
return all.map((r) => r.data).find((l) => locationCompound === stringifyLocationRef(l));
|
|
152
|
-
}
|
|
153
135
|
async getLocationByRef(locationRef, options) {
|
|
154
136
|
const all = await this.requestRequired("GET", "/locations", options);
|
|
155
137
|
return all.map((r) => r.data).find((l) => locationRef === stringifyLocationRef(l));
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/types/api.ts","../src/CatalogClient.ts","../src/types/status.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { CompoundEntityRef, Entity } from '@backstage/catalog-model';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogClient.getEntities}, to signify that you want to filter on the\n * presence of that key no matter what its value is.\n *\n * @public\n */\nexport const CATALOG_FILTER_EXISTS = Symbol.for(\n // Random UUID to ensure no collisions\n 'CATALOG_FILTER_EXISTS_0e15b590c0b343a2bae3e787e84c2111',\n);\n\n/**\n * The request type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * If given, return only the parts of each entity that match those dot\n * separated paths in each object.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations']`, then response\n * objects will be shaped like\n *\n * ```\n * {\n * \"kind\": \"Component\",\n * \"metadata\": {\n * \"annotations\": {\n * \"foo\": \"bar\"\n * }\n * }\n * }\n * ```\n */\n fields?: string[] | undefined;\n /**\n * If given, skips over the first N items in the result set.\n */\n offset?: number;\n /**\n * If given, returns at most N items from the result set.\n */\n limit?: number;\n /**\n * If given, skips over all items before that cursor as returned by a previous\n * request.\n */\n after?: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsResponse {\n rootEntityRef: string;\n items: Array<{\n entity: Entity;\n parentEntityRefs: string[];\n }>;\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * Dot separated paths for the facets to extract from each entity.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations.backstage.io/orphan']`, then the\n * response will be shaped like\n *\n * ```\n * {\n * \"facets\": {\n * \"kind\": [\n * { \"key\": \"Component\", \"count\": 22 },\n * { \"key\": \"API\", \"count\": 13 }\n * ],\n * \"metadata.annotations.backstage.io/orphan\": [\n * { \"key\": \"true\", \"count\": 2 }\n * ]\n * }\n * }\n * ```\n */\n facets: string[];\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsResponse {\n /**\n * The computed facets, one entry per facet in the request.\n */\n facets: Record<string, Array<{ value: string; count: number }>>;\n}\n\n/**\n * Options you can pass into a catalog request for additional information.\n *\n * @public\n */\nexport interface CatalogRequestOptions {\n token?: string;\n}\n\n/**\n * Entity location for a specific entity.\n *\n * @public\n */\nexport type Location = {\n id: string;\n type: string;\n target: string;\n /** @deprecated This field is is ignored */\n presence?: 'optional' | 'required';\n};\n\n/**\n * The request type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n dryRun?: boolean;\n /** @deprecated This field is is ignored */\n presence?: 'optional' | 'required';\n};\n\n/**\n * The response type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n entities: Entity[];\n // Only set in dryRun mode.\n exists?: boolean;\n};\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets entity ancestor information, i.e. the hierarchy of parent entities\n * whose processing resulted in a given entity appearing in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse>;\n\n /**\n * Gets a single entity from the catalog by its ref (kind, namespace, name)\n * triplet.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n * @returns The matching entity, or undefined if there was no entity with that ref\n */\n getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined>;\n\n /**\n * Gets a single entity from the catalog by its ref (kind, namespace, name)\n * triplet.\n *\n * @deprecated Use getEntityRef instead\n * @param name - A complete entity ref\n * @param options - Additional options\n */\n getEntityByName(\n name: CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined>;\n\n /**\n * Removes a single entity from the catalog by entity UID.\n *\n * @param uid - An entity UID\n * @param options - Additional options\n */\n removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Refreshes (marks for reprocessing) an entity in the catalog.\n *\n * @param entityRef - An entity ref on string form (e.g.\n * 'component/default:my-component')\n * @param options - Additional options\n */\n refreshEntity(\n entityRef: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Gets a summary of field facets of entities in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse>;\n\n // Locations\n\n /**\n * Gets a registered location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Gets a registered location by its ref.\n *\n * @param locationRef - A location ref, e.g. \"url:https://github.com/...\"\n * @param options - Additional options\n */\n getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Registers a new location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n addLocation(\n location: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse>;\n\n /**\n * Removes a registered Location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n}\n","/*\n * Copyright 2020 The Backstage Authors\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 ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n Entity,\n CompoundEntityRef,\n parseEntityRef,\n stringifyEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport crossFetch from 'cross-fetch';\nimport {\n CATALOG_FILTER_EXISTS,\n AddLocationRequest,\n AddLocationResponse,\n CatalogApi,\n GetEntitiesRequest,\n GetEntitiesResponse,\n CatalogRequestOptions,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n Location,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n} from './types/api';\nimport { DiscoveryApi } from './types/discovery';\nimport { FetchApi } from './types/fetch';\n\n/**\n * A frontend and backend compatible client for communicating with the Backstage\n * software catalog.\n *\n * @public\n */\nexport class CatalogClient implements CatalogApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi || { fetch: crossFetch };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n const { kind, namespace, name } = parseEntityRef(request.entityRef);\n return await this.requestRequired(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}/ancestry`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationById}\n */\n async getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n 'GET',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const { filter = [], fields = [], offset, limit, after } = request ?? {};\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n if (fields.length) {\n params.push(`fields=${fields.map(encodeURIComponent).join(',')}`);\n }\n\n if (offset !== undefined) {\n params.push(`offset=${offset}`);\n }\n if (limit !== undefined) {\n params.push(`limit=${limit}`);\n }\n if (after !== undefined) {\n params.push(`after=${encodeURIComponent(after)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n const entities: Entity[] = await this.requestRequired(\n 'GET',\n `/entities${query}`,\n options,\n );\n\n const refCompare = (a: Entity, b: Entity) => {\n // in case field filtering is used, these fields might not be part of the response\n if (\n a.metadata?.name === undefined ||\n a.kind === undefined ||\n b.metadata?.name === undefined ||\n b.kind === undefined\n ) {\n return 0;\n }\n\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) {\n return -1;\n }\n if (aRef > bRef) {\n return 1;\n }\n return 0;\n };\n\n return { items: entities.sort(refCompare) };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace, name } = parseEntityRef(entityRef);\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n // NOTE(freben): When we deprecate getEntityByName from the interface, we may\n // still want to leave this implementation in place for quite some time\n // longer, to minimize the risk for breakages. Suggested date for removal:\n // August 2022\n /**\n * {@inheritdoc CatalogApi.getEntityByName}\n */\n async getEntityByName(\n compoundName: CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace = 'default', name } = compoundName;\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/refresh`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entityRef }),\n },\n );\n\n if (response.status !== 200) {\n throw new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n for (const facet of facets) {\n params.push(`facet=${encodeURIComponent(facet)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n return await this.requestOptional('GET', `/entity-facets${query}`, options);\n }\n\n /**\n * {@inheritdoc CatalogApi.addLocation}\n */\n async addLocation(\n { type = 'url', target, dryRun, presence }: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/locations${\n dryRun ? '?dryRun=true' : ''\n }`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ type, target, presence }),\n },\n );\n\n if (response.status !== 201) {\n throw new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * @deprecated please use getLocationByRef instead\n */\n async getOriginLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const locationCompound =\n entity.metadata.annotations?.[ANNOTATION_ORIGIN_LOCATION];\n if (!locationCompound) {\n return undefined;\n }\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationCompound === stringifyLocationRef(l));\n }\n\n /**\n * @deprecated please use getLocationByRef instead\n */\n async getLocationByEntity(\n entity: Entity,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const locationCompound = entity.metadata.annotations?.[ANNOTATION_LOCATION];\n if (!locationCompound) {\n return undefined;\n }\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationCompound === stringifyLocationRef(l));\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationRef === stringifyLocationRef(l));\n }\n\n /**\n * {@inheritdoc CatalogApi.removeLocationById}\n */\n async removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.removeEntityByUid}\n */\n async removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/entities/by-uid/${encodeURIComponent(uid)}`,\n options,\n );\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private async requestOptional(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any | undefined> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\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\n/**\n * The entity `status.items[].type` for the status of the processing engine in\n * regards to an entity.\n *\n * @public\n */\nexport const ENTITY_STATUS_CATALOG_PROCESSING_TYPE =\n 'backstage.io/catalog-processing';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/types/api.ts","../src/CatalogClient.ts","../src/types/status.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\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 { CompoundEntityRef, Entity } from '@backstage/catalog-model';\n\n/**\n * This symbol can be used in place of a value when passed to filters in e.g.\n * {@link CatalogClient.getEntities}, to signify that you want to filter on the\n * presence of that key no matter what its value is.\n *\n * @public\n */\nexport const CATALOG_FILTER_EXISTS = Symbol.for(\n // Random UUID to ensure no collisions\n 'CATALOG_FILTER_EXISTS_0e15b590c0b343a2bae3e787e84c2111',\n);\n\n/**\n * The request type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * If given, return only the parts of each entity that match those dot\n * separated paths in each object.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations']`, then response\n * objects will be shaped like\n *\n * ```\n * {\n * \"kind\": \"Component\",\n * \"metadata\": {\n * \"annotations\": {\n * \"foo\": \"bar\"\n * }\n * }\n * }\n * ```\n */\n fields?: string[] | undefined;\n /**\n * If given, skips over the first N items in the result set.\n */\n offset?: number;\n /**\n * If given, returns at most N items from the result set.\n */\n limit?: number;\n /**\n * If given, skips over all items before that cursor as returned by a previous\n * request.\n */\n after?: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntities}.\n *\n * @public\n */\nexport interface GetEntitiesResponse {\n items: Entity[];\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsRequest {\n entityRef: string;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityAncestors}.\n *\n * @public\n */\nexport interface GetEntityAncestorsResponse {\n rootEntityRef: string;\n items: Array<{\n entity: Entity;\n parentEntityRefs: string[];\n }>;\n}\n\n/**\n * The request type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsRequest {\n /**\n * If given, return only entities that match the given patterns.\n *\n * @remarks\n *\n * If multiple filter sets are given as an array, then there is effectively an\n * OR between each filter set.\n *\n * Within one filter set, there is effectively an AND between the various\n * keys.\n *\n * Within one key, if there are more than one value, then there is effectively\n * an OR between them.\n *\n * Example: For an input of\n *\n * ```\n * [\n * { kind: ['API', 'Component'] },\n * { 'metadata.name': 'a', 'metadata.namespace': 'b' }\n * ]\n * ```\n *\n * This effectively means\n *\n * ```\n * (kind = EITHER 'API' OR 'Component')\n * OR\n * (metadata.name = 'a' AND metadata.namespace = 'b' )\n * ```\n *\n * Each key is a dot separated path in each object.\n *\n * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`\n * (exported from this package), which means that you assert on the existence\n * of that key, no matter what its value is.\n */\n filter?:\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>\n | undefined;\n /**\n * Dot separated paths for the facets to extract from each entity.\n *\n * @remarks\n *\n * Example: For an input of `['kind', 'metadata.annotations.backstage.io/orphan']`, then the\n * response will be shaped like\n *\n * ```\n * {\n * \"facets\": {\n * \"kind\": [\n * { \"key\": \"Component\", \"count\": 22 },\n * { \"key\": \"API\", \"count\": 13 }\n * ],\n * \"metadata.annotations.backstage.io/orphan\": [\n * { \"key\": \"true\", \"count\": 2 }\n * ]\n * }\n * }\n * ```\n */\n facets: string[];\n}\n\n/**\n * The response type for {@link CatalogClient.getEntityFacets}.\n *\n * @public\n */\nexport interface GetEntityFacetsResponse {\n /**\n * The computed facets, one entry per facet in the request.\n */\n facets: Record<string, Array<{ value: string; count: number }>>;\n}\n\n/**\n * Options you can pass into a catalog request for additional information.\n *\n * @public\n */\nexport interface CatalogRequestOptions {\n token?: string;\n}\n\n/**\n * Entity location for a specific entity.\n *\n * @public\n */\nexport type Location = {\n id: string;\n type: string;\n target: string;\n};\n\n/**\n * The request type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationRequest = {\n type?: string;\n target: string;\n dryRun?: boolean;\n};\n\n/**\n * The response type for {@link CatalogClient.addLocation}.\n *\n * @public\n */\nexport type AddLocationResponse = {\n location: Location;\n entities: Entity[];\n // Only set in dryRun mode.\n exists?: boolean;\n};\n\n/**\n * A client for interacting with the Backstage software catalog through its API.\n *\n * @public\n */\nexport interface CatalogApi {\n /**\n * Lists catalog entities.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse>;\n\n /**\n * Gets entity ancestor information, i.e. the hierarchy of parent entities\n * whose processing resulted in a given entity appearing in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse>;\n\n /**\n * Gets a single entity from the catalog by its ref (kind, namespace, name)\n * triplet.\n *\n * @param entityRef - A complete entity ref, either on string or compound form\n * @param options - Additional options\n * @returns The matching entity, or undefined if there was no entity with that ref\n */\n getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined>;\n\n /**\n * Removes a single entity from the catalog by entity UID.\n *\n * @param uid - An entity UID\n * @param options - Additional options\n */\n removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Refreshes (marks for reprocessing) an entity in the catalog.\n *\n * @param entityRef - An entity ref on string form (e.g.\n * 'component/default:my-component')\n * @param options - Additional options\n */\n refreshEntity(\n entityRef: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n\n /**\n * Gets a summary of field facets of entities in the catalog.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse>;\n\n // Locations\n\n /**\n * Gets a registered location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Gets a registered location by its ref.\n *\n * @param locationRef - A location ref, e.g. \"url:https://github.com/...\"\n * @param options - Additional options\n */\n getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined>;\n\n /**\n * Registers a new location.\n *\n * @param location - Request parameters\n * @param options - Additional options\n */\n addLocation(\n location: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse>;\n\n /**\n * Removes a registered Location by its ID.\n *\n * @param id - A location ID\n * @param options - Additional options\n */\n removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void>;\n}\n","/*\n * Copyright 2020 The Backstage Authors\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 Entity,\n CompoundEntityRef,\n parseEntityRef,\n stringifyEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport crossFetch from 'cross-fetch';\nimport {\n CATALOG_FILTER_EXISTS,\n AddLocationRequest,\n AddLocationResponse,\n CatalogApi,\n GetEntitiesRequest,\n GetEntitiesResponse,\n CatalogRequestOptions,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n Location,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n} from './types/api';\nimport { DiscoveryApi } from './types/discovery';\nimport { FetchApi } from './types/fetch';\n\n/**\n * A frontend and backend compatible client for communicating with the Backstage\n * software catalog.\n *\n * @public\n */\nexport class CatalogClient implements CatalogApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi || { fetch: crossFetch };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n const { kind, namespace, name } = parseEntityRef(request.entityRef);\n return await this.requestRequired(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}/ancestry`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationById}\n */\n async getLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n 'GET',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const { filter = [], fields = [], offset, limit, after } = request ?? {};\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n if (fields.length) {\n params.push(`fields=${fields.map(encodeURIComponent).join(',')}`);\n }\n\n if (offset !== undefined) {\n params.push(`offset=${offset}`);\n }\n if (limit !== undefined) {\n params.push(`limit=${limit}`);\n }\n if (after !== undefined) {\n params.push(`after=${encodeURIComponent(after)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n const entities: Entity[] = await this.requestRequired(\n 'GET',\n `/entities${query}`,\n options,\n );\n\n const refCompare = (a: Entity, b: Entity) => {\n // in case field filtering is used, these fields might not be part of the response\n if (\n a.metadata?.name === undefined ||\n a.kind === undefined ||\n b.metadata?.name === undefined ||\n b.kind === undefined\n ) {\n return 0;\n }\n\n const aRef = stringifyEntityRef(a);\n const bRef = stringifyEntityRef(b);\n if (aRef < bRef) {\n return -1;\n }\n if (aRef > bRef) {\n return 1;\n }\n return 0;\n };\n\n return { items: entities.sort(refCompare) };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace, name } = parseEntityRef(entityRef);\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n // NOTE(freben): When we deprecate getEntityByName from the interface, we may\n // still want to leave this implementation in place for quite some time\n // longer, to minimize the risk for breakages. Suggested date for removal:\n // August 2022\n /**\n * @deprecated Use getEntityByRef instead\n */\n async getEntityByName(\n compoundName: CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n const { kind, namespace = 'default', name } = compoundName;\n return this.requestOptional(\n 'GET',\n `/entities/by-name/${encodeURIComponent(kind)}/${encodeURIComponent(\n namespace,\n )}/${encodeURIComponent(name)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/refresh`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entityRef }),\n },\n );\n\n if (response.status !== 200) {\n throw new Error(await response.text());\n }\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityFacets}\n */\n async getEntityFacets(\n request: GetEntityFacetsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityFacetsResponse> {\n const { filter = [], facets } = request;\n const params: string[] = [];\n\n // filter param can occur multiple times, for example\n // /api/catalog/entities?filter=metadata.name=wayback-search,kind=component&filter=metadata.name=www-artist,kind=component'\n // the \"outer array\" defined by `filter` occurrences corresponds to \"anyOf\" filters\n // the \"inner array\" defined within a `filter` param corresponds to \"allOf\" filters\n for (const filterItem of [filter].flat()) {\n const filterParts: string[] = [];\n for (const [key, value] of Object.entries(filterItem)) {\n for (const v of [value].flat()) {\n if (v === CATALOG_FILTER_EXISTS) {\n filterParts.push(encodeURIComponent(key));\n } else if (typeof v === 'string') {\n filterParts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(v)}`,\n );\n }\n }\n }\n\n if (filterParts.length) {\n params.push(`filter=${filterParts.join(',')}`);\n }\n }\n\n for (const facet of facets) {\n params.push(`facet=${encodeURIComponent(facet)}`);\n }\n\n const query = params.length ? `?${params.join('&')}` : '';\n return await this.requestOptional('GET', `/entity-facets${query}`, options);\n }\n\n /**\n * {@inheritdoc CatalogApi.addLocation}\n */\n async addLocation(\n { type = 'url', target, dryRun }: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/locations${\n dryRun ? '?dryRun=true' : ''\n }`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ type, target }),\n },\n );\n\n if (response.status !== 201) {\n throw new Error(await response.text());\n }\n\n const { location, entities, exists } = await response.json();\n\n if (!location) {\n throw new Error(`Location wasn't added: ${target}`);\n }\n\n return {\n location,\n entities,\n exists,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByRef}\n */\n async getLocationByRef(\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n const all: { data: Location }[] = await this.requestRequired(\n 'GET',\n '/locations',\n options,\n );\n return all\n .map(r => r.data)\n .find(l => locationRef === stringifyLocationRef(l));\n }\n\n /**\n * {@inheritdoc CatalogApi.removeLocationById}\n */\n async removeLocationById(\n id: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/locations/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.removeEntityByUid}\n */\n async removeEntityByUid(\n uid: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n await this.requestIgnored(\n 'DELETE',\n `/entities/by-uid/${encodeURIComponent(uid)}`,\n options,\n );\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<void> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n\n private async requestOptional(\n method: string,\n path: string,\n options?: CatalogRequestOptions,\n ): Promise<any | undefined> {\n const url = `${await this.discoveryApi.getBaseUrl('catalog')}${path}`;\n const headers: Record<string, string> = options?.token\n ? { Authorization: `Bearer ${options.token}` }\n : {};\n const response = await this.fetchApi.fetch(url, { method, headers });\n\n if (!response.ok) {\n if (response.status === 404) {\n return undefined;\n }\n throw await ResponseError.fromResponse(response);\n }\n\n return await response.json();\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\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\n/**\n * The entity `status.items[].type` for the status of the processing engine in\n * regards to an entity.\n *\n * @public\n */\nexport const ENTITY_STATUS_CATALOG_PROCESSING_TYPE =\n 'backstage.io/catalog-processing';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/catalog-client",
|
|
3
3
|
"description": "An isomorphic client for the catalog backend",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"main": "dist/index.cjs.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -33,18 +33,18 @@
|
|
|
33
33
|
"clean": "backstage-cli package clean"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@backstage/catalog-model": "^0.
|
|
37
|
-
"@backstage/errors": "^0.
|
|
36
|
+
"@backstage/catalog-model": "^1.0.0",
|
|
37
|
+
"@backstage/errors": "^1.0.0",
|
|
38
38
|
"cross-fetch": "^3.1.5"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@backstage/cli": "^0.
|
|
41
|
+
"@backstage/cli": "^0.16.0",
|
|
42
42
|
"@types/jest": "^26.0.7",
|
|
43
43
|
"msw": "^0.35.0"
|
|
44
44
|
},
|
|
45
45
|
"files": [
|
|
46
46
|
"dist"
|
|
47
47
|
],
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "e9496f746b31600dbfac7fa76987479e66426257",
|
|
49
49
|
"module": "dist/index.esm.js"
|
|
50
50
|
}
|