@backstage/catalog-client 1.1.2 → 1.2.0-next.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # @backstage/catalog-client
2
2
 
3
+ ## 1.2.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 00d90b520a: **BREAKING PRODUCERS**: Added a new `getEntitiesByRefs` endpoint to `CatalogApi`, for efficient batch fetching of entities by ref.
8
+
9
+ ### Patch Changes
10
+
11
+ - 3280711113: Updated dependency `msw` to `^0.49.0`.
12
+ - Updated dependencies
13
+ - @backstage/catalog-model@1.1.4-next.0
14
+ - @backstage/errors@1.1.4-next.0
15
+
3
16
  ## 1.1.2
4
17
 
5
18
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -91,6 +91,29 @@ class CatalogClient {
91
91
  };
92
92
  return { items: entities.sort(refCompare) };
93
93
  }
94
+ async getEntitiesByRefs(request, options) {
95
+ var _a;
96
+ const params = [];
97
+ if ((_a = request.fields) == null ? void 0 : _a.length) {
98
+ params.push(`fields=${request.fields.map(encodeURIComponent).join(",")}`);
99
+ }
100
+ const baseUrl = await this.discoveryApi.getBaseUrl("catalog");
101
+ const query = params.length ? `?${params.join("&")}` : "";
102
+ const url = `${baseUrl}/entities/by-refs${query}`;
103
+ const response = await this.fetchApi.fetch(url, {
104
+ headers: {
105
+ "Content-Type": "application/json",
106
+ ...(options == null ? void 0 : options.token) && { Authorization: `Bearer ${options == null ? void 0 : options.token}` }
107
+ },
108
+ method: "POST",
109
+ body: JSON.stringify({ entityRefs: request.entityRefs })
110
+ });
111
+ if (!response.ok) {
112
+ throw await errors.ResponseError.fromResponse(response);
113
+ }
114
+ const { items } = await response.json();
115
+ return { items };
116
+ }
94
117
  async getEntityByRef(entityRef, options) {
95
118
  const { kind, namespace, name } = catalogModel.parseEntityRef(entityRef);
96
119
  return this.requestOptional(
@@ -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';\nimport { SerializedError } from '@backstage/errors';\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 * The response type for {@link CatalogClient.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\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 * Validate entity and its location.\n *\n * @param entity - Entity to validate\n * @param locationRef - Location ref in format `url:http://example.com/file`\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\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 ValidateEntityResponse,\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 request: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const { type = 'url', target, dryRun } = request;\n\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 * {@inheritdoc CatalogApi.validateEntity}\n */\n async validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/validate-entity`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entity, location: locationRef }),\n },\n );\n\n if (response.ok) {\n return {\n valid: true,\n };\n }\n\n if (response.status !== 400) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { errors = [] } = await response.json();\n\n return {\n valid: false,\n errors,\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","errors"],"mappings":"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"}
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';\nimport { SerializedError } from '@backstage/errors';\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 * A key-value based filter expression for entities.\n *\n * @remarks\n *\n * Each key of a record is a dot-separated path into the entity structure, e.g.\n * `metadata.name`.\n *\n * The values are literal values to match against. As a value you can also pass\n * in the symbol `CATALOG_FILTER_EXISTS` (exported from this package), which\n * means that you assert on the existence of that key, no matter what its value\n * is.\n *\n * All matching of keys and values is case insensitive.\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 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 * @public\n */\nexport type EntityFilterQuery =\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>;\n\n/**\n * A set of dot-separated paths into an entity's keys, showing what parts of an\n * entity to include in a response, and excluding all others.\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 * @public\n */\nexport type EntityFieldsQuery = string[];\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 filter.\n */\n filter?: EntityFilterQuery;\n /**\n * If given, return only the parts of each entity that match the field\n * declarations.\n */\n fields?: EntityFieldsQuery;\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.getEntitiesByRefs}.\n *\n * @public\n */\nexport interface GetEntitiesByRefsRequest {\n /**\n * The list of entity refs to fetch.\n *\n * @remarks\n *\n * The returned list of entities will be in the same order as the refs, and\n * null will be returned in those positions that were not found.\n */\n entityRefs: string[];\n /**\n * If given, return only the parts of each entity that match the field\n * declarations.\n */\n fields?: EntityFieldsQuery | undefined;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntitiesByRefs}.\n *\n * @public\n */\nexport interface GetEntitiesByRefsResponse {\n /**\n * The returned list of entities.\n *\n * @remarks\n *\n * The list will be in the same order as the refs given in the request, and\n * null will be returned in those positions that were not found.\n */\n items: Array<Entity | undefined>;\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 * The response type for {@link CatalogClient.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\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 a batch of entities, by their entity refs.\n *\n * @remarks\n *\n * The output list of entities is of the same size and in the same order as\n * the requested list of entity refs. Entries that are not found are returned\n * as null.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse>;\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 * Validate entity and its location.\n *\n * @param entity - Entity to validate\n * @param locationRef - Location ref in format `url:http://example.com/file`\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\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 ValidateEntityResponse,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\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.getEntitiesByRefs}\n */\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse> {\n const params: string[] = [];\n if (request.fields?.length) {\n params.push(`fields=${request.fields.map(encodeURIComponent).join(',')}`);\n }\n\n const baseUrl = await this.discoveryApi.getBaseUrl('catalog');\n const query = params.length ? `?${params.join('&')}` : '';\n const url = `${baseUrl}/entities/by-refs${query}`;\n\n const response = await this.fetchApi.fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entityRefs: request.entityRefs }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { items } = await response.json();\n\n return { items };\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 request: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const { type = 'url', target, dryRun } = request;\n\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 * {@inheritdoc CatalogApi.validateEntity}\n */\n async validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/validate-entity`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entity, location: locationRef }),\n },\n );\n\n if (response.ok) {\n return {\n valid: true,\n };\n }\n\n if (response.status !== 400) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { errors = [] } = await response.json();\n\n return {\n valid: false,\n errors,\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","ResponseError","stringifyLocationRef","errors"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,6 +9,71 @@ import { SerializedError } from '@backstage/errors';
9
9
  * @public
10
10
  */
11
11
  declare const CATALOG_FILTER_EXISTS: unique symbol;
12
+ /**
13
+ * A key-value based filter expression for entities.
14
+ *
15
+ * @remarks
16
+ *
17
+ * Each key of a record is a dot-separated path into the entity structure, e.g.
18
+ * `metadata.name`.
19
+ *
20
+ * The values are literal values to match against. As a value you can also pass
21
+ * in the symbol `CATALOG_FILTER_EXISTS` (exported from this package), which
22
+ * means that you assert on the existence of that key, no matter what its value
23
+ * is.
24
+ *
25
+ * All matching of keys and values is case insensitive.
26
+ *
27
+ * If multiple filter sets are given as an array, then there is effectively an
28
+ * OR between each filter set.
29
+ *
30
+ * Within one filter set, there is effectively an AND between the various keys.
31
+ *
32
+ * Within one key, if there are more than one value, then there is effectively
33
+ * an OR between them.
34
+ *
35
+ * Example: For an input of
36
+ *
37
+ * ```
38
+ * [
39
+ * { kind: ['API', 'Component'] },
40
+ * { 'metadata.name': 'a', 'metadata.namespace': 'b' }
41
+ * ]
42
+ * ```
43
+ *
44
+ * This effectively means
45
+ *
46
+ * ```
47
+ * (kind = EITHER 'API' OR 'Component')
48
+ * OR
49
+ * (metadata.name = 'a' AND metadata.namespace = 'b' )
50
+ * ```
51
+ *
52
+ * @public
53
+ */
54
+ declare type EntityFilterQuery = Record<string, string | symbol | (string | symbol)[]>[] | Record<string, string | symbol | (string | symbol)[]>;
55
+ /**
56
+ * A set of dot-separated paths into an entity's keys, showing what parts of an
57
+ * entity to include in a response, and excluding all others.
58
+ *
59
+ * @remarks
60
+ *
61
+ * Example: For an input of `['kind', 'metadata.annotations']`, then response
62
+ * objects will be shaped like
63
+ *
64
+ * ```
65
+ * {
66
+ * "kind": "Component",
67
+ * "metadata": {
68
+ * "annotations": {
69
+ * "foo": "bar"
70
+ * }
71
+ * }
72
+ * }
73
+ * ```
74
+ * @public
75
+ */
76
+ declare type EntityFieldsQuery = string[];
12
77
  /**
13
78
  * The request type for {@link CatalogClient.getEntities}.
14
79
  *
@@ -16,64 +81,14 @@ declare const CATALOG_FILTER_EXISTS: unique symbol;
16
81
  */
17
82
  interface GetEntitiesRequest {
18
83
  /**
19
- * If given, return only entities that match the given patterns.
20
- *
21
- * @remarks
22
- *
23
- * If multiple filter sets are given as an array, then there is effectively an
24
- * OR between each filter set.
25
- *
26
- * Within one filter set, there is effectively an AND between the various
27
- * keys.
28
- *
29
- * Within one key, if there are more than one value, then there is effectively
30
- * an OR between them.
31
- *
32
- * Example: For an input of
33
- *
34
- * ```
35
- * [
36
- * { kind: ['API', 'Component'] },
37
- * { 'metadata.name': 'a', 'metadata.namespace': 'b' }
38
- * ]
39
- * ```
40
- *
41
- * This effectively means
42
- *
43
- * ```
44
- * (kind = EITHER 'API' OR 'Component')
45
- * OR
46
- * (metadata.name = 'a' AND metadata.namespace = 'b' )
47
- * ```
48
- *
49
- * Each key is a dot separated path in each object.
50
- *
51
- * As a value you can also pass in the symbol `CATALOG_FILTER_EXISTS`
52
- * (exported from this package), which means that you assert on the existence
53
- * of that key, no matter what its value is.
84
+ * If given, return only entities that match the given filter.
54
85
  */
55
- filter?: Record<string, string | symbol | (string | symbol)[]>[] | Record<string, string | symbol | (string | symbol)[]> | undefined;
86
+ filter?: EntityFilterQuery;
56
87
  /**
57
- * If given, return only the parts of each entity that match those dot
58
- * separated paths in each object.
59
- *
60
- * @remarks
61
- *
62
- * Example: For an input of `['kind', 'metadata.annotations']`, then response
63
- * objects will be shaped like
64
- *
65
- * ```
66
- * {
67
- * "kind": "Component",
68
- * "metadata": {
69
- * "annotations": {
70
- * "foo": "bar"
71
- * }
72
- * }
73
- * }
74
- * ```
88
+ * If given, return only the parts of each entity that match the field
89
+ * declarations.
75
90
  */
76
- fields?: string[] | undefined;
91
+ fields?: EntityFieldsQuery;
77
92
  /**
78
93
  * If given, skips over the first N items in the result set.
79
94
  */
@@ -96,6 +111,43 @@ interface GetEntitiesRequest {
96
111
  interface GetEntitiesResponse {
97
112
  items: Entity[];
98
113
  }
114
+ /**
115
+ * The request type for {@link CatalogClient.getEntitiesByRefs}.
116
+ *
117
+ * @public
118
+ */
119
+ interface GetEntitiesByRefsRequest {
120
+ /**
121
+ * The list of entity refs to fetch.
122
+ *
123
+ * @remarks
124
+ *
125
+ * The returned list of entities will be in the same order as the refs, and
126
+ * null will be returned in those positions that were not found.
127
+ */
128
+ entityRefs: string[];
129
+ /**
130
+ * If given, return only the parts of each entity that match the field
131
+ * declarations.
132
+ */
133
+ fields?: EntityFieldsQuery | undefined;
134
+ }
135
+ /**
136
+ * The response type for {@link CatalogClient.getEntitiesByRefs}.
137
+ *
138
+ * @public
139
+ */
140
+ interface GetEntitiesByRefsResponse {
141
+ /**
142
+ * The returned list of entities.
143
+ *
144
+ * @remarks
145
+ *
146
+ * The list will be in the same order as the refs given in the request, and
147
+ * null will be returned in those positions that were not found.
148
+ */
149
+ items: Array<Entity | undefined>;
150
+ }
99
151
  /**
100
152
  * The request type for {@link CatalogClient.getEntityAncestors}.
101
153
  *
@@ -260,6 +312,19 @@ interface CatalogApi {
260
312
  * @param options - Additional options
261
313
  */
262
314
  getEntities(request?: GetEntitiesRequest, options?: CatalogRequestOptions): Promise<GetEntitiesResponse>;
315
+ /**
316
+ * Gets a batch of entities, by their entity refs.
317
+ *
318
+ * @remarks
319
+ *
320
+ * The output list of entities is of the same size and in the same order as
321
+ * the requested list of entity refs. Entries that are not found are returned
322
+ * as null.
323
+ *
324
+ * @param request - Request parameters
325
+ * @param options - Additional options
326
+ */
327
+ getEntitiesByRefs(request: GetEntitiesByRefsRequest, options?: CatalogRequestOptions): Promise<GetEntitiesByRefsResponse>;
263
328
  /**
264
329
  * Gets entity ancestor information, i.e. the hierarchy of parent entities
265
330
  * whose processing resulted in a given entity appearing in the catalog.
@@ -365,6 +430,10 @@ declare class CatalogClient implements CatalogApi {
365
430
  * {@inheritdoc CatalogApi.getEntities}
366
431
  */
367
432
  getEntities(request?: GetEntitiesRequest, options?: CatalogRequestOptions): Promise<GetEntitiesResponse>;
433
+ /**
434
+ * {@inheritdoc CatalogApi.getEntitiesByRefs}
435
+ */
436
+ getEntitiesByRefs(request: GetEntitiesByRefsRequest, options?: CatalogRequestOptions): Promise<GetEntitiesByRefsResponse>;
368
437
  /**
369
438
  * {@inheritdoc CatalogApi.getEntityByRef}
370
439
  */
@@ -414,4 +483,4 @@ declare class CatalogClient implements CatalogApi {
414
483
  */
415
484
  declare const ENTITY_STATUS_CATALOG_PROCESSING_TYPE = "backstage.io/catalog-processing";
416
485
 
417
- export { AddLocationRequest, AddLocationResponse, CATALOG_FILTER_EXISTS, CatalogApi, CatalogClient, CatalogRequestOptions, ENTITY_STATUS_CATALOG_PROCESSING_TYPE, GetEntitiesRequest, GetEntitiesResponse, GetEntityAncestorsRequest, GetEntityAncestorsResponse, GetEntityFacetsRequest, GetEntityFacetsResponse, Location, ValidateEntityResponse };
486
+ export { AddLocationRequest, AddLocationResponse, CATALOG_FILTER_EXISTS, CatalogApi, CatalogClient, CatalogRequestOptions, ENTITY_STATUS_CATALOG_PROCESSING_TYPE, EntityFieldsQuery, EntityFilterQuery, GetEntitiesByRefsRequest, GetEntitiesByRefsResponse, GetEntitiesRequest, GetEntitiesResponse, GetEntityAncestorsRequest, GetEntityAncestorsResponse, GetEntityFacetsRequest, GetEntityFacetsResponse, Location, ValidateEntityResponse };
package/dist/index.esm.js CHANGED
@@ -83,6 +83,29 @@ class CatalogClient {
83
83
  };
84
84
  return { items: entities.sort(refCompare) };
85
85
  }
86
+ async getEntitiesByRefs(request, options) {
87
+ var _a;
88
+ const params = [];
89
+ if ((_a = request.fields) == null ? void 0 : _a.length) {
90
+ params.push(`fields=${request.fields.map(encodeURIComponent).join(",")}`);
91
+ }
92
+ const baseUrl = await this.discoveryApi.getBaseUrl("catalog");
93
+ const query = params.length ? `?${params.join("&")}` : "";
94
+ const url = `${baseUrl}/entities/by-refs${query}`;
95
+ const response = await this.fetchApi.fetch(url, {
96
+ headers: {
97
+ "Content-Type": "application/json",
98
+ ...(options == null ? void 0 : options.token) && { Authorization: `Bearer ${options == null ? void 0 : options.token}` }
99
+ },
100
+ method: "POST",
101
+ body: JSON.stringify({ entityRefs: request.entityRefs })
102
+ });
103
+ if (!response.ok) {
104
+ throw await ResponseError.fromResponse(response);
105
+ }
106
+ const { items } = await response.json();
107
+ return { items };
108
+ }
86
109
  async getEntityByRef(entityRef, options) {
87
110
  const { kind, namespace, name } = parseEntityRef(entityRef);
88
111
  return this.requestOptional(
@@ -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';\nimport { SerializedError } from '@backstage/errors';\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 * The response type for {@link CatalogClient.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\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 * Validate entity and its location.\n *\n * @param entity - Entity to validate\n * @param locationRef - Location ref in format `url:http://example.com/file`\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\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 ValidateEntityResponse,\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 request: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const { type = 'url', target, dryRun } = request;\n\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 * {@inheritdoc CatalogApi.validateEntity}\n */\n async validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/validate-entity`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entity, location: locationRef }),\n },\n );\n\n if (response.ok) {\n return {\n valid: true,\n };\n }\n\n if (response.status !== 400) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { errors = [] } = await response.json();\n\n return {\n valid: false,\n errors,\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';\nimport { SerializedError } from '@backstage/errors';\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 * A key-value based filter expression for entities.\n *\n * @remarks\n *\n * Each key of a record is a dot-separated path into the entity structure, e.g.\n * `metadata.name`.\n *\n * The values are literal values to match against. As a value you can also pass\n * in the symbol `CATALOG_FILTER_EXISTS` (exported from this package), which\n * means that you assert on the existence of that key, no matter what its value\n * is.\n *\n * All matching of keys and values is case insensitive.\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 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 * @public\n */\nexport type EntityFilterQuery =\n | Record<string, string | symbol | (string | symbol)[]>[]\n | Record<string, string | symbol | (string | symbol)[]>;\n\n/**\n * A set of dot-separated paths into an entity's keys, showing what parts of an\n * entity to include in a response, and excluding all others.\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 * @public\n */\nexport type EntityFieldsQuery = string[];\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 filter.\n */\n filter?: EntityFilterQuery;\n /**\n * If given, return only the parts of each entity that match the field\n * declarations.\n */\n fields?: EntityFieldsQuery;\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.getEntitiesByRefs}.\n *\n * @public\n */\nexport interface GetEntitiesByRefsRequest {\n /**\n * The list of entity refs to fetch.\n *\n * @remarks\n *\n * The returned list of entities will be in the same order as the refs, and\n * null will be returned in those positions that were not found.\n */\n entityRefs: string[];\n /**\n * If given, return only the parts of each entity that match the field\n * declarations.\n */\n fields?: EntityFieldsQuery | undefined;\n}\n\n/**\n * The response type for {@link CatalogClient.getEntitiesByRefs}.\n *\n * @public\n */\nexport interface GetEntitiesByRefsResponse {\n /**\n * The returned list of entities.\n *\n * @remarks\n *\n * The list will be in the same order as the refs given in the request, and\n * null will be returned in those positions that were not found.\n */\n items: Array<Entity | undefined>;\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 * The response type for {@link CatalogClient.validateEntity}\n *\n * @public\n */\nexport type ValidateEntityResponse =\n | { valid: true }\n | { valid: false; errors: SerializedError[] };\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 a batch of entities, by their entity refs.\n *\n * @remarks\n *\n * The output list of entities is of the same size and in the same order as\n * the requested list of entity refs. Entries that are not found are returned\n * as null.\n *\n * @param request - Request parameters\n * @param options - Additional options\n */\n getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse>;\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 * Validate entity and its location.\n *\n * @param entity - Entity to validate\n * @param locationRef - Location ref in format `url:http://example.com/file`\n */\n validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse>;\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 ValidateEntityResponse,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\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.getEntitiesByRefs}\n */\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse> {\n const params: string[] = [];\n if (request.fields?.length) {\n params.push(`fields=${request.fields.map(encodeURIComponent).join(',')}`);\n }\n\n const baseUrl = await this.discoveryApi.getBaseUrl('catalog');\n const query = params.length ? `?${params.join('&')}` : '';\n const url = `${baseUrl}/entities/by-refs${query}`;\n\n const response = await this.fetchApi.fetch(url, {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entityRefs: request.entityRefs }),\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { items } = await response.json();\n\n return { items };\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 request: AddLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AddLocationResponse> {\n const { type = 'url', target, dryRun } = request;\n\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 * {@inheritdoc CatalogApi.validateEntity}\n */\n async validateEntity(\n entity: Entity,\n locationRef: string,\n options?: CatalogRequestOptions,\n ): Promise<ValidateEntityResponse> {\n const response = await this.fetchApi.fetch(\n `${await this.discoveryApi.getBaseUrl('catalog')}/validate-entity`,\n {\n headers: {\n 'Content-Type': 'application/json',\n ...(options?.token && { Authorization: `Bearer ${options?.token}` }),\n },\n method: 'POST',\n body: JSON.stringify({ entity, location: locationRef }),\n },\n );\n\n if (response.ok) {\n return {\n valid: true,\n };\n }\n\n if (response.status !== 400) {\n throw await ResponseError.fromResponse(response);\n }\n\n const { errors = [] } = await response.json();\n\n return {\n valid: false,\n errors,\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":";;;;AA0BO,MAAM,wBAAwB,MAAO,CAAA,GAAA;AAAA,EAE1C,wDAAA;AACF;;ACsBO,MAAM,aAAoC,CAAA;AAAA,EAI/C,YAAY,OAGT,EAAA;AACD,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA,CAAA;AAC5B,IAAA,IAAA,CAAK,QAAW,GAAA,OAAA,CAAQ,QAAY,IAAA,EAAE,OAAO,UAAW,EAAA,CAAA;AAAA,GAC1D;AAAA,EAKA,MAAM,kBACJ,CAAA,OAAA,EACA,OACqC,EAAA;AACrC,IAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,MAAS,GAAA,cAAA,CAAe,QAAQ,SAAS,CAAA,CAAA;AAClE,IAAA,OAAO,MAAM,IAAK,CAAA,eAAA;AAAA,MAChB,KAAA;AAAA,MACA,CAAA,kBAAA,EAAqB,kBAAmB,CAAA,IAAI,CAAK,CAAA,CAAA,EAAA,kBAAA;AAAA,QAC/C,SAAA;AAAA,OACF,CAAA,CAAA,EAAK,mBAAmB,IAAI,CAAA,CAAA,SAAA,CAAA;AAAA,MAC5B,OAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAKA,MAAM,eACJ,CAAA,EAAA,EACA,OAC+B,EAAA;AAC/B,IAAA,OAAO,MAAM,IAAK,CAAA,eAAA;AAAA,MAChB,KAAA;AAAA,MACA,CAAA,WAAA,EAAc,mBAAmB,EAAE,CAAA,CAAA,CAAA;AAAA,MACnC,OAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAKA,MAAM,WACJ,CAAA,OAAA,EACA,OAC8B,EAAA;AAC9B,IAAA,MAAM,EAAE,MAAA,GAAS,EAAC,EAAG,MAAS,GAAA,EAAI,EAAA,MAAA,EAAQ,KAAO,EAAA,KAAA,EAAU,GAAA,OAAA,IAAA,IAAA,GAAA,OAAA,GAAW,EAAC,CAAA;AACvE,IAAA,MAAM,SAAmB,EAAC,CAAA;AAM1B,IAAA,KAAA,MAAW,UAAc,IAAA,CAAC,MAAM,CAAA,CAAE,MAAQ,EAAA;AACxC,MAAA,MAAM,cAAwB,EAAC,CAAA;AAC/B,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,UAAU,CAAG,EAAA;AACrD,QAAA,KAAA,MAAW,CAAK,IAAA,CAAC,KAAK,CAAA,CAAE,MAAQ,EAAA;AAC9B,UAAA,IAAI,MAAM,qBAAuB,EAAA;AAC/B,YAAY,WAAA,CAAA,IAAA,CAAK,kBAAmB,CAAA,GAAG,CAAC,CAAA,CAAA;AAAA,WAC1C,MAAA,IAAW,OAAO,CAAA,KAAM,QAAU,EAAA;AAChC,YAAY,WAAA,CAAA,IAAA;AAAA,cACV,CAAG,EAAA,kBAAA,CAAmB,GAAG,CAAA,CAAA,CAAA,EAAK,mBAAmB,CAAC,CAAA,CAAA,CAAA;AAAA,aACpD,CAAA;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAEA,MAAA,IAAI,YAAY,MAAQ,EAAA;AACtB,QAAA,MAAA,CAAO,IAAK,CAAA,CAAA,OAAA,EAAU,WAAY,CAAA,IAAA,CAAK,GAAG,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,OAC/C;AAAA,KACF;AAEA,IAAA,IAAI,OAAO,MAAQ,EAAA;AACjB,MAAO,MAAA,CAAA,IAAA,CAAK,UAAU,MAAO,CAAA,GAAA,CAAI,kBAAkB,CAAE,CAAA,IAAA,CAAK,GAAG,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KAClE;AAEA,IAAA,IAAI,WAAW,KAAW,CAAA,EAAA;AACxB,MAAO,MAAA,CAAA,IAAA,CAAK,UAAU,MAAQ,CAAA,CAAA,CAAA,CAAA;AAAA,KAChC;AACA,IAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,MAAO,MAAA,CAAA,IAAA,CAAK,SAAS,KAAO,CAAA,CAAA,CAAA,CAAA;AAAA,KAC9B;AACA,IAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,MAAA,MAAA,CAAO,IAAK,CAAA,CAAA,MAAA,EAAS,kBAAmB,CAAA,KAAK,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KAClD;AAEA,IAAA,MAAM,QAAQ,MAAO,CAAA,MAAA,GAAS,IAAI,MAAO,CAAA,IAAA,CAAK,GAAG,CAAM,CAAA,CAAA,GAAA,EAAA,CAAA;AACvD,IAAM,MAAA,QAAA,GAAqB,MAAM,IAAK,CAAA,eAAA;AAAA,MACpC,KAAA;AAAA,MACA,CAAY,SAAA,EAAA,KAAA,CAAA,CAAA;AAAA,MACZ,OAAA;AAAA,KACF,CAAA;AAEA,IAAM,MAAA,UAAA,GAAa,CAAC,CAAA,EAAW,CAAc,KAAA;AApJjD,MAAA,IAAA,EAAA,EAAA,EAAA,CAAA;AAsJM,MAAA,IAAA,CAAA,CACE,EAAE,GAAA,CAAA,CAAA,QAAA,KAAF,IAAY,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,MAAS,UACrB,CAAE,CAAA,IAAA,KAAS,KACX,CAAA,IAAA,CAAA,CAAA,EAAA,GAAA,CAAA,CAAE,aAAF,IAAY,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAA,MAAS,KACrB,CAAA,IAAA,CAAA,CAAE,SAAS,KACX,CAAA,EAAA;AACA,QAAO,OAAA,CAAA,CAAA;AAAA,OACT;AAEA,MAAM,MAAA,IAAA,GAAO,mBAAmB,CAAC,CAAA,CAAA;AACjC,MAAM,MAAA,IAAA,GAAO,mBAAmB,CAAC,CAAA,CAAA;AACjC,MAAA,IAAI,OAAO,IAAM,EAAA;AACf,QAAO,OAAA,CAAA,CAAA,CAAA;AAAA,OACT;AACA,MAAA,IAAI,OAAO,IAAM,EAAA;AACf,QAAO,OAAA,CAAA,CAAA;AAAA,OACT;AACA,MAAO,OAAA,CAAA,CAAA;AAAA,KACT,CAAA;AAEA,IAAA,OAAO,EAAE,KAAA,EAAO,QAAS,CAAA,IAAA,CAAK,UAAU,CAAE,EAAA,CAAA;AAAA,GAC5C;AAAA,EAKA,MAAM,iBACJ,CAAA,OAAA,EACA,OACoC,EAAA;AAnLxC,IAAA,IAAA,EAAA,CAAA;AAoLI,IAAA,MAAM,SAAmB,EAAC,CAAA;AAC1B,IAAI,IAAA,CAAA,EAAA,GAAA,OAAA,CAAQ,MAAR,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAgB,MAAQ,EAAA;AAC1B,MAAO,MAAA,CAAA,IAAA,CAAK,UAAU,OAAQ,CAAA,MAAA,CAAO,IAAI,kBAAkB,CAAA,CAAE,IAAK,CAAA,GAAG,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KAC1E;AAEA,IAAA,MAAM,OAAU,GAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,SAAS,CAAA,CAAA;AAC5D,IAAA,MAAM,QAAQ,MAAO,CAAA,MAAA,GAAS,IAAI,MAAO,CAAA,IAAA,CAAK,GAAG,CAAM,CAAA,CAAA,GAAA,EAAA,CAAA;AACvD,IAAM,MAAA,GAAA,GAAM,GAAG,OAA2B,CAAA,iBAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAE1C,IAAA,MAAM,QAAW,GAAA,MAAM,IAAK,CAAA,QAAA,CAAS,MAAM,GAAK,EAAA;AAAA,MAC9C,OAAS,EAAA;AAAA,QACP,cAAgB,EAAA,kBAAA;AAAA,QAChB,IAAI,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,KAAA,KAAS,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,mCAAS,KAAQ,CAAA,CAAA,EAAA;AAAA,OACpE;AAAA,MACA,MAAQ,EAAA,MAAA;AAAA,MACR,MAAM,IAAK,CAAA,SAAA,CAAU,EAAE,UAAY,EAAA,OAAA,CAAQ,YAAY,CAAA;AAAA,KACxD,CAAA,CAAA;AAED,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAM,aAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AAEA,IAAA,MAAM,EAAE,KAAA,EAAU,GAAA,MAAM,SAAS,IAAK,EAAA,CAAA;AAEtC,IAAA,OAAO,EAAE,KAAM,EAAA,CAAA;AAAA,GACjB;AAAA,EAKA,MAAM,cACJ,CAAA,SAAA,EACA,OAC6B,EAAA;AAC7B,IAAA,MAAM,EAAE,IAAM,EAAA,SAAA,EAAW,IAAK,EAAA,GAAI,eAAe,SAAS,CAAA,CAAA;AAC1D,IAAA,OAAO,IAAK,CAAA,eAAA;AAAA,MACV,KAAA;AAAA,MACA,CAAA,kBAAA,EAAqB,kBAAmB,CAAA,IAAI,CAAK,CAAA,CAAA,EAAA,kBAAA;AAAA,QAC/C,SAAA;AAAA,OACF,CAAA,CAAA,EAAK,mBAAmB,IAAI,CAAA,CAAA,CAAA;AAAA,MAC5B,OAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EASA,MAAM,eACJ,CAAA,YAAA,EACA,OAC6B,EAAA;AAC7B,IAAA,MAAM,EAAE,IAAA,EAAM,SAAY,GAAA,SAAA,EAAW,MAAS,GAAA,YAAA,CAAA;AAC9C,IAAA,OAAO,IAAK,CAAA,eAAA;AAAA,MACV,KAAA;AAAA,MACA,CAAA,kBAAA,EAAqB,kBAAmB,CAAA,IAAI,CAAK,CAAA,CAAA,EAAA,kBAAA;AAAA,QAC/C,SAAA;AAAA,OACF,CAAA,CAAA,EAAK,mBAAmB,IAAI,CAAA,CAAA,CAAA;AAAA,MAC5B,OAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAKA,MAAM,aAAc,CAAA,SAAA,EAAmB,OAAiC,EAAA;AACtE,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,QAAS,CAAA,KAAA;AAAA,MACnC,CAAG,EAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,SAAS,CAAA,CAAA,QAAA,CAAA;AAAA,MAC/C;AAAA,QACE,OAAS,EAAA;AAAA,UACP,cAAgB,EAAA,kBAAA;AAAA,UAChB,IAAI,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,KAAA,KAAS,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,mCAAS,KAAQ,CAAA,CAAA,EAAA;AAAA,SACpE;AAAA,QACA,MAAQ,EAAA,MAAA;AAAA,QACR,IAAM,EAAA,IAAA,CAAK,SAAU,CAAA,EAAE,WAAW,CAAA;AAAA,OACpC;AAAA,KACF,CAAA;AAEA,IAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,KACvC;AAAA,GACF;AAAA,EAKA,MAAM,eACJ,CAAA,OAAA,EACA,OACkC,EAAA;AAClC,IAAA,MAAM,EAAE,MAAA,GAAS,EAAC,EAAG,QAAW,GAAA,OAAA,CAAA;AAChC,IAAA,MAAM,SAAmB,EAAC,CAAA;AAM1B,IAAA,KAAA,MAAW,UAAc,IAAA,CAAC,MAAM,CAAA,CAAE,MAAQ,EAAA;AACxC,MAAA,MAAM,cAAwB,EAAC,CAAA;AAC/B,MAAA,KAAA,MAAW,CAAC,GAAK,EAAA,KAAK,KAAK,MAAO,CAAA,OAAA,CAAQ,UAAU,CAAG,EAAA;AACrD,QAAA,KAAA,MAAW,CAAK,IAAA,CAAC,KAAK,CAAA,CAAE,MAAQ,EAAA;AAC9B,UAAA,IAAI,MAAM,qBAAuB,EAAA;AAC/B,YAAY,WAAA,CAAA,IAAA,CAAK,kBAAmB,CAAA,GAAG,CAAC,CAAA,CAAA;AAAA,WAC1C,MAAA,IAAW,OAAO,CAAA,KAAM,QAAU,EAAA;AAChC,YAAY,WAAA,CAAA,IAAA;AAAA,cACV,CAAG,EAAA,kBAAA,CAAmB,GAAG,CAAA,CAAA,CAAA,EAAK,mBAAmB,CAAC,CAAA,CAAA,CAAA;AAAA,aACpD,CAAA;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAEA,MAAA,IAAI,YAAY,MAAQ,EAAA;AACtB,QAAA,MAAA,CAAO,IAAK,CAAA,CAAA,OAAA,EAAU,WAAY,CAAA,IAAA,CAAK,GAAG,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,OAC/C;AAAA,KACF;AAEA,IAAA,KAAA,MAAW,SAAS,MAAQ,EAAA;AAC1B,MAAA,MAAA,CAAO,IAAK,CAAA,CAAA,MAAA,EAAS,kBAAmB,CAAA,KAAK,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KAClD;AAEA,IAAA,MAAM,QAAQ,MAAO,CAAA,MAAA,GAAS,IAAI,MAAO,CAAA,IAAA,CAAK,GAAG,CAAM,CAAA,CAAA,GAAA,EAAA,CAAA;AACvD,IAAA,OAAO,MAAM,IAAK,CAAA,eAAA,CAAgB,KAAO,EAAA,CAAA,cAAA,EAAiB,SAAS,OAAO,CAAA,CAAA;AAAA,GAC5E;AAAA,EAKA,MAAM,WACJ,CAAA,OAAA,EACA,OAC8B,EAAA;AAC9B,IAAA,MAAM,EAAE,IAAA,GAAO,KAAO,EAAA,MAAA,EAAQ,QAAW,GAAA,OAAA,CAAA;AAEzC,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,QAAS,CAAA,KAAA;AAAA,MACnC,CAAA,EAAG,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,SAAS,CAAA,CAAA,UAAA,EAC7C,SAAS,cAAiB,GAAA,EAAA,CAAA,CAAA;AAAA,MAE5B;AAAA,QACE,OAAS,EAAA;AAAA,UACP,cAAgB,EAAA,kBAAA;AAAA,UAChB,IAAI,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,KAAA,KAAS,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,mCAAS,KAAQ,CAAA,CAAA,EAAA;AAAA,SACpE;AAAA,QACA,MAAQ,EAAA,MAAA;AAAA,QACR,MAAM,IAAK,CAAA,SAAA,CAAU,EAAE,IAAA,EAAM,QAAQ,CAAA;AAAA,OACvC;AAAA,KACF,CAAA;AAEA,IAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,MAAA,MAAM,IAAI,KAAA,CAAM,MAAM,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,KACvC;AAEA,IAAA,MAAM,EAAE,QAAU,EAAA,QAAA,EAAU,QAAW,GAAA,MAAM,SAAS,IAAK,EAAA,CAAA;AAE3D,IAAA,IAAI,CAAC,QAAU,EAAA;AACb,MAAM,MAAA,IAAI,KAAM,CAAA,CAAA,uBAAA,EAA0B,MAAQ,CAAA,CAAA,CAAA,CAAA;AAAA,KACpD;AAEA,IAAO,OAAA;AAAA,MACL,QAAA;AAAA,MACA,QAAA;AAAA,MACA,MAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAKA,MAAM,gBACJ,CAAA,WAAA,EACA,OAC+B,EAAA;AAC/B,IAAM,MAAA,GAAA,GAA4B,MAAM,IAAK,CAAA,eAAA;AAAA,MAC3C,KAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA;AAAA,KACF,CAAA;AACA,IAAO,OAAA,GAAA,CACJ,GAAI,CAAA,CAAA,CAAA,KAAK,CAAE,CAAA,IAAI,CACf,CAAA,IAAA,CAAK,CAAK,CAAA,KAAA,WAAA,KAAgB,oBAAqB,CAAA,CAAC,CAAC,CAAA,CAAA;AAAA,GACtD;AAAA,EAKA,MAAM,kBACJ,CAAA,EAAA,EACA,OACe,EAAA;AACf,IAAA,MAAM,IAAK,CAAA,cAAA;AAAA,MACT,QAAA;AAAA,MACA,CAAA,WAAA,EAAc,mBAAmB,EAAE,CAAA,CAAA,CAAA;AAAA,MACnC,OAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAKA,MAAM,iBACJ,CAAA,GAAA,EACA,OACe,EAAA;AACf,IAAA,MAAM,IAAK,CAAA,cAAA;AAAA,MACT,QAAA;AAAA,MACA,CAAA,iBAAA,EAAoB,mBAAmB,GAAG,CAAA,CAAA,CAAA;AAAA,MAC1C,OAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAKA,MAAM,cAAA,CACJ,MACA,EAAA,WAAA,EACA,OACiC,EAAA;AACjC,IAAM,MAAA,QAAA,GAAW,MAAM,IAAA,CAAK,QAAS,CAAA,KAAA;AAAA,MACnC,CAAG,EAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,SAAS,CAAA,CAAA,gBAAA,CAAA;AAAA,MAC/C;AAAA,QACE,OAAS,EAAA;AAAA,UACP,cAAgB,EAAA,kBAAA;AAAA,UAChB,IAAI,OAAS,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,OAAA,CAAA,KAAA,KAAS,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,mCAAS,KAAQ,CAAA,CAAA,EAAA;AAAA,SACpE;AAAA,QACA,MAAQ,EAAA,MAAA;AAAA,QACR,MAAM,IAAK,CAAA,SAAA,CAAU,EAAE,MAAQ,EAAA,QAAA,EAAU,aAAa,CAAA;AAAA,OACxD;AAAA,KACF,CAAA;AAEA,IAAA,IAAI,SAAS,EAAI,EAAA;AACf,MAAO,OAAA;AAAA,QACL,KAAO,EAAA,IAAA;AAAA,OACT,CAAA;AAAA,KACF;AAEA,IAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,MAAM,MAAA,MAAM,aAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AAEA,IAAA,MAAM,EAAE,MAAS,GAAA,IAAO,GAAA,MAAM,SAAS,IAAK,EAAA,CAAA;AAE5C,IAAO,OAAA;AAAA,MACL,KAAO,EAAA,KAAA;AAAA,MACP,MAAA;AAAA,KACF,CAAA;AAAA,GACF;AAAA,EAMA,MAAc,cAAA,CACZ,MACA,EAAA,IAAA,EACA,OACe,EAAA;AACf,IAAA,MAAM,MAAM,CAAG,EAAA,MAAM,KAAK,YAAa,CAAA,UAAA,CAAW,SAAS,CAAI,CAAA,EAAA,IAAA,CAAA,CAAA,CAAA;AAC/D,IAAM,MAAA,OAAA,GAAA,CAAkC,mCAAS,KAC7C,IAAA,EAAE,eAAe,CAAU,OAAA,EAAA,OAAA,CAAQ,KAAQ,CAAA,CAAA,EAAA,GAC3C,EAAC,CAAA;AACL,IAAM,MAAA,QAAA,GAAW,MAAM,IAAK,CAAA,QAAA,CAAS,MAAM,GAAK,EAAA,EAAE,MAAQ,EAAA,OAAA,EAAS,CAAA,CAAA;AAEnE,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAM,aAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AAAA,GACF;AAAA,EAEA,MAAc,eAAA,CACZ,MACA,EAAA,IAAA,EACA,OACc,EAAA;AACd,IAAA,MAAM,MAAM,CAAG,EAAA,MAAM,KAAK,YAAa,CAAA,UAAA,CAAW,SAAS,CAAI,CAAA,EAAA,IAAA,CAAA,CAAA,CAAA;AAC/D,IAAM,MAAA,OAAA,GAAA,CAAkC,mCAAS,KAC7C,IAAA,EAAE,eAAe,CAAU,OAAA,EAAA,OAAA,CAAQ,KAAQ,CAAA,CAAA,EAAA,GAC3C,EAAC,CAAA;AACL,IAAM,MAAA,QAAA,GAAW,MAAM,IAAK,CAAA,QAAA,CAAS,MAAM,GAAK,EAAA,EAAE,MAAQ,EAAA,OAAA,EAAS,CAAA,CAAA;AAEnE,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAM,MAAA,MAAM,aAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AAEA,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA,CAAA;AAAA,GAC7B;AAAA,EAEA,MAAc,eAAA,CACZ,MACA,EAAA,IAAA,EACA,OAC0B,EAAA;AAC1B,IAAA,MAAM,MAAM,CAAG,EAAA,MAAM,KAAK,YAAa,CAAA,UAAA,CAAW,SAAS,CAAI,CAAA,EAAA,IAAA,CAAA,CAAA,CAAA;AAC/D,IAAM,MAAA,OAAA,GAAA,CAAkC,mCAAS,KAC7C,IAAA,EAAE,eAAe,CAAU,OAAA,EAAA,OAAA,CAAQ,KAAQ,CAAA,CAAA,EAAA,GAC3C,EAAC,CAAA;AACL,IAAM,MAAA,QAAA,GAAW,MAAM,IAAK,CAAA,QAAA,CAAS,MAAM,GAAK,EAAA,EAAE,MAAQ,EAAA,OAAA,EAAS,CAAA,CAAA;AAEnE,IAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,MAAI,IAAA,QAAA,CAAS,WAAW,GAAK,EAAA;AAC3B,QAAO,OAAA,KAAA,CAAA,CAAA;AAAA,OACT;AACA,MAAM,MAAA,MAAM,aAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AAEA,IAAO,OAAA,MAAM,SAAS,IAAK,EAAA,CAAA;AAAA,GAC7B;AACF;;ACldO,MAAM,qCACX,GAAA;;;;"}
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": "1.1.2",
4
+ "version": "1.2.0-next.0",
5
5
  "main": "dist/index.cjs.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "Apache-2.0",
@@ -32,13 +32,13 @@
32
32
  "clean": "backstage-cli package clean"
33
33
  },
34
34
  "dependencies": {
35
- "@backstage/catalog-model": "^1.1.3",
36
- "@backstage/errors": "^1.1.3",
35
+ "@backstage/catalog-model": "^1.1.4-next.0",
36
+ "@backstage/errors": "^1.1.4-next.0",
37
37
  "cross-fetch": "^3.1.5"
38
38
  },
39
39
  "devDependencies": {
40
- "@backstage/cli": "^0.21.0",
41
- "msw": "^0.48.0"
40
+ "@backstage/cli": "^0.21.2-next.0",
41
+ "msw": "^0.49.0"
42
42
  },
43
43
  "files": [
44
44
  "dist"