@backstage/catalog-client 1.12.2-next.0 → 1.13.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,17 @@
1
1
  # @backstage/catalog-client
2
2
 
3
+ ## 1.13.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b4e8249: Implemented support for the new `queryLocations` and `streamLocations` that allow paginated/streamed and filtered location queries
8
+
9
+ ### Patch Changes
10
+
11
+ - 9cf6762: Improved the `InMemoryCatalogClient` test utility to support ordering, pagination, full-text search, and field projection for entity query methods. Also fixed `getEntityFacets` to correctly handle multi-valued fields.
12
+ - Updated dependencies
13
+ - @backstage/filter-predicates@0.1.0
14
+
3
15
  ## 1.12.2-next.0
4
16
 
5
17
  ### Patch Changes
@@ -34,6 +34,43 @@ class CatalogClient {
34
34
  items: res.map((item) => item.data)
35
35
  };
36
36
  }
37
+ /**
38
+ * {@inheritdoc CatalogApi.queryLocations}
39
+ */
40
+ async queryLocations(request, options) {
41
+ const res = await this.requestRequired(
42
+ await this.apiClient.getLocationsByQuery(
43
+ { body: request ?? {} },
44
+ options
45
+ )
46
+ );
47
+ return {
48
+ items: res.items,
49
+ totalItems: res.totalItems,
50
+ pageInfo: res.pageInfo
51
+ };
52
+ }
53
+ /**
54
+ * {@inheritdoc CatalogApi.streamLocations}
55
+ */
56
+ async *streamLocations(request, options) {
57
+ let response = await this.queryLocations(
58
+ { limit: constants.DEFAULT_STREAM_LOCATIONS_LIMIT, ...request },
59
+ options
60
+ );
61
+ if (response.items.length) {
62
+ yield response.items;
63
+ }
64
+ while (response.pageInfo.nextCursor) {
65
+ response = await this.queryLocations(
66
+ { cursor: response.pageInfo.nextCursor },
67
+ options
68
+ );
69
+ if (response.items.length) {
70
+ yield response.items;
71
+ }
72
+ }
73
+ }
37
74
  /**
38
75
  * {@inheritdoc CatalogApi.getLocationById}
39
76
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogClient.cjs.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\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 CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n GetLocationsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n StreamEntitiesRequest,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport { DefaultApiClient, TypedResponse } from './schema/openapi';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { DEFAULT_STREAM_ENTITIES_LIMIT } from './constants.ts';\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 apiClient: DefaultApiClient;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.apiClient = new DefaultApiClient(options);\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n return await this.requestRequired(\n await this.apiClient.getEntityAncestryByName(\n { path: parseEntityRef(request.entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocations}\n */\n async getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse> {\n const res = await this.requestRequired(\n await this.apiClient.getLocations(request ?? {}, options),\n );\n return {\n items: res.map(item => item.data),\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 await this.apiClient.getLocation({ path: { id } }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByEntity}\n */\n async getLocationByEntity(\n entityRef: CompoundEntityRef | string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n await this.apiClient.getLocationByEntity(\n { path: parseEntityRef(entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const {\n filter = [],\n fields = [],\n order,\n offset,\n limit,\n after,\n } = request ?? {};\n const encodedOrder = [];\n if (order) {\n for (const directive of [order].flat()) {\n if (directive) {\n encodedOrder.push(`${directive.order}:${directive.field}`);\n }\n }\n }\n\n const entities = await this.requestRequired(\n await this.apiClient.getEntities(\n {\n query: {\n fields,\n limit,\n filter: this.getFilterValue(filter),\n offset,\n after,\n order: order ? encodedOrder : undefined,\n },\n },\n options,\n ),\n );\n return { items: entities };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntitiesByRefs}\n */\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse> {\n const getOneChunk = async (refs: string[]) => {\n const response = await this.apiClient.getEntitiesByRefs(\n {\n body: { entityRefs: refs, fields: request.fields },\n query: { filter: this.getFilterValue(request.filter) },\n },\n options,\n );\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n const body = (await response.json()) as {\n items: Array<Entity | null>;\n };\n return body.items.map(i => i ?? undefined);\n };\n\n let result: Array<Entity | undefined> | undefined;\n for (const refs of splitRefsIntoChunks(request.entityRefs)) {\n const entities = await getOneChunk(refs);\n if (!result) {\n result = entities;\n } else {\n result.push(...entities);\n }\n }\n\n return { items: result ?? [] };\n }\n\n /**\n * {@inheritdoc CatalogApi.queryEntities}\n */\n async queryEntities(\n request: QueryEntitiesRequest = {},\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse> {\n const params: Partial<\n Parameters<typeof this.apiClient.getEntitiesByQuery>[0]['query']\n > = {};\n\n if (isQueryEntitiesInitialRequest(request)) {\n const {\n fields = [],\n filter,\n limit,\n offset,\n orderFields,\n fullTextFilter,\n } = request;\n params.filter = this.getFilterValue(filter);\n\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (offset !== undefined) {\n params.offset = offset;\n }\n if (orderFields !== undefined) {\n params.orderField = (\n Array.isArray(orderFields) ? orderFields : [orderFields]\n ).map(({ field, order }) => `${field},${order}`);\n }\n if (fields.length) {\n params.fields = fields;\n }\n\n const normalizedFullTextFilterTerm = fullTextFilter?.term?.trim();\n if (normalizedFullTextFilterTerm) {\n params.fullTextFilterTerm = normalizedFullTextFilterTerm;\n }\n if (fullTextFilter?.fields?.length) {\n params.fullTextFilterFields = fullTextFilter.fields;\n }\n } else {\n const { fields = [], limit, cursor } = request;\n\n params.cursor = cursor;\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (fields.length) {\n params.fields = fields;\n }\n }\n\n return this.requestRequired(\n await this.apiClient.getEntitiesByQuery({ query: params }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n return this.requestOptional(\n await this.apiClient.getEntityByName(\n {\n path: parseEntityRef(entityRef),\n },\n options,\n ),\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 await this.apiClient.getEntityByName(\n { path: { kind, namespace, name } },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.apiClient.refreshEntity(\n { body: { entityRef } },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\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 return await this.requestOptional(\n await this.apiClient.getEntityFacets(\n {\n query: { facet: facets, filter: this.getFilterValue(filter) },\n },\n options,\n ),\n );\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.apiClient.createLocation(\n {\n body: { type, target },\n query: { dryRun: dryRun ? 'true' : undefined },\n },\n options,\n );\n\n if (response.status !== 201) {\n throw await ResponseError.fromResponse(response);\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 = await this.requestRequired(\n await this.apiClient.getLocations({}, 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 await this.apiClient.deleteLocation({ path: { id } }, 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 await this.apiClient.deleteEntityByUid({ path: { uid } }, 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.apiClient.validateEntity(\n { body: { entity, location: locationRef } },\n options,\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()) as any;\n\n return {\n valid: false,\n errors,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.analyzeLocation}\n */\n async analyzeLocation(\n request: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse> {\n const response = await this.apiClient.analyzeLocation(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<AnalyzeLocationResponse>;\n }\n\n /**\n * {@inheritdoc CatalogApi.streamEntities}\n */\n async *streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]> {\n let cursor: string | undefined = undefined;\n const limit = request?.pageSize ?? DEFAULT_STREAM_ENTITIES_LIMIT;\n do {\n const res = await this.queryEntities(\n cursor ? { ...request, cursor, limit } : { ...request, limit },\n options,\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\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 private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\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(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":["DefaultApiClient","parseEntityRef","ResponseError","splitRefsIntoChunks","isQueryEntitiesInitialRequest","stringifyLocationRef","errors","DEFAULT_STREAM_ENTITIES_LIMIT","CATALOG_FILTER_EXISTS"],"mappings":"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"}
1
+ {"version":3,"file":"CatalogClient.cjs.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\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 CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n GetLocationsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n QueryLocationsInitialRequest,\n QueryLocationsRequest,\n QueryLocationsResponse,\n StreamEntitiesRequest,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport {\n DefaultApiClient,\n GetLocationsByQueryRequest,\n TypedResponse,\n} from './schema/openapi';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport {\n DEFAULT_STREAM_ENTITIES_LIMIT,\n DEFAULT_STREAM_LOCATIONS_LIMIT,\n} from './constants';\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 apiClient: DefaultApiClient;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.apiClient = new DefaultApiClient(options);\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n return await this.requestRequired(\n await this.apiClient.getEntityAncestryByName(\n { path: parseEntityRef(request.entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocations}\n */\n async getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse> {\n const res = await this.requestRequired(\n await this.apiClient.getLocations(request ?? {}, options),\n );\n return {\n items: res.map(item => item.data),\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.queryLocations}\n */\n async queryLocations(\n request?: QueryLocationsRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryLocationsResponse> {\n const res = await this.requestRequired(\n await this.apiClient.getLocationsByQuery(\n { body: (request ?? {}) as unknown as GetLocationsByQueryRequest },\n options,\n ),\n );\n return {\n items: res.items,\n totalItems: res.totalItems,\n pageInfo: res.pageInfo,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.streamLocations}\n */\n async *streamLocations(\n request?: QueryLocationsInitialRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Location[]> {\n let response = await this.queryLocations(\n { limit: DEFAULT_STREAM_LOCATIONS_LIMIT, ...request },\n options,\n );\n if (response.items.length) {\n yield response.items;\n }\n\n while (response.pageInfo.nextCursor) {\n response = await this.queryLocations(\n { cursor: response.pageInfo.nextCursor },\n options,\n );\n if (response.items.length) {\n yield response.items;\n }\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 await this.apiClient.getLocation({ path: { id } }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByEntity}\n */\n async getLocationByEntity(\n entityRef: CompoundEntityRef | string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n await this.apiClient.getLocationByEntity(\n { path: parseEntityRef(entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const {\n filter = [],\n fields = [],\n order,\n offset,\n limit,\n after,\n } = request ?? {};\n const encodedOrder = [];\n if (order) {\n for (const directive of [order].flat()) {\n if (directive) {\n encodedOrder.push(`${directive.order}:${directive.field}`);\n }\n }\n }\n\n const entities = await this.requestRequired(\n await this.apiClient.getEntities(\n {\n query: {\n fields,\n limit,\n filter: this.getFilterValue(filter),\n offset,\n after,\n order: order ? encodedOrder : undefined,\n },\n },\n options,\n ),\n );\n return { items: entities };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntitiesByRefs}\n */\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse> {\n const getOneChunk = async (refs: string[]) => {\n const response = await this.apiClient.getEntitiesByRefs(\n {\n body: { entityRefs: refs, fields: request.fields },\n query: { filter: this.getFilterValue(request.filter) },\n },\n options,\n );\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n const body = (await response.json()) as {\n items: Array<Entity | null>;\n };\n return body.items.map(i => i ?? undefined);\n };\n\n let result: Array<Entity | undefined> | undefined;\n for (const refs of splitRefsIntoChunks(request.entityRefs)) {\n const entities = await getOneChunk(refs);\n if (!result) {\n result = entities;\n } else {\n result.push(...entities);\n }\n }\n\n return { items: result ?? [] };\n }\n\n /**\n * {@inheritdoc CatalogApi.queryEntities}\n */\n async queryEntities(\n request: QueryEntitiesRequest = {},\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse> {\n const params: Partial<\n Parameters<typeof this.apiClient.getEntitiesByQuery>[0]['query']\n > = {};\n\n if (isQueryEntitiesInitialRequest(request)) {\n const {\n fields = [],\n filter,\n limit,\n offset,\n orderFields,\n fullTextFilter,\n } = request;\n params.filter = this.getFilterValue(filter);\n\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (offset !== undefined) {\n params.offset = offset;\n }\n if (orderFields !== undefined) {\n params.orderField = (\n Array.isArray(orderFields) ? orderFields : [orderFields]\n ).map(({ field, order }) => `${field},${order}`);\n }\n if (fields.length) {\n params.fields = fields;\n }\n\n const normalizedFullTextFilterTerm = fullTextFilter?.term?.trim();\n if (normalizedFullTextFilterTerm) {\n params.fullTextFilterTerm = normalizedFullTextFilterTerm;\n }\n if (fullTextFilter?.fields?.length) {\n params.fullTextFilterFields = fullTextFilter.fields;\n }\n } else {\n const { fields = [], limit, cursor } = request;\n\n params.cursor = cursor;\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (fields.length) {\n params.fields = fields;\n }\n }\n\n return this.requestRequired(\n await this.apiClient.getEntitiesByQuery({ query: params }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n return this.requestOptional(\n await this.apiClient.getEntityByName(\n {\n path: parseEntityRef(entityRef),\n },\n options,\n ),\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 await this.apiClient.getEntityByName(\n { path: { kind, namespace, name } },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.apiClient.refreshEntity(\n { body: { entityRef } },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\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 return await this.requestOptional(\n await this.apiClient.getEntityFacets(\n {\n query: { facet: facets, filter: this.getFilterValue(filter) },\n },\n options,\n ),\n );\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.apiClient.createLocation(\n {\n body: { type, target },\n query: { dryRun: dryRun ? 'true' : undefined },\n },\n options,\n );\n\n if (response.status !== 201) {\n throw await ResponseError.fromResponse(response);\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 = await this.requestRequired(\n await this.apiClient.getLocations({}, 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 await this.apiClient.deleteLocation({ path: { id } }, 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 await this.apiClient.deleteEntityByUid({ path: { uid } }, 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.apiClient.validateEntity(\n { body: { entity, location: locationRef } },\n options,\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()) as any;\n\n return {\n valid: false,\n errors,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.analyzeLocation}\n */\n async analyzeLocation(\n request: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse> {\n const response = await this.apiClient.analyzeLocation(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<AnalyzeLocationResponse>;\n }\n\n /**\n * {@inheritdoc CatalogApi.streamEntities}\n */\n async *streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]> {\n let cursor: string | undefined = undefined;\n const limit = request?.pageSize ?? DEFAULT_STREAM_ENTITIES_LIMIT;\n do {\n const res = await this.queryEntities(\n cursor ? { ...request, cursor, limit } : { ...request, limit },\n options,\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\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 private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\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(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":["DefaultApiClient","parseEntityRef","DEFAULT_STREAM_LOCATIONS_LIMIT","ResponseError","splitRefsIntoChunks","isQueryEntitiesInitialRequest","stringifyLocationRef","errors","DEFAULT_STREAM_ENTITIES_LIMIT","CATALOG_FILTER_EXISTS"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { ResponseError } from '@backstage/errors';
3
3
  import { CATALOG_FILTER_EXISTS } from './types/api.esm.js';
4
4
  import { splitRefsIntoChunks, isQueryEntitiesInitialRequest } from './utils.esm.js';
5
5
  import { DefaultApiClient } from './schema/openapi/generated/apis/Api.client.esm.js';
6
- import { DEFAULT_STREAM_ENTITIES_LIMIT } from './constants.esm.js';
6
+ import { DEFAULT_STREAM_LOCATIONS_LIMIT, DEFAULT_STREAM_ENTITIES_LIMIT } from './constants.esm.js';
7
7
 
8
8
  class CatalogClient {
9
9
  apiClient;
@@ -32,6 +32,43 @@ class CatalogClient {
32
32
  items: res.map((item) => item.data)
33
33
  };
34
34
  }
35
+ /**
36
+ * {@inheritdoc CatalogApi.queryLocations}
37
+ */
38
+ async queryLocations(request, options) {
39
+ const res = await this.requestRequired(
40
+ await this.apiClient.getLocationsByQuery(
41
+ { body: request ?? {} },
42
+ options
43
+ )
44
+ );
45
+ return {
46
+ items: res.items,
47
+ totalItems: res.totalItems,
48
+ pageInfo: res.pageInfo
49
+ };
50
+ }
51
+ /**
52
+ * {@inheritdoc CatalogApi.streamLocations}
53
+ */
54
+ async *streamLocations(request, options) {
55
+ let response = await this.queryLocations(
56
+ { limit: DEFAULT_STREAM_LOCATIONS_LIMIT, ...request },
57
+ options
58
+ );
59
+ if (response.items.length) {
60
+ yield response.items;
61
+ }
62
+ while (response.pageInfo.nextCursor) {
63
+ response = await this.queryLocations(
64
+ { cursor: response.pageInfo.nextCursor },
65
+ options
66
+ );
67
+ if (response.items.length) {
68
+ yield response.items;
69
+ }
70
+ }
71
+ }
35
72
  /**
36
73
  * {@inheritdoc CatalogApi.getLocationById}
37
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CatalogClient.esm.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\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 CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n GetLocationsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n StreamEntitiesRequest,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport { DefaultApiClient, TypedResponse } from './schema/openapi';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport { DEFAULT_STREAM_ENTITIES_LIMIT } from './constants.ts';\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 apiClient: DefaultApiClient;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.apiClient = new DefaultApiClient(options);\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n return await this.requestRequired(\n await this.apiClient.getEntityAncestryByName(\n { path: parseEntityRef(request.entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocations}\n */\n async getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse> {\n const res = await this.requestRequired(\n await this.apiClient.getLocations(request ?? {}, options),\n );\n return {\n items: res.map(item => item.data),\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 await this.apiClient.getLocation({ path: { id } }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByEntity}\n */\n async getLocationByEntity(\n entityRef: CompoundEntityRef | string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n await this.apiClient.getLocationByEntity(\n { path: parseEntityRef(entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const {\n filter = [],\n fields = [],\n order,\n offset,\n limit,\n after,\n } = request ?? {};\n const encodedOrder = [];\n if (order) {\n for (const directive of [order].flat()) {\n if (directive) {\n encodedOrder.push(`${directive.order}:${directive.field}`);\n }\n }\n }\n\n const entities = await this.requestRequired(\n await this.apiClient.getEntities(\n {\n query: {\n fields,\n limit,\n filter: this.getFilterValue(filter),\n offset,\n after,\n order: order ? encodedOrder : undefined,\n },\n },\n options,\n ),\n );\n return { items: entities };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntitiesByRefs}\n */\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse> {\n const getOneChunk = async (refs: string[]) => {\n const response = await this.apiClient.getEntitiesByRefs(\n {\n body: { entityRefs: refs, fields: request.fields },\n query: { filter: this.getFilterValue(request.filter) },\n },\n options,\n );\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n const body = (await response.json()) as {\n items: Array<Entity | null>;\n };\n return body.items.map(i => i ?? undefined);\n };\n\n let result: Array<Entity | undefined> | undefined;\n for (const refs of splitRefsIntoChunks(request.entityRefs)) {\n const entities = await getOneChunk(refs);\n if (!result) {\n result = entities;\n } else {\n result.push(...entities);\n }\n }\n\n return { items: result ?? [] };\n }\n\n /**\n * {@inheritdoc CatalogApi.queryEntities}\n */\n async queryEntities(\n request: QueryEntitiesRequest = {},\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse> {\n const params: Partial<\n Parameters<typeof this.apiClient.getEntitiesByQuery>[0]['query']\n > = {};\n\n if (isQueryEntitiesInitialRequest(request)) {\n const {\n fields = [],\n filter,\n limit,\n offset,\n orderFields,\n fullTextFilter,\n } = request;\n params.filter = this.getFilterValue(filter);\n\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (offset !== undefined) {\n params.offset = offset;\n }\n if (orderFields !== undefined) {\n params.orderField = (\n Array.isArray(orderFields) ? orderFields : [orderFields]\n ).map(({ field, order }) => `${field},${order}`);\n }\n if (fields.length) {\n params.fields = fields;\n }\n\n const normalizedFullTextFilterTerm = fullTextFilter?.term?.trim();\n if (normalizedFullTextFilterTerm) {\n params.fullTextFilterTerm = normalizedFullTextFilterTerm;\n }\n if (fullTextFilter?.fields?.length) {\n params.fullTextFilterFields = fullTextFilter.fields;\n }\n } else {\n const { fields = [], limit, cursor } = request;\n\n params.cursor = cursor;\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (fields.length) {\n params.fields = fields;\n }\n }\n\n return this.requestRequired(\n await this.apiClient.getEntitiesByQuery({ query: params }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n return this.requestOptional(\n await this.apiClient.getEntityByName(\n {\n path: parseEntityRef(entityRef),\n },\n options,\n ),\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 await this.apiClient.getEntityByName(\n { path: { kind, namespace, name } },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.apiClient.refreshEntity(\n { body: { entityRef } },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\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 return await this.requestOptional(\n await this.apiClient.getEntityFacets(\n {\n query: { facet: facets, filter: this.getFilterValue(filter) },\n },\n options,\n ),\n );\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.apiClient.createLocation(\n {\n body: { type, target },\n query: { dryRun: dryRun ? 'true' : undefined },\n },\n options,\n );\n\n if (response.status !== 201) {\n throw await ResponseError.fromResponse(response);\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 = await this.requestRequired(\n await this.apiClient.getLocations({}, 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 await this.apiClient.deleteLocation({ path: { id } }, 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 await this.apiClient.deleteEntityByUid({ path: { uid } }, 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.apiClient.validateEntity(\n { body: { entity, location: locationRef } },\n options,\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()) as any;\n\n return {\n valid: false,\n errors,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.analyzeLocation}\n */\n async analyzeLocation(\n request: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse> {\n const response = await this.apiClient.analyzeLocation(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<AnalyzeLocationResponse>;\n }\n\n /**\n * {@inheritdoc CatalogApi.streamEntities}\n */\n async *streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]> {\n let cursor: string | undefined = undefined;\n const limit = request?.pageSize ?? DEFAULT_STREAM_ENTITIES_LIMIT;\n do {\n const res = await this.queryEntities(\n cursor ? { ...request, cursor, limit } : { ...request, limit },\n options,\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\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 private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\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(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CatalogClient.esm.js","sources":["../src/CatalogClient.ts"],"sourcesContent":["/*\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 CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyLocationRef,\n} from '@backstage/catalog-model';\nimport { ResponseError } from '@backstage/errors';\nimport {\n AddLocationRequest,\n AddLocationResponse,\n CATALOG_FILTER_EXISTS,\n CatalogApi,\n CatalogRequestOptions,\n EntityFilterQuery,\n GetEntitiesByRefsRequest,\n GetEntitiesByRefsResponse,\n GetEntitiesRequest,\n GetEntitiesResponse,\n GetEntityAncestorsRequest,\n GetEntityAncestorsResponse,\n GetEntityFacetsRequest,\n GetEntityFacetsResponse,\n GetLocationsResponse,\n Location,\n QueryEntitiesRequest,\n QueryEntitiesResponse,\n QueryLocationsInitialRequest,\n QueryLocationsRequest,\n QueryLocationsResponse,\n StreamEntitiesRequest,\n ValidateEntityResponse,\n} from './types/api';\nimport { isQueryEntitiesInitialRequest, splitRefsIntoChunks } from './utils';\nimport {\n DefaultApiClient,\n GetLocationsByQueryRequest,\n TypedResponse,\n} from './schema/openapi';\nimport type {\n AnalyzeLocationRequest,\n AnalyzeLocationResponse,\n} from '@backstage/plugin-catalog-common';\nimport {\n DEFAULT_STREAM_ENTITIES_LIMIT,\n DEFAULT_STREAM_LOCATIONS_LIMIT,\n} from './constants';\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 apiClient: DefaultApiClient;\n\n constructor(options: {\n discoveryApi: { getBaseUrl(pluginId: string): Promise<string> };\n fetchApi?: { fetch: typeof fetch };\n }) {\n this.apiClient = new DefaultApiClient(options);\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityAncestors}\n */\n async getEntityAncestors(\n request: GetEntityAncestorsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntityAncestorsResponse> {\n return await this.requestRequired(\n await this.apiClient.getEntityAncestryByName(\n { path: parseEntityRef(request.entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocations}\n */\n async getLocations(\n request?: {},\n options?: CatalogRequestOptions,\n ): Promise<GetLocationsResponse> {\n const res = await this.requestRequired(\n await this.apiClient.getLocations(request ?? {}, options),\n );\n return {\n items: res.map(item => item.data),\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.queryLocations}\n */\n async queryLocations(\n request?: QueryLocationsRequest,\n options?: CatalogRequestOptions,\n ): Promise<QueryLocationsResponse> {\n const res = await this.requestRequired(\n await this.apiClient.getLocationsByQuery(\n { body: (request ?? {}) as unknown as GetLocationsByQueryRequest },\n options,\n ),\n );\n return {\n items: res.items,\n totalItems: res.totalItems,\n pageInfo: res.pageInfo,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.streamLocations}\n */\n async *streamLocations(\n request?: QueryLocationsInitialRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Location[]> {\n let response = await this.queryLocations(\n { limit: DEFAULT_STREAM_LOCATIONS_LIMIT, ...request },\n options,\n );\n if (response.items.length) {\n yield response.items;\n }\n\n while (response.pageInfo.nextCursor) {\n response = await this.queryLocations(\n { cursor: response.pageInfo.nextCursor },\n options,\n );\n if (response.items.length) {\n yield response.items;\n }\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 await this.apiClient.getLocation({ path: { id } }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getLocationByEntity}\n */\n async getLocationByEntity(\n entityRef: CompoundEntityRef | string,\n options?: CatalogRequestOptions,\n ): Promise<Location | undefined> {\n return await this.requestOptional(\n await this.apiClient.getLocationByEntity(\n { path: parseEntityRef(entityRef) },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntities}\n */\n async getEntities(\n request?: GetEntitiesRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesResponse> {\n const {\n filter = [],\n fields = [],\n order,\n offset,\n limit,\n after,\n } = request ?? {};\n const encodedOrder = [];\n if (order) {\n for (const directive of [order].flat()) {\n if (directive) {\n encodedOrder.push(`${directive.order}:${directive.field}`);\n }\n }\n }\n\n const entities = await this.requestRequired(\n await this.apiClient.getEntities(\n {\n query: {\n fields,\n limit,\n filter: this.getFilterValue(filter),\n offset,\n after,\n order: order ? encodedOrder : undefined,\n },\n },\n options,\n ),\n );\n return { items: entities };\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntitiesByRefs}\n */\n async getEntitiesByRefs(\n request: GetEntitiesByRefsRequest,\n options?: CatalogRequestOptions,\n ): Promise<GetEntitiesByRefsResponse> {\n const getOneChunk = async (refs: string[]) => {\n const response = await this.apiClient.getEntitiesByRefs(\n {\n body: { entityRefs: refs, fields: request.fields },\n query: { filter: this.getFilterValue(request.filter) },\n },\n options,\n );\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n const body = (await response.json()) as {\n items: Array<Entity | null>;\n };\n return body.items.map(i => i ?? undefined);\n };\n\n let result: Array<Entity | undefined> | undefined;\n for (const refs of splitRefsIntoChunks(request.entityRefs)) {\n const entities = await getOneChunk(refs);\n if (!result) {\n result = entities;\n } else {\n result.push(...entities);\n }\n }\n\n return { items: result ?? [] };\n }\n\n /**\n * {@inheritdoc CatalogApi.queryEntities}\n */\n async queryEntities(\n request: QueryEntitiesRequest = {},\n options?: CatalogRequestOptions,\n ): Promise<QueryEntitiesResponse> {\n const params: Partial<\n Parameters<typeof this.apiClient.getEntitiesByQuery>[0]['query']\n > = {};\n\n if (isQueryEntitiesInitialRequest(request)) {\n const {\n fields = [],\n filter,\n limit,\n offset,\n orderFields,\n fullTextFilter,\n } = request;\n params.filter = this.getFilterValue(filter);\n\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (offset !== undefined) {\n params.offset = offset;\n }\n if (orderFields !== undefined) {\n params.orderField = (\n Array.isArray(orderFields) ? orderFields : [orderFields]\n ).map(({ field, order }) => `${field},${order}`);\n }\n if (fields.length) {\n params.fields = fields;\n }\n\n const normalizedFullTextFilterTerm = fullTextFilter?.term?.trim();\n if (normalizedFullTextFilterTerm) {\n params.fullTextFilterTerm = normalizedFullTextFilterTerm;\n }\n if (fullTextFilter?.fields?.length) {\n params.fullTextFilterFields = fullTextFilter.fields;\n }\n } else {\n const { fields = [], limit, cursor } = request;\n\n params.cursor = cursor;\n if (limit !== undefined) {\n params.limit = limit;\n }\n if (fields.length) {\n params.fields = fields;\n }\n }\n\n return this.requestRequired(\n await this.apiClient.getEntitiesByQuery({ query: params }, options),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.getEntityByRef}\n */\n async getEntityByRef(\n entityRef: string | CompoundEntityRef,\n options?: CatalogRequestOptions,\n ): Promise<Entity | undefined> {\n return this.requestOptional(\n await this.apiClient.getEntityByName(\n {\n path: parseEntityRef(entityRef),\n },\n options,\n ),\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 await this.apiClient.getEntityByName(\n { path: { kind, namespace, name } },\n options,\n ),\n );\n }\n\n /**\n * {@inheritdoc CatalogApi.refreshEntity}\n */\n async refreshEntity(entityRef: string, options?: CatalogRequestOptions) {\n const response = await this.apiClient.refreshEntity(\n { body: { entityRef } },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\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 return await this.requestOptional(\n await this.apiClient.getEntityFacets(\n {\n query: { facet: facets, filter: this.getFilterValue(filter) },\n },\n options,\n ),\n );\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.apiClient.createLocation(\n {\n body: { type, target },\n query: { dryRun: dryRun ? 'true' : undefined },\n },\n options,\n );\n\n if (response.status !== 201) {\n throw await ResponseError.fromResponse(response);\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 = await this.requestRequired(\n await this.apiClient.getLocations({}, 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 await this.apiClient.deleteLocation({ path: { id } }, 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 await this.apiClient.deleteEntityByUid({ path: { uid } }, 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.apiClient.validateEntity(\n { body: { entity, location: locationRef } },\n options,\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()) as any;\n\n return {\n valid: false,\n errors,\n };\n }\n\n /**\n * {@inheritdoc CatalogApi.analyzeLocation}\n */\n async analyzeLocation(\n request: AnalyzeLocationRequest,\n options?: CatalogRequestOptions,\n ): Promise<AnalyzeLocationResponse> {\n const response = await this.apiClient.analyzeLocation(\n {\n body: request,\n },\n options,\n );\n\n if (response.status !== 200) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json() as Promise<AnalyzeLocationResponse>;\n }\n\n /**\n * {@inheritdoc CatalogApi.streamEntities}\n */\n async *streamEntities(\n request?: StreamEntitiesRequest,\n options?: CatalogRequestOptions,\n ): AsyncIterable<Entity[]> {\n let cursor: string | undefined = undefined;\n const limit = request?.pageSize ?? DEFAULT_STREAM_ENTITIES_LIMIT;\n do {\n const res = await this.queryEntities(\n cursor ? { ...request, cursor, limit } : { ...request, limit },\n options,\n );\n\n yield res.items;\n\n cursor = res.pageInfo.nextCursor;\n } while (cursor);\n }\n\n //\n // Private methods\n //\n\n private async requestIgnored(response: Response): Promise<void> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n }\n\n private async requestRequired<T>(response: TypedResponse<T>): Promise<T> {\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n\n private async requestOptional(response: Response): Promise<any | undefined> {\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 private getFilterValue(filter: EntityFilterQuery = []) {\n const filters: string[] = [];\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(key);\n } else if (typeof v === 'string') {\n filterParts.push(`${key}=${v}`);\n }\n }\n }\n\n if (filterParts.length) {\n filters.push(filterParts.join(','));\n }\n }\n return filters;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const DEFAULT_STREAM_ENTITIES_LIMIT = 500;
4
+ const DEFAULT_STREAM_LOCATIONS_LIMIT = 500;
4
5
 
5
6
  exports.DEFAULT_STREAM_ENTITIES_LIMIT = DEFAULT_STREAM_ENTITIES_LIMIT;
7
+ exports.DEFAULT_STREAM_LOCATIONS_LIMIT = DEFAULT_STREAM_LOCATIONS_LIMIT;
6
8
  //# sourceMappingURL=constants.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.cjs.js","sources":["../src/constants.ts"],"sourcesContent":["/*\n * Copyright 2025 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\nexport const DEFAULT_STREAM_ENTITIES_LIMIT = 500;\n"],"names":[],"mappings":";;AAgBO,MAAM,6BAAA,GAAgC;;;;"}
1
+ {"version":3,"file":"constants.cjs.js","sources":["../src/constants.ts"],"sourcesContent":["/*\n * Copyright 2025 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\nexport const DEFAULT_STREAM_ENTITIES_LIMIT = 500;\nexport const DEFAULT_STREAM_LOCATIONS_LIMIT = 500;\n"],"names":[],"mappings":";;AAgBO,MAAM,6BAAA,GAAgC;AACtC,MAAM,8BAAA,GAAiC;;;;;"}
@@ -1,4 +1,5 @@
1
1
  const DEFAULT_STREAM_ENTITIES_LIMIT = 500;
2
+ const DEFAULT_STREAM_LOCATIONS_LIMIT = 500;
2
3
 
3
- export { DEFAULT_STREAM_ENTITIES_LIMIT };
4
+ export { DEFAULT_STREAM_ENTITIES_LIMIT, DEFAULT_STREAM_LOCATIONS_LIMIT };
4
5
  //# sourceMappingURL=constants.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.esm.js","sources":["../src/constants.ts"],"sourcesContent":["/*\n * Copyright 2025 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\nexport const DEFAULT_STREAM_ENTITIES_LIMIT = 500;\n"],"names":[],"mappings":"AAgBO,MAAM,6BAAA,GAAgC;;;;"}
1
+ {"version":3,"file":"constants.esm.js","sources":["../src/constants.ts"],"sourcesContent":["/*\n * Copyright 2025 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\nexport const DEFAULT_STREAM_ENTITIES_LIMIT = 500;\nexport const DEFAULT_STREAM_LOCATIONS_LIMIT = 500;\n"],"names":[],"mappings":"AAgBO,MAAM,6BAAA,GAAgC;AACtC,MAAM,8BAAA,GAAiC;;;;"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { Entity, CompoundEntityRef } from '@backstage/catalog-model';
2
2
  import { SerializedError } from '@backstage/errors';
3
3
  import { AnalyzeLocationRequest, AnalyzeLocationResponse } from '@backstage/plugin-catalog-common';
4
+ import { FilterPredicate } from '@backstage/filter-predicates';
4
5
 
5
6
  /**
6
7
  * This symbol can be used in place of a value when passed to filters in e.g.
@@ -428,6 +429,41 @@ type StreamEntitiesRequest = Omit<QueryEntitiesInitialRequest, 'limit' | 'offset
428
429
  */
429
430
  pageSize?: number;
430
431
  };
432
+ /**
433
+ * The request type for {@link CatalogApi.queryLocations}.
434
+ *
435
+ * @public
436
+ */
437
+ type QueryLocationsRequest = QueryLocationsInitialRequest | QueryLocationsCursorRequest;
438
+ /**
439
+ * The request type for initial requests to {@link CatalogApi.queryLocations}.
440
+ *
441
+ * @public
442
+ */
443
+ interface QueryLocationsInitialRequest {
444
+ limit?: number;
445
+ query?: FilterPredicate;
446
+ }
447
+ /**
448
+ * The request type for cursor requests to {@link CatalogApi.queryLocations}.
449
+ *
450
+ * @public
451
+ */
452
+ interface QueryLocationsCursorRequest {
453
+ cursor: string;
454
+ }
455
+ /**
456
+ * The response type for {@link CatalogApi.queryLocations}.
457
+ *
458
+ * @public
459
+ */
460
+ interface QueryLocationsResponse {
461
+ items: Location[];
462
+ totalItems: number;
463
+ pageInfo: {
464
+ nextCursor?: string;
465
+ };
466
+ }
431
467
  /**
432
468
  * A client for interacting with the Backstage software catalog through its API.
433
469
  *
@@ -539,6 +575,54 @@ interface CatalogApi {
539
575
  * @param options - Additional options
540
576
  */
541
577
  getLocations(request?: {}, options?: CatalogRequestOptions): Promise<GetLocationsResponse>;
578
+ /**
579
+ * Gets paginated locations from the catalog.
580
+ *
581
+ * @remarks
582
+ *
583
+ * @example
584
+ *
585
+ * ```
586
+ * const response = await catalogClient.queryLocations({
587
+ * limit: 20,
588
+ * query: {
589
+ * type: 'url',
590
+ * target: { $hasPrefix: 'https://github.com/backstage/backstage' },
591
+ * },
592
+ * });
593
+ * ```
594
+ *
595
+ * This will match all locations of type `url` having a target starting
596
+ * with `https://github.com/backstage/backstage`.
597
+ *
598
+ * The response will contain a maximum of 20 locations. In case
599
+ * more than 20 locations exist, the response will contain a `nextCursor`
600
+ * property that can be used to fetch the next batch of locations.
601
+ *
602
+ * ```
603
+ * const secondBatchResponse = await catalogClient
604
+ * .queryLocations({ cursor: response.pageInfo.nextCursor });
605
+ * ```
606
+ *
607
+ * `secondBatchResponse` will contain the next batch of (maximum) 20 locations,
608
+ * again together with a `nextCursor` property if there is more data to fetch.
609
+ *
610
+ * @public
611
+ *
612
+ * @param request - Request parameters
613
+ * @param options - Additional options
614
+ */
615
+ queryLocations(request?: QueryLocationsRequest, options?: CatalogRequestOptions): Promise<QueryLocationsResponse>;
616
+ /**
617
+ * Asynchronously streams locations from the catalog. Uses `queryLocations`
618
+ * to fetch locations in batches, and yields them one page at a time.
619
+ *
620
+ * @public
621
+ *
622
+ * @param request - Request parameters
623
+ * @param options - Additional options
624
+ */
625
+ streamLocations(request?: QueryLocationsInitialRequest, options?: CatalogRequestOptions): AsyncIterable<Location[]>;
542
626
  /**
543
627
  * Gets a registered location by its ID.
544
628
  *
@@ -625,6 +709,14 @@ declare class CatalogClient implements CatalogApi {
625
709
  * {@inheritdoc CatalogApi.getLocations}
626
710
  */
627
711
  getLocations(request?: {}, options?: CatalogRequestOptions): Promise<GetLocationsResponse>;
712
+ /**
713
+ * {@inheritdoc CatalogApi.queryLocations}
714
+ */
715
+ queryLocations(request?: QueryLocationsRequest, options?: CatalogRequestOptions): Promise<QueryLocationsResponse>;
716
+ /**
717
+ * {@inheritdoc CatalogApi.streamLocations}
718
+ */
719
+ streamLocations(request?: QueryLocationsInitialRequest, options?: CatalogRequestOptions): AsyncIterable<Location[]>;
628
720
  /**
629
721
  * {@inheritdoc CatalogApi.getLocationById}
630
722
  */
@@ -704,4 +796,4 @@ declare class CatalogClient implements CatalogApi {
704
796
  declare const ENTITY_STATUS_CATALOG_PROCESSING_TYPE = "backstage.io/catalog-processing";
705
797
 
706
798
  export { CATALOG_FILTER_EXISTS, CatalogClient, ENTITY_STATUS_CATALOG_PROCESSING_TYPE };
707
- export type { AddLocationRequest, AddLocationResponse, CatalogApi, CatalogRequestOptions, EntityFieldsQuery, EntityFilterQuery, EntityOrderQuery, GetEntitiesByRefsRequest, GetEntitiesByRefsResponse, GetEntitiesRequest, GetEntitiesResponse, GetEntityAncestorsRequest, GetEntityAncestorsResponse, GetEntityFacetsRequest, GetEntityFacetsResponse, GetLocationsResponse, Location, QueryEntitiesCursorRequest, QueryEntitiesInitialRequest, QueryEntitiesRequest, QueryEntitiesResponse, StreamEntitiesRequest, ValidateEntityResponse };
799
+ export type { AddLocationRequest, AddLocationResponse, CatalogApi, CatalogRequestOptions, EntityFieldsQuery, EntityFilterQuery, EntityOrderQuery, GetEntitiesByRefsRequest, GetEntitiesByRefsResponse, GetEntitiesRequest, GetEntitiesResponse, GetEntityAncestorsRequest, GetEntityAncestorsResponse, GetEntityFacetsRequest, GetEntityFacetsResponse, GetLocationsResponse, Location, QueryEntitiesCursorRequest, QueryEntitiesInitialRequest, QueryEntitiesRequest, QueryEntitiesResponse, QueryLocationsCursorRequest, QueryLocationsInitialRequest, QueryLocationsRequest, QueryLocationsResponse, StreamEntitiesRequest, ValidateEntityResponse };
@@ -345,6 +345,23 @@ class DefaultApiClient {
345
345
  method: "GET"
346
346
  });
347
347
  }
348
+ /**
349
+ * Query for locations
350
+ * @param getLocationsByQueryRequest -
351
+ */
352
+ async getLocationsByQuery(request, options) {
353
+ const baseUrl = await this.discoveryApi.getBaseUrl(pluginId.pluginId);
354
+ const uriTemplate = `/locations/by-query`;
355
+ const uri = parser__namespace.parse(uriTemplate).expand({});
356
+ return await this.fetchApi.fetch(`${baseUrl}${uri}`, {
357
+ headers: {
358
+ "Content-Type": "application/json",
359
+ ...options?.token && { Authorization: `Bearer ${options?.token}` }
360
+ },
361
+ method: "POST",
362
+ body: JSON.stringify(request.body)
363
+ });
364
+ }
348
365
  }
349
366
 
350
367
  exports.DefaultApiClient = DefaultApiClient;